import { describe, it, expect, beforeEach, vi } from "vitest"; import { mount } from "@vue/test-utils"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import ApiPermissions from "@/views/admin/ApiPermissions.vue"; import { createPinia, setActivePinia } from "pinia"; vi.mock("vue-router", async () => { const actual = await vi.importActual("vue-router"); return { ...actual, useRoute: () => ({ params: { id: "study-1" } }), }; }); vi.mock("@/api/projectPermissions", () => ({ fetchApiEndpointPermissions: vi.fn().mockResolvedValue({ data: {} }), updateApiEndpointPermissions: vi.fn().mockResolvedValue({ data: {} }), fetchPermissionMetrics: vi.fn().mockResolvedValue({ data: {} }), fetchCacheStats: vi.fn().mockResolvedValue({ data: {} }), fetchPermissionAlerts: vi.fn().mockResolvedValue({ data: { total: 0, alerts: [] } }), fetchPermissionHealth: vi.fn().mockResolvedValue({ data: {} }), resetPermissionMetrics: vi.fn().mockResolvedValue({ data: undefined }), })); describe("ApiPermissions.vue", () => { beforeEach(() => { Object.defineProperty(window, "localStorage", { value: { getItem: vi.fn(() => null), setItem: vi.fn(), removeItem: vi.fn(), clear: vi.fn(), }, configurable: true, }); Object.defineProperty(globalThis, "localStorage", { value: window.localStorage, configurable: true, }); setActivePinia(createPinia()); }); it("renders permission management page", () => { const wrapper = mount(ApiPermissions, { global: { stubs: { ApiEndpointPermissions: true, PermissionMonitoring: true, }, }, }); expect(wrapper.find(".permission-page").exists()).toBe(true); expect(wrapper.find(".permission-title h2").text()).toBe("权限管理"); }); it("renders tabs", () => { const source = readFileSync(resolve(__dirname, "./ApiPermissions.vue"), "utf8"); expect(source).toContain('label="角色权限"'); expect(source).toContain('label="权限监控"'); }); it("has save button disabled when not dirty", () => { const source = readFileSync(resolve(__dirname, "./ApiPermissions.vue"), "utf8"); expect(source).toContain(':disabled="!dirty"'); }); });