import { describe, it, expect, vi, beforeEach } from "vitest";
import { setActivePinia, createPinia } from "pinia";
import { useAreasStore } from "../areas.js";
vi.mock("../../api/modules/areas.js", () => ({
areasApi: {
list: vi.fn(),
newArea: vi.fn(),
updateDisplayName: vi.fn(),
remove: vi.fn(),
unassign: vi.fn(),
placeInArea: vi.fn(),
},
}));
import { areasApi } from "../../api/modules/areas.js";
describe("useAreasStore", () => {
beforeEach(() => {
setActivePinia(createPinia());
vi.clearAllMocks();
});
describe("areaTree getter", () => {
it("returns flat list for root-only areas", () => {
const store = useAreasStore();
store.areas = [
{ id: 1, parent_id: 0, display_name: "Kitchen" },
{ id: 2, parent_id: 0, display_name: "Hall" },
];
const tree = store.areaTree;
expect(tree).toHaveLength(2);
expect(tree[0].display_name).toBe("Kitchen");
expect(tree[1].display_name).toBe("Hall");
});
it("nests children under parents", () => {
const store = useAreasStore();
store.areas = [
{ id: 1, parent_id: 0, display_name: "House" },
{ id: 2, parent_id: 1, display_name: "Kitchen" },
{ id: 3, parent_id: 1, display_name: "Bedroom" },
];
const tree = store.areaTree;
expect(tree).toHaveLength(1);
expect(tree[0].children).toHaveLength(2);
expect(tree[0].children[0].display_name).toBe("Kitchen");
expect(tree[0].children[1].display_name).toBe("Bedroom");
});
it("skips self-referencing areas", () => {
const store = useAreasStore();
store.areas = [
{ id: 1, parent_id: 1, display_name: "Self" },
];
const tree = store.areaTree;
expect(tree).toHaveLength(1);
expect(tree[0].children).toEqual([]);
});
it("treats missing parent as root", () => {
const store = useAreasStore();
store.areas = [
{ id: 1, parent_id: 0, display_name: "Root" },
{ id: 2, parent_id: 99, display_name: "Orphan" },
];
const tree = store.areaTree;
expect(tree).toHaveLength(2);
});
});
describe("loadAreas", () => {
it("sets areas on success", async () => {
areasApi.list.mockResolvedValue({
ok: true,
data: { data: { areas: [{ id: 1, display_name: "Kitchen" }] } },
});
const store = useAreasStore();
await store.loadAreas();
expect(store.areas).toEqual([{ id: 1, display_name: "Kitchen" }]);
expect(store.isLoading).toBe(false);
expect(store.error).toBeNull();
});
it("sets error on failure", async () => {
areasApi.list.mockResolvedValue({
ok: false,
error: { message: "Network error" },
});
const store = useAreasStore();
await store.loadAreas();
expect(store.error).toEqual({ message: "Network error" });
expect(store.isLoading).toBe(false);
});
});
describe("createArea", () => {
it("adds new area to list on success", async () => {
areasApi.newArea.mockResolvedValue({
ok: true,
data: { data: { area: { id: 5, display_name: "New" } } },
});
const store = useAreasStore();
store.areas = [{ id: 1, display_name: "Old" }];
await store.createArea({ type: "room", alias: "new", display_name: "New" });
expect(store.areas).toHaveLength(2);
expect(store.areas[1].display_name).toBe("New");
});
});
describe("renameArea", () => {
it("updates display_name in place", async () => {
areasApi.updateDisplayName.mockResolvedValue({ ok: true });
const store = useAreasStore();
store.areas = [{ id: 1, display_name: "Old" }];
await store.renameArea(1, "New");
expect(store.areas[0].display_name).toBe("New");
});
});
describe("removeArea", () => {
it("removes area from list on success", async () => {
areasApi.remove.mockResolvedValue({ ok: true });
const store = useAreasStore();
store.areas = [{ id: 1 }, { id: 2 }];
await store.removeArea(1);
expect(store.areas).toHaveLength(1);
expect(store.areas[0].id).toBe(2);
});
});
describe("unassignArea", () => {
it("sets parent_id to 0 on success", async () => {
areasApi.unassign.mockResolvedValue({ ok: true });
const store = useAreasStore();
store.areas = [{ id: 1, parent_id: 2 }];
await store.unassignArea(1);
expect(store.areas[0].parent_id).toBe(0);
});
});
describe("assignToArea", () => {
it("sets parent_id on success", async () => {
areasApi.placeInArea.mockResolvedValue({ ok: true });
const store = useAreasStore();
store.areas = [{ id: 1, parent_id: 0 }];
await store.assignToArea(1, 2);
expect(store.areas[0].parent_id).toBe(2);
});
});
});