Files
frontend/test/data/backup.test.ts
T
Paulus SchoutsenandClaude 4db73f6a3d Correct backup, onboarding and cloud API types in the frontend (#54286)
Compare the backup, onboarding and cloud data modules with the
handlers that produce them, and fix the mismatches.

Several backup calls declared the wrong result. Deleting a backup
returns agent errors, generating one returns a job id rather than a
backup id, and restoring one returns nothing. The backup list carries
extended content, not the base type.

Add the blocked manager state, which is the state the manager starts
in and replays to new subscribers, along with the event reason fields
and the core_restart restore state.

Correct the onboarding installation type, which listed a value the
backend never sends and omitted one it does, and narrow the cloud
onboarding status to the single field that endpoint returns.

Remove the cloud strict connection preference and its translations.
No such preference exists in core, so the warning it gated could never
render.


Claude-Session: https://claude.ai/code/session_01YDqKNfAAvMV7zJJNodsHfK

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-27 09:35:47 +02:00

170 lines
4.5 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { BackupConfig } from "../../src/data/backup";
import {
BackupScheduleRecurrence,
CLOUD_AGENT,
cloudBackupEnabled,
cloudBackupHealth,
isSupportedBackupFile,
} from "../../src/data/backup";
const NOW = "2026-01-01T00:00:00.000Z";
const makeFile = (name: string, type: string): File =>
new File([""], name, { type });
const makeConfig = (overrides: Partial<BackupConfig> = {}): BackupConfig =>
({
automatic_backups_configured: true,
last_attempted_automatic_backup: null,
last_completed_automatic_backup: null,
next_automatic_backup: null,
next_automatic_backup_additional: false,
create_backup: {
agent_ids: [CLOUD_AGENT],
include_addons: null,
include_all_addons: false,
include_database: true,
include_folders: null,
name: null,
password: null,
},
retention: {},
schedule: {
recurrence: BackupScheduleRecurrence.DAILY,
time: null,
days: [],
},
agents: {},
...overrides,
}) satisfies BackupConfig;
describe("isSupportedBackupFile", () => {
it("accepts a .tar with the correct MIME type", () => {
expect(
isSupportedBackupFile(makeFile("backup.tar", "application/x-tar"))
).toBe(true);
});
it("accepts a .tar when the browser reports no MIME type (Firefox on Windows)", () => {
expect(isSupportedBackupFile(makeFile("backup.tar", ""))).toBe(true);
});
it("accepts a .tar reported as a generic binary type", () => {
expect(
isSupportedBackupFile(makeFile("backup.tar", "application/octet-stream"))
).toBe(true);
});
it("accepts regardless of extension casing", () => {
expect(isSupportedBackupFile(makeFile("BACKUP.TAR", ""))).toBe(true);
});
it("rejects a non-tar file", () => {
expect(isSupportedBackupFile(makeFile("photo.png", "image/png"))).toBe(
false
);
});
});
describe("cloudBackupEnabled", () => {
it("is false when there is no config", () => {
expect(cloudBackupEnabled(undefined)).toBe(false);
});
it("is false when the cloud agent is not a backup target", () => {
expect(
cloudBackupEnabled(
makeConfig({
create_backup: {
...makeConfig().create_backup,
agent_ids: ["backup.local"],
},
})
)
).toBe(false);
});
it("is false when automatic backups are not configured", () => {
expect(
cloudBackupEnabled(makeConfig({ automatic_backups_configured: false }))
).toBe(false);
});
it("is true when the cloud agent is a backup target", () => {
expect(cloudBackupEnabled(makeConfig())).toBe(true);
});
});
describe("cloudBackupHealth", () => {
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(new Date(NOW));
});
afterEach(() => {
vi.useRealTimers();
});
it("is 'none' when the cloud agent is not a backup target", () => {
expect(
cloudBackupHealth(
makeConfig({
create_backup: {
...makeConfig().create_backup,
agent_ids: ["backup.local"],
},
last_completed_automatic_backup: "2025-12-31T00:00:00.000Z",
})
)
).toBe("none");
});
it("is 'none' when there is no attempted or completed backup", () => {
expect(cloudBackupHealth(makeConfig())).toBe("none");
});
it("is 'failed' when the last attempt is newer than the last success", () => {
expect(
cloudBackupHealth(
makeConfig({
last_completed_automatic_backup: "2025-12-30T00:00:00.000Z",
last_attempted_automatic_backup: "2025-12-31T00:00:00.000Z",
})
)
).toBe("failed");
});
it("is 'old' when the next scheduled backup is overdue", () => {
expect(
cloudBackupHealth(
makeConfig({
last_completed_automatic_backup: "2025-12-31T00:00:00.000Z",
next_automatic_backup: "2025-12-31T12:00:00.000Z",
})
)
).toBe("old");
});
it("is 'success' when the last backup completed and the next is in the future", () => {
expect(
cloudBackupHealth(
makeConfig({
last_completed_automatic_backup: "2025-12-31T00:00:00.000Z",
next_automatic_backup: "2026-01-02T00:00:00.000Z",
})
)
).toBe("success");
});
it("is 'success' when completed with no next backup scheduled", () => {
expect(
cloudBackupHealth(
makeConfig({
last_completed_automatic_backup: "2025-12-31T00:00:00.000Z",
})
)
).toBe("success");
});
});