diff --git a/app/client/modules/backups/routes/__tests__/edit-backup.test.tsx b/app/client/modules/backups/routes/__tests__/edit-backup.test.tsx new file mode 100644 index 00000000..5d46dd16 --- /dev/null +++ b/app/client/modules/backups/routes/__tests__/edit-backup.test.tsx @@ -0,0 +1,87 @@ +import { afterEach, expect, test, vi } from "vitest"; +import { HttpResponse, http, server } from "~/test/msw/server"; +import { cleanup, render, screen, userEvent } from "~/test/test-utils"; + +const navigateMock = vi.fn(async () => {}); + +vi.mock("@tanstack/react-router", async (importOriginal) => { + const actual = await importOriginal(); + + return { + ...actual, + useNavigate: (() => navigateMock) as typeof actual.useNavigate, + }; +}); + +import { EditBackupPage } from "../edit-backup"; + +afterEach(() => { + navigateMock.mockClear(); + cleanup(); +}); + +test("submits the computed cron expression when saving a daily schedule", async () => { + const submittedBody = new Promise>((resolve) => { + server.use( + http.get("/api/v1/backups/:shortId", () => { + return HttpResponse.json({ + shortId: "backup-1", + name: "Backup 1", + repository: { shortId: "repo-1", name: "Repo 1", type: "local" }, + volume: { + id: "volume-1", + shortId: "vol-1", + name: "Volume 1", + config: { backend: "directory", path: "/mnt" }, + }, + cronExpression: "0 2 * * *", + retentionPolicy: null, + includePaths: ["/project"], + includePatterns: [], + excludePatterns: [], + excludeIfPresent: [], + oneFileSystem: false, + customResticParams: [], + }); + }), + http.get("/api/v1/repositories", () => { + return HttpResponse.json([{ shortId: "repo-1", name: "Repo 1", type: "local" }]); + }), + http.get("/api/v1/volumes/:shortId/files", () => { + return HttpResponse.json({ + files: [{ name: "project", path: "/project", type: "directory" }], + path: "/", + offset: 0, + limit: 100, + total: 1, + hasMore: false, + }); + }), + http.patch("/api/v1/backups/:shortId", async ({ request }) => { + const body = (await request.json()) as Record; + resolve(body); + + return HttpResponse.json({ + shortId: "backup-1", + volume: { + id: "volume-1", + shortId: "vol-1", + name: "Volume 1", + config: { backend: "directory", path: "/mnt" }, + }, + repository: { shortId: "repo-1", name: "Repo 1", type: "local" }, + ...body, + }); + }), + ); + }); + + render(, { withSuspense: true }); + + await userEvent.click(await screen.findByRole("button", { name: "Update schedule" })); + + await expect(submittedBody).resolves.toMatchObject({ + frequency: "daily", + cronExpression: "00 02 * * *", + }); +}); diff --git a/app/client/modules/backups/routes/edit-backup.tsx b/app/client/modules/backups/routes/edit-backup.tsx index 5ec2bf8e..8aae42c7 100644 --- a/app/client/modules/backups/routes/edit-backup.tsx +++ b/app/client/modules/backups/routes/edit-backup.tsx @@ -50,9 +50,9 @@ export function EditBackupPage({ backupId }: { backupId: string }) { updateSchedule.mutate({ path: { shortId: schedule.shortId }, body: { + ...formValues, cronExpression, retentionPolicy: Object.keys(retentionPolicy).length > 0 ? retentionPolicy : undefined, - ...formValues, }, }); };