homeio
PublikFork dari doctor-io/homeio
route.test.ts
import { NextRequest, NextResponse } from "next/server";
import { describe, expect, it, vi } from "vitest";
vi.mock("@/lib/server/modules/system/preferences-service", () => ({
getSystemPreferences: vi.fn(),
updateSystemPreferences: vi.fn(),
}));
import { GET, PUT } from "@/app/api/v1/system/preferences/route";
import { requireApiSession } from "@/lib/server/modules/auth/api";
import {
getSystemPreferences,
updateSystemPreferences,
} from "@/lib/server/modules/system/preferences-service";
describe("/api/v1/system/preferences", () => {
it("returns hostname and timezone for authenticated users", async () => {
vi.mocked(getSystemPreferences).mockResolvedValueOnce({
hostname: "home-node",
timezone: "Europe/Paris",
});
const response = await GET(
new NextRequest("http://localhost/api/v1/system/preferences", {
headers: {
cookie: "homeio_session=session-token",
},
}),
);
const json = (await response.json()) as { data: { hostname: string; timezone: string } };
expect(response.status).toBe(200);
expect(json.data).toEqual({
hostname: "home-node",
timezone: "Europe/Paris",
});
});
it("returns 401 for unauthenticated requests", async () => {
vi.mocked(requireApiSession).mockResolvedValueOnce({
session: null,
response: NextResponse.json({ error: "Unauthorized" }, { status: 401 }),
});
const response = await GET(
new NextRequest("http://localhost/api/v1/system/preferences"),
);
expect(response.status).toBe(401);
});
it("updates system preferences for authenticated users", async () => {
vi.mocked(updateSystemPreferences).mockResolvedValueOnce({
hostname: "homeio-box",
timezone: "Europe/Berlin",
});
const response = await PUT(
new NextRequest("http://localhost/api/v1/system/preferences", {
method: "PUT",
headers: {
cookie: "homeio_session=session-token",
"Content-Type": "application/json",
},
body: JSON.stringify({
hostname: "homeio-box",
timezone: "Europe/Berlin",
}),
}),
);
const json = (await response.json()) as { data: { hostname: string; timezone: string } };
expect(response.status).toBe(200);
expect(updateSystemPreferences).toHaveBeenCalledWith({
hostname: "homeio-box",
timezone: "Europe/Berlin",
});
expect(json.data).toEqual({
hostname: "homeio-box",
timezone: "Europe/Berlin",
});
});
it("returns 400 for invalid payloads", async () => {
const response = await PUT(
new NextRequest("http://localhost/api/v1/system/preferences", {
method: "PUT",
headers: {
cookie: "homeio_session=session-token",
"Content-Type": "application/json",
},
body: JSON.stringify({ hostname: "homeio-box" }),
}),
);
const json = (await response.json()) as { error: string };
expect(response.status).toBe(400);
expect(json.error).toBe("Invalid system preferences payload");
});
it("returns 400 for invalid hostname/timezone values", async () => {
vi.mocked(updateSystemPreferences).mockRejectedValueOnce(
new Error("Invalid timezone. Choose one of the supported timezone options."),
);
const response = await PUT(
new NextRequest("http://localhost/api/v1/system/preferences", {
method: "PUT",
headers: {
cookie: "homeio_session=session-token",
"Content-Type": "application/json",
},
body: JSON.stringify({
hostname: "homeio-box",
timezone: "Europe/Invalid",
}),
}),
);
const json = (await response.json()) as { error: string };
expect(response.status).toBe(400);
expect(json.error).toContain("Invalid timezone");
});
it("returns 500 when the service fails", async () => {
vi.mocked(updateSystemPreferences).mockRejectedValueOnce(new Error("hostnamectl failed"));
const response = await PUT(
new NextRequest("http://localhost/api/v1/system/preferences", {
method: "PUT",
headers: {
cookie: "homeio_session=session-token",
"Content-Type": "application/json",
},
body: JSON.stringify({
hostname: "homeio-box",
timezone: "Europe/Berlin",
}),
}),
);
const json = (await response.json()) as { error: string };
expect(response.status).toBe(500);
expect(json.error).toBe("Failed to update system preferences");
});
});