Promote dev → uat: GRO-2159 drag-to-reorder + re-optimize (#64)
CI / Test (push) Successful in 35s
CI / Lint & Typecheck (push) Successful in 44s
CI / Build & Push Docker Image (push) Successful in 11s
CI / Test (pull_request) Successful in 21s
CI / Lint & Typecheck (pull_request) Successful in 27s
CI / Build & Push Docker Image (pull_request) Successful in 12s

This commit was merged in pull request #64.
This commit is contained in:
2026-06-09 03:10:17 +00:00
parent db11e5f2bd
commit e93017b279
5 changed files with 330 additions and 48 deletions
+30
View File
@@ -79,6 +79,9 @@ function mockFetch(meRole: "manager" | "groomer") {
if (url === "/api/routes/optimize" && opts?.method === "POST") {
return Promise.resolve({ ok: true, json: () => Promise.resolve(ROUTE_RESPONSE) } as Response);
}
if (/^\/api\/routes\/[^/]+\/reorder$/.test(url) && opts?.method === "PATCH") {
return Promise.resolve({ ok: true, json: () => Promise.resolve(ROUTE_RESPONSE) } as Response);
}
return Promise.resolve({ ok: true, json: () => Promise.resolve({}) } as Response);
});
}
@@ -124,6 +127,33 @@ describe("RoutesPage", () => {
expect(screen.queryByText("Groomer")).not.toBeInTheDocument();
});
it("renders a drag handle for each stop (drag-to-reorder enabled)", async () => {
global.fetch = mockFetch("manager") as unknown as typeof fetch;
render(<RoutesPage />);
await waitFor(() => expect(screen.getByText("Alice")).toBeInTheDocument());
expect(screen.getByLabelText("Drag to reorder Alice")).toBeInTheDocument();
expect(screen.getByLabelText("Drag to reorder Bob")).toBeInTheDocument();
});
it("flags the tight-schedule conflict on the affected stop", async () => {
global.fetch = mockFetch("manager") as unknown as typeof fetch;
render(<RoutesPage />);
await waitFor(() => expect(screen.getByText("Bob")).toBeInTheDocument());
expect(
screen.getByText(/Tight schedule — travel \+ buffer may exceed the gap/)
).toBeInTheDocument();
});
it("does not show the re-optimize hint before any manual reorder", async () => {
global.fetch = mockFetch("manager") as unknown as typeof fetch;
render(<RoutesPage />);
await waitFor(() => expect(screen.getByText("Alice")).toBeInTheDocument());
expect(screen.queryByText("Re-optimize")).not.toBeInTheDocument();
});
it("calls the optimize endpoint when Optimize is clicked", async () => {
const fetchMock = mockFetch("manager");
global.fetch = fetchMock as unknown as typeof fetch;