fix: T4a browser check findings
- Withdrawal wording from one backend helper everywhere ("bis
einschließlich TT.MM. – ab TT.MM. wieder erntefähig", year when it
crosses New Year); withdrawal-status returns lastBlockedDay and the
ready text, the frontend no longer computes dates
- Calendar events name colony or apiary, withdrawal events carry
product and detail; compact withdrawal rows on mobile
- One bottling warning per colony and treatment; pre-save hint
- Offline: online-only actions disabled with a reason, cached data
shows its timestamp, open sheets block submit offline
- Mobile: no horizontal scroll at 360 px, touch targets >= 44 px,
toasts and the add button no longer cover content
- Cleanup sheet without destructive preselection; natural sort of
colony codes; collapsible automation rule cards; varroa list newest
first with chart axes; text fixes
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
32c61c8e14
commit
c2f71bcb03
101 files changed
+2189
-271
No files matched your search
@@ -1,12 +1,13 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { render, screen, within } from "@testing-library/react";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { act, render, screen, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { NextStepsCard } from "./next-steps-card";
|
||||
import { fetchColonyNextSteps } from "@/lib/autopilot/api";
|
||||
import { colonyNextStepsKey, fetchColonyNextSteps } from "@/lib/autopilot/api";
|
||||
import { colonyStepsFixture, stepFixture } from "@/lib/autopilot/step-fixtures";
|
||||
import { acceptSuggestion, bulkDismissSuggestions, reopenSuggestion } from "@/lib/suggestions/api";
|
||||
import { ApiError } from "@/lib/auth/api-client";
|
||||
import { reportRequestOutcome } from "@/lib/offline/connectivity";
|
||||
import { toast } from "sonner";
|
||||
|
||||
vi.mock("@/lib/autopilot/api", async (importOriginal) => ({
|
||||
@@ -49,6 +50,10 @@ const TASK_STEP = stepFixture({
|
||||
});
|
||||
|
||||
describe("NextStepsCard", () => {
|
||||
afterEach(() => {
|
||||
act(() => reportRequestOutcome("reached-server"));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.mocked(fetchColonyNextSteps).mockReset();
|
||||
vi.mocked(acceptSuggestion).mockReset();
|
||||
@@ -233,4 +238,47 @@ describe("NextStepsCard", () => {
|
||||
await vi.waitFor(() => expect(fetchColonyNextSteps).toHaveBeenCalledTimes(2));
|
||||
await vi.waitFor(() => expect(second.container).toBeEmptyDOMElement());
|
||||
});
|
||||
|
||||
it("offline: decision buttons are off with „Nur mit Verbindung“ and the data says since when", async () => {
|
||||
vi.mocked(fetchColonyNextSteps).mockResolvedValue(
|
||||
colonyStepsFixture({
|
||||
steps: [
|
||||
stepFixture({
|
||||
intent: "HONEY_SUPER",
|
||||
title: "Honigraum",
|
||||
action: { type: "ACCEPT", suggestionId: "s1" },
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
act(() => reportRequestOutcome("network-error"));
|
||||
renderCard();
|
||||
|
||||
expect(await screen.findByRole("button", { name: "Übernehmen" })).toBeDisabled();
|
||||
expect(screen.getByRole("button", { name: "Verwerfen" })).toBeDisabled();
|
||||
expect(screen.getByRole("button", { name: "Übernehmen" })).toHaveAttribute(
|
||||
"aria-describedby",
|
||||
screen.getByText("Nur mit Verbindung").id,
|
||||
);
|
||||
expect(screen.getByText(/^Stand: \d{2}\.\d{2}\. \d{2}:\d{2}$/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps showing the cached steps when the reload fails at network level", async () => {
|
||||
vi.mocked(fetchColonyNextSteps).mockRejectedValue(new TypeError("Failed to fetch"));
|
||||
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||
client.setQueryData(
|
||||
colonyNextStepsKey("c1"),
|
||||
colonyStepsFixture({ steps: [stepFixture({ title: "Aus dem Cache" })] }),
|
||||
);
|
||||
render(
|
||||
<QueryClientProvider client={client}>
|
||||
<NextStepsCard colonyId="c1" />
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
|
||||
await waitFor(() => expect(fetchColonyNextSteps).toHaveBeenCalled());
|
||||
expect(await screen.findByText("Aus dem Cache")).toBeInTheDocument();
|
||||
// Online, but the reload failed: the cached steps say since when.
|
||||
expect(await screen.findByText(/^Stand: \d{2}\.\d{2}\. \d{2}:\d{2}$/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user