import { describe, it, expect, vi, beforeEach } from "vitest";
import { setActivePinia, createPinia } from "pinia";
import { useDevicesStore } from "../devices.js";
vi.mock("../../api/modules/devices.js", () => ({
devicesApi: {
list: vi.fn(),
status: vi.fn(),
reboot: vi.fn(),
resetup: vi.fn(),
reset: vi.fn(),
},
}));
import { devicesApi } from "../../api/modules/devices.js";
describe("useDevicesStore", () => {
beforeEach(() => {
setActivePinia(createPinia());
vi.clearAllMocks();
});
describe("loadDevices", () => {
it("sets devices on success", async () => {
devicesApi.list.mockResolvedValue({
ok: true,
data: { data: { devices: [{ id: 1, name: "Relay" }] } },
});
const store = useDevicesStore();
await store.loadDevices();
expect(store.devices).toEqual([{ id: 1, name: "Relay" }]);
expect(store.isLoading).toBe(false);
expect(store.error).toBeNull();
expect(store.lastLoadedAt).not.toBeNull();
});
it("sets error on failure", async () => {
devicesApi.list.mockResolvedValue({
ok: false,
error: { message: "Failed" },
});
const store = useDevicesStore();
await store.loadDevices();
expect(store.error).toEqual({ message: "Failed" });
expect(store.isLoading).toBe(false);
});
});
describe("setDeviceState", () => {
it("stores state by device id", () => {
const store = useDevicesStore();
store.devices = [{ id: 1, connection_status: "active" }];
store.setDeviceState(store.devices[0], { status: "loading", message: "Loading" });
expect(store.stateByDeviceId["1"]).toMatchObject({
deviceId: "1",
status: "loading",
message: "Loading",
connectionStatus: "active",
});
});
it("does nothing for missing device id", () => {
const store = useDevicesStore();
store.setDeviceState(null, { status: "loading" });
expect(store.stateByDeviceId).toEqual({});
});
});
describe("loadDeviceStates", () => {
it("marks lost devices as skipped", async () => {
devicesApi.status.mockResolvedValue({ ok: true, data: {} });
const store = useDevicesStore();
store.devices = [{ id: 1, connection_status: "lost" }];
await store.loadDeviceStates();
expect(store.stateByDeviceId["1"].status).toBe("skipped");
expect(store.stateByDeviceId["1"].message).toBe("Connection lost");
expect(devicesApi.status).not.toHaveBeenCalled();
});
it("fetches status for active devices", async () => {
devicesApi.status.mockResolvedValue({
ok: true,
data: { data: { device: { device_response: { status: "ok" } } } },
});
const store = useDevicesStore();
store.devices = [{ id: 1, connection_status: "active" }];
await store.loadDeviceStates();
expect(devicesApi.status).toHaveBeenCalledWith(1);
expect(store.stateByDeviceId["1"].status).toBe("ready");
expect(store.stateByDeviceId["1"].message).toBe("ok");
});
it("marks errored status responses", async () => {
devicesApi.status.mockResolvedValue({
ok: false,
error: { message: "Timeout", raw: {} },
});
const store = useDevicesStore();
store.devices = [{ id: 1, connection_status: "active" }];
await store.loadDeviceStates();
expect(store.stateByDeviceId["1"].status).toBe("error");
expect(store.stateByDeviceId["1"].message).toBe("Timeout");
});
});
describe("rebootDevice", () => {
it("calls API and clears rebooting state after", async () => {
devicesApi.reboot.mockResolvedValue({ ok: true });
const store = useDevicesStore();
expect(store.isRebooting(1)).toBe(false);
await store.rebootDevice(1);
expect(store.isRebooting(1)).toBe(false);
expect(devicesApi.reboot).toHaveBeenCalledWith(1);
});
it("tracks rebooting id in state", () => {
const store = useDevicesStore();
store.rebootingIds.add("1");
expect(store.rebootingIds.has("1")).toBe(true);
expect(store.rebootingIds.has("2")).toBe(false);
});
});
});