fix(schedule): disable if saving with manual-only mode
Some checks failed
Release Workflow / determine-release-type (push) Has been cancelled
Release Workflow / checks (push) Has been cancelled
Release Workflow / e2e-tests (push) Has been cancelled
Release Workflow / build-images (push) Has been cancelled
Release Workflow / publish-release (push) Has been cancelled
Some checks failed
Release Workflow / determine-release-type (push) Has been cancelled
Release Workflow / checks (push) Has been cancelled
Release Workflow / e2e-tests (push) Has been cancelled
Release Workflow / build-images (push) Has been cancelled
Release Workflow / publish-release (push) Has been cancelled
This commit is contained in:
parent
74d20d5be3
commit
f11e3b7f82
2 changed files with 148 additions and 1 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { afterEach, expect, test, vi } from "vitest";
|
||||
import { HttpResponse, http, server } from "~/test/msw/server";
|
||||
import { cleanup, render, screen, userEvent } from "~/test/test-utils";
|
||||
import { cleanup, fireEvent, render, screen, userEvent } from "~/test/test-utils";
|
||||
|
||||
const navigateMock = vi.fn(async () => {});
|
||||
|
||||
|
|
@ -27,6 +27,7 @@ test("submits the computed cron expression when saving a daily schedule", async
|
|||
return HttpResponse.json({
|
||||
shortId: "backup-1",
|
||||
name: "Backup 1",
|
||||
enabled: true,
|
||||
repository: { shortId: "repo-1", name: "Repo 1", type: "local" },
|
||||
volume: {
|
||||
id: "volume-1",
|
||||
|
|
@ -82,6 +83,151 @@ test("submits the computed cron expression when saving a daily schedule", async
|
|||
|
||||
await expect(submittedBody).resolves.toMatchObject({
|
||||
frequency: "daily",
|
||||
enabled: true,
|
||||
cronExpression: "00 02 * * *",
|
||||
});
|
||||
});
|
||||
|
||||
test("disables the schedule when switching an enabled custom cron schedule to manual only", async () => {
|
||||
const submittedBody = new Promise<Record<string, unknown>>((resolve) => {
|
||||
server.use(
|
||||
http.get("/api/v1/backups/:shortId", () => {
|
||||
return HttpResponse.json({
|
||||
shortId: "backup-1",
|
||||
name: "Backup 1",
|
||||
enabled: true,
|
||||
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: "*/13 * * * *",
|
||||
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<string, unknown>;
|
||||
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(<EditBackupPage backupId="backup-1" />, { withSuspense: true });
|
||||
|
||||
const nativeFrequencySelect = (await screen.findAllByRole("combobox"))
|
||||
.at(1)
|
||||
?.parentElement?.querySelector('select[aria-hidden="true"]');
|
||||
if (!(nativeFrequencySelect instanceof HTMLSelectElement)) {
|
||||
throw new Error("Expected hidden native select for frequency field");
|
||||
}
|
||||
|
||||
fireEvent.change(nativeFrequencySelect, { target: { value: "manual" } });
|
||||
await userEvent.click(screen.getByRole("button", { name: "Update schedule" }));
|
||||
|
||||
await expect(submittedBody).resolves.toMatchObject({
|
||||
frequency: "manual",
|
||||
enabled: false,
|
||||
cronExpression: "",
|
||||
});
|
||||
});
|
||||
|
||||
test("preserves a disabled schedule when saving a non-manual frequency", async () => {
|
||||
const submittedBody = new Promise<Record<string, unknown>>((resolve) => {
|
||||
server.use(
|
||||
http.get("/api/v1/backups/:shortId", () => {
|
||||
return HttpResponse.json({
|
||||
shortId: "backup-1",
|
||||
name: "Backup 1",
|
||||
enabled: false,
|
||||
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<string, unknown>;
|
||||
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(<EditBackupPage backupId="backup-1" />, { withSuspense: true });
|
||||
|
||||
await userEvent.click(await screen.findByRole("button", { name: "Update schedule" }));
|
||||
|
||||
await expect(submittedBody).resolves.toMatchObject({
|
||||
frequency: "daily",
|
||||
enabled: false,
|
||||
cronExpression: "00 02 * * *",
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ export function EditBackupPage({ backupId }: { backupId: string }) {
|
|||
path: { shortId: schedule.shortId },
|
||||
body: {
|
||||
...formValues,
|
||||
enabled: formValues.frequency === "manual" ? false : schedule.enabled,
|
||||
cronExpression,
|
||||
retentionPolicy: Object.keys(retentionPolicy).length > 0 ? retentionPolicy : undefined,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue