/** * Device ID service tests * * Tests the service layer that integrates with the Rust backend. * The Rust backend handles UUID generation and database storage. * * TRACES: UR-009 | DR-011 */ import { describe, it, expect, vi, beforeEach } from "vitest"; import { getDeviceId, getDeviceIdSync, clearCache } from "./deviceId"; // Mock Tauri invoke vi.mock("@tauri-apps/api/core", () => ({ invoke: vi.fn(), })); import { invoke } from "@tauri-apps/api/core"; describe("Device ID Service", () => { beforeEach(() => { clearCache(); vi.clearAllMocks(); }); it("should retrieve device ID from backend", async () => { const mockDeviceId = "550e8400-e29b-41d4-a716-446655440000"; (invoke as any).mockResolvedValue(mockDeviceId); const deviceId = await getDeviceId(); expect(deviceId).toBe(mockDeviceId); expect(invoke).toHaveBeenCalledWith("device_get_id"); expect(invoke).toHaveBeenCalledTimes(1); }); it("should cache device ID in memory after first call", async () => { const mockDeviceId = "550e8400-e29b-41d4-a716-446655440000"; (invoke as any).mockResolvedValue(mockDeviceId); const id1 = await getDeviceId(); const id2 = await getDeviceId(); expect(id1).toBe(id2); // Should only invoke backend once due to caching expect(invoke).toHaveBeenCalledTimes(1); }); it("should return cached device ID synchronously after initialization", async () => { const mockDeviceId = "550e8400-e29b-41d4-a716-446655440000"; (invoke as any).mockResolvedValue(mockDeviceId); await getDeviceId(); const cachedId = getDeviceIdSync(); expect(cachedId).toBe(mockDeviceId); }); it("should return empty string from sync if not yet initialized", () => { const syncId = getDeviceIdSync(); expect(syncId).toBe(""); }); it("should throw error when backend fails", async () => { (invoke as any).mockRejectedValue(new Error("Backend error")); await expect(getDeviceId()).rejects.toThrow("Failed to initialize device ID"); }); it("should clear cache on logout", async () => { const mockDeviceId = "550e8400-e29b-41d4-a716-446655440000"; (invoke as any).mockResolvedValue(mockDeviceId); await getDeviceId(); expect(getDeviceIdSync()).toBe(mockDeviceId); clearCache(); expect(getDeviceIdSync()).toBe(""); }); it("should call backend again after cache is cleared", async () => { const mockDeviceId = "550e8400-e29b-41d4-a716-446655440000"; (invoke as any).mockResolvedValue(mockDeviceId); await getDeviceId(); clearCache(); await getDeviceId(); // Should call backend twice (once per getDeviceId call) expect(invoke).toHaveBeenCalledTimes(2); }); });