231 lines
6.6 KiB
TypeScript
231 lines
6.6 KiB
TypeScript
import { stringify } from "superjson";
|
|
import { describe, expect, test, vi } from "vitest";
|
|
|
|
import type { Session } from "@homarr/auth";
|
|
import { createId } from "@homarr/common";
|
|
import { boards, serverSettings } from "@homarr/db/schema";
|
|
import { createDb } from "@homarr/db/test";
|
|
import { defaultServerSettings, defaultServerSettingsKeys } from "@homarr/server-settings";
|
|
|
|
import { serverSettingsRouter } from "../serverSettings";
|
|
|
|
// Mock the auth module to return an empty session
|
|
vi.mock("@homarr/auth", () => ({ auth: () => ({}) as Session }));
|
|
|
|
const defaultSession = {
|
|
user: {
|
|
id: createId(),
|
|
permissions: ["admin"],
|
|
colorScheme: "light",
|
|
},
|
|
expires: new Date().toISOString(),
|
|
} satisfies Session;
|
|
|
|
describe("getAll server settings", () => {
|
|
test("getAll should throw error when unauthorized", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: null,
|
|
});
|
|
|
|
await db.insert(serverSettings).values([
|
|
{
|
|
settingKey: defaultServerSettingsKeys[0],
|
|
value: stringify(defaultServerSettings.analytics),
|
|
},
|
|
]);
|
|
|
|
const actAsync = async () => await caller.getAll();
|
|
|
|
await expect(actAsync()).rejects.toThrow();
|
|
});
|
|
test("getAll should return default server settings when nothing in database", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
|
|
const result = await caller.getAll();
|
|
|
|
expect(result).toStrictEqual(defaultServerSettings);
|
|
});
|
|
});
|
|
|
|
describe("saveSettings", () => {
|
|
test("saveSettings should persist settings when defaults are not seeded", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
|
|
await caller.saveSettings({
|
|
settingsKey: "board",
|
|
value: {
|
|
enableAutomaticMobileLayout: false,
|
|
},
|
|
});
|
|
|
|
const dbSettings = await db.select().from(serverSettings);
|
|
expect(dbSettings).toStrictEqual([
|
|
{
|
|
settingKey: "board",
|
|
value: stringify({
|
|
...defaultServerSettings.board,
|
|
enableAutomaticMobileLayout: false,
|
|
}),
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("saveSettings should update settings and return true when it updated only one", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
|
|
await db.insert(serverSettings).values([
|
|
{
|
|
settingKey: defaultServerSettingsKeys[0],
|
|
value: stringify(defaultServerSettings.analytics),
|
|
},
|
|
]);
|
|
|
|
await caller.saveSettings({
|
|
settingsKey: "analytics",
|
|
value: {
|
|
enableGeneral: true,
|
|
},
|
|
});
|
|
|
|
const dbSettings = await db.select().from(serverSettings);
|
|
expect(dbSettings).toStrictEqual([
|
|
{
|
|
settingKey: "analytics",
|
|
value: stringify({
|
|
enableGeneral: true,
|
|
instanceId: null,
|
|
}),
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("board settings API", () => {
|
|
test("getBoardSettings should return board defaults", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
|
|
await expect(caller.getBoardSettings()).resolves.toStrictEqual(defaultServerSettings.board);
|
|
});
|
|
|
|
test("getBoardSettings should backfill the automatic layout default for legacy values", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
const legacyBoardSettings = {
|
|
homeBoardId: defaultServerSettings.board.homeBoardId,
|
|
mobileHomeBoardId: defaultServerSettings.board.mobileHomeBoardId,
|
|
enableStatusByDefault: defaultServerSettings.board.enableStatusByDefault,
|
|
forceDisableStatus: defaultServerSettings.board.forceDisableStatus,
|
|
};
|
|
await db.insert(serverSettings).values({
|
|
settingKey: "board",
|
|
value: stringify(legacyBoardSettings),
|
|
});
|
|
|
|
await expect(caller.getBoardSettings()).resolves.toStrictEqual(defaultServerSettings.board);
|
|
});
|
|
|
|
test("updateBoardSettings should insert settings when defaults are not persisted", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
const boardId = createId();
|
|
await db.insert(boards).values({ id: boardId, name: "default", isPublic: true });
|
|
|
|
const result = await caller.updateBoardSettings({
|
|
homeBoardId: boardId,
|
|
forceDisableStatus: true,
|
|
});
|
|
|
|
expect(result).toStrictEqual({
|
|
...defaultServerSettings.board,
|
|
homeBoardId: boardId,
|
|
forceDisableStatus: true,
|
|
});
|
|
const dbSettings = await db.select().from(serverSettings);
|
|
expect(dbSettings).toStrictEqual([
|
|
{
|
|
settingKey: "board",
|
|
value: stringify(result),
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("updateBoardSettings should update existing settings", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
const boardId = createId();
|
|
await db.insert(boards).values({ id: boardId, name: "default", isPublic: true });
|
|
|
|
await caller.updateBoardSettings({ homeBoardId: boardId });
|
|
const result = await caller.updateBoardSettings({
|
|
mobileHomeBoardId: boardId,
|
|
enableAutomaticMobileLayout: false,
|
|
enableStatusByDefault: false,
|
|
});
|
|
|
|
expect(result).toStrictEqual({
|
|
...defaultServerSettings.board,
|
|
homeBoardId: boardId,
|
|
mobileHomeBoardId: boardId,
|
|
enableAutomaticMobileLayout: false,
|
|
enableStatusByDefault: false,
|
|
});
|
|
const dbSettings = await db.select().from(serverSettings);
|
|
expect(dbSettings).toStrictEqual([
|
|
{
|
|
settingKey: "board",
|
|
value: stringify(result),
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("updateBoardSettings should reject private home boards", async () => {
|
|
const db = createDb();
|
|
const caller = serverSettingsRouter.createCaller({
|
|
db,
|
|
deviceType: undefined,
|
|
session: defaultSession,
|
|
});
|
|
const boardId = createId();
|
|
await db.insert(boards).values({ id: boardId, name: "private", isPublic: false });
|
|
|
|
const actAsync = async () => await caller.updateBoardSettings({ homeBoardId: boardId });
|
|
|
|
await expect(actAsync()).rejects.toThrow("must reference public boards");
|
|
});
|
|
});
|