homeio
PublicForked from doctor-io/homeio
route.test.ts
import type { NextRequest } from "next/server";
import { describe, expect, it, vi, beforeEach } from "vitest";
const { scheduleSystemUpdateMock, requireApiSessionMock, emitPowerActionMock } = vi.hoisted(() => ({
scheduleSystemUpdateMock: vi.fn(),
requireApiSessionMock: vi.fn(),
emitPowerActionMock: vi.fn(),
}));
vi.mock("@/lib/server/modules/system/power-action-events", () => ({
emitPowerAction: emitPowerActionMock,
}));
vi.mock("@/lib/server/modules/system/update-service", () => ({
scheduleSystemUpdate: scheduleSystemUpdateMock,
}));
vi.mock("@/lib/server/modules/auth/api", () => ({
requireApiSession: requireApiSessionMock,
}));
import { POST } from "@/app/api/v1/system/updates/apply/route";
import { NextResponse } from "next/server";
describe("POST /api/v1/system/updates/apply", () => {
beforeEach(() => {
vi.restoreAllMocks();
scheduleSystemUpdateMock.mockReset();
requireApiSessionMock.mockReset();
emitPowerActionMock.mockReset();
});
it("returns 401 when unauthenticated", async () => {
requireApiSessionMock.mockResolvedValueOnce({
session: null,
response: NextResponse.json({ error: "Unauthorized" }, { status: 401 }),
});
const request = new Request("http://localhost/api/v1/system/updates/apply", {
method: "POST",
});
const response = await POST(request as unknown as NextRequest);
expect(response.status).toBe(401);
});
it("returns 400 with helpful message when running in Docker container", async () => {
requireApiSessionMock.mockResolvedValueOnce({
session: { userId: "user-1", username: "admin" },
response: null,
});
scheduleSystemUpdateMock.mockRejectedValueOnce(
new Error(
"Homeio is running in a Docker container. In-app self-update via systemd is disabled. Please update your container using: docker compose pull && docker compose up -d"
)
);
const request = new Request("http://localhost/api/v1/system/updates/apply", {
method: "POST",
});
const response = await POST(request as unknown as NextRequest);
expect(response.status).toBe(400);
const json = await response.json();
expect(json.error).toContain("Docker container");
expect(emitPowerActionMock).not.toHaveBeenCalled();
});
it("returns 202 when update is accepted", async () => {
requireApiSessionMock.mockResolvedValueOnce({
session: { userId: "user-1", username: "admin" },
response: null,
});
scheduleSystemUpdateMock.mockResolvedValueOnce({ accepted: true, action: "update" });
const request = new Request("http://localhost/api/v1/system/updates/apply", {
method: "POST",
});
const response = await POST(request as unknown as NextRequest);
expect(response.status).toBe(202);
const json = await response.json();
expect(json.data.accepted).toBe(true);
// Other open sessions switch to the update screen too.
expect(emitPowerActionMock).toHaveBeenCalledWith("update");
});
});