Files
Magent/frontend/app/setup/setup-model.test.ts
T
Assclaw fd6671cf7e
Magent CI/CD / verify (push) Successful in 5m20s
Magent CI/CD / deploy-beta (push) Successful in 1m41s
feat: add backup recovery, setup wizard and user-view guards
2026-09-18 17:23:03 +12:00

86 lines
3.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { APPS, configuredApp, settingsPayload, settingsValues } from "./setup-model";
describe("installation settings", () => {
it("offers every supported media integration", () => {
expect(APPS.map((app) => app.id).sort()).toEqual([
"bazarr",
"jellyfin",
"jellystat",
"prowlarr",
"qbittorrent",
"radarr",
"seerr",
"sonarr",
]);
});
it("never copies saved secrets into the form or overwrites them with a blank", () => {
expect(settingsValues([{ key: "sonarr_api_key", value: "secret", sensitive: true, isSet: true }])).toEqual({
sonarr_api_key: "",
});
expect(settingsPayload({ sonarr_api_key: "", sonarr_base_url: "http://sonarr:8989" })).toEqual({
sonarr_base_url: "http://sonarr:8989",
});
});
it("sends only editable fields and validates numeric settings", () => {
expect(
settingsPayload({ jwt_secret: "no", requests_cleanup_days: "90", site_login_show_signup_link: false }),
).toEqual({ requests_cleanup_days: 90, site_login_show_signup_link: false });
expect(() => settingsPayload({ requests_cleanup_days: "-1" })).toThrow("whole number");
expect(() => settingsPayload({ sonarr_quality_profile_id: "1.5" })).toThrow("whole number");
});
it("can save just one app without accidentally saving another draft", () => {
expect(
settingsPayload(
{ sonarr_base_url: "http://sonarr:8989", radarr_api_key: "draft-secret" },
APPS.find((app) => app.id === "sonarr")?.fields,
),
).toEqual({ sonarr_base_url: "http://sonarr:8989" });
});
it("validates URL drafts even when app testing bypasses browser form validation", () => {
for (const value of [
"sonarr:8989",
"/sonarr",
"ftp://sonarr:8989",
"javascript:alert(1)",
"http://sonarr/my library",
]) {
expect(() => settingsPayload({ sonarr_base_url: value })).toThrow("HTTP or HTTPS URL");
}
expect(() => settingsPayload({ sonarr_base_url: "https://user:secret@sonarr.test" })).toThrow("credential fields");
expect(
settingsPayload({
sonarr_base_url: " http://sonarr:8989 ",
magent_application_url: "https://magent.example.test",
}),
).toEqual({ sonarr_base_url: "http://sonarr:8989", magent_application_url: "https://magent.example.test" });
expect(settingsPayload({ sonarr_base_url: "" })).toEqual({ sonarr_base_url: "" });
});
it("validates sender email and sync time before step navigation saves", () => {
for (const value of ["not-an-email", "two@@example.test", "name@example test", "Name <name@example.test>"]) {
expect(() => settingsPayload({ magent_notify_email_from_address: value })).toThrow("valid email address");
}
for (const value of ["24:00", "12:60", "2:30", "02:30:00"]) {
expect(() => settingsPayload({ requests_full_sync_time: value })).toThrow("HH:MM");
}
expect(
settingsPayload({
magent_notify_email_from_address: " alerts+admin@example.test ",
requests_full_sync_time: "23:59",
}),
).toEqual({ magent_notify_email_from_address: "alerts+admin@example.test", requests_full_sync_time: "23:59" });
expect(settingsPayload({ magent_notify_email_from_address: "", requests_full_sync_time: "" })).toEqual({
magent_notify_email_from_address: "",
requests_full_sync_time: "",
});
});
it("does not call a URL-only app configured", () => {
const app = APPS[0];
const url = { key: "jellyfin_base_url", value: "http://jellyfin:8096", sensitive: false, isSet: true };
expect(configuredApp(app, [url])).toBe(false);
expect(configuredApp(app, [url, { key: "jellyfin_api_key", value: null, sensitive: true, isSet: true }])).toBe(
true,
);
});
});