import { config, mount, flushPromises } from "@vue/test-utils"; import { createPinia, setActivePinia } from "pinia"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { NConfigProvider, NDialogProvider, NMessageProvider, dateZhCN, zhCN, } from "naive-ui"; import { defineComponent, h, nextTick } from "vue"; import EndpointsView from "./EndpointsView.vue"; import { mockApi } from "@/api/mock"; import * as admin from "@/api/admin"; vi.mock("@/api/admin", async () => import("@/api/admin-mock")); config.global.stubs = { teleport: true }; function wrap(Comp: object) { return defineComponent({ setup() { return () => h(NConfigProvider, { locale: zhCN, dateLocale: dateZhCN, size: "small" }, { default: () => h(NMessageProvider, null, { default: () => h(NDialogProvider, null, { default: () => h(Comp), }), }), }); }, }); } describe("EndpointsView 开通端", () => { beforeEach(() => { setActivePinia(createPinia()); mockApi._setSession(); }); it("开通后密码只显示一次,关闭后消失", async () => { const pinia = createPinia(); const w = mount(wrap(EndpointsView), { global: { plugins: [pinia] }, attachTo: document.body, }); await flushPromises(); const openBtn = w.findAll("button").find((b) => b.text().trim() === "开通"); expect(openBtn).toBeTruthy(); await openBtn!.trigger("click"); await nextTick(); await flushPromises(); const nameRoot = w.find('[data-testid="create-name"]'); expect(nameRoot.exists()).toBe(true); await nameRoot.find("input").setValue("测试端"); await w.find('[data-testid="create-submit"]').trigger("click"); await flushPromises(); expect(w.text()).toContain("只显示一次"); const dismiss = w.findAll("button").find((b) => b.text().includes("我已保存")); expect(dismiss).toBeTruthy(); await dismiss!.trigger("click"); await nextTick(); expect(w.text()).not.toContain("只显示一次"); w.unmount(); }); it("手填密码开通后不显示一次性面板和 undefined", async () => { const pinia = createPinia(); const w = mount(wrap(EndpointsView), { global: { plugins: [pinia] }, attachTo: document.body, }); await flushPromises(); const openBtn = w.findAll("button").find((b) => b.text().trim() === "开通"); await openBtn!.trigger("click"); await nextTick(); await flushPromises(); await w.find('[data-testid="create-name"]').find("input").setValue("手填端"); await w.find('[data-testid="create-login-password"]').find("input").setValue("handpassword12"); await w.find('[data-testid="create-submit"]').trigger("click"); await flushPromises(); expect(w.text()).not.toContain("undefined"); expect(w.text()).not.toContain("只显示一次"); expect(w.text()).toContain("手填端"); w.unmount(); }); }); describe("EndpointsView 列表与编辑", () => { beforeEach(() => { setActivePinia(createPinia()); mockApi._setSession(); vi.restoreAllMocks(); }); it("login_locked=false 时解锁按钮可点", async () => { const w = mount(wrap(EndpointsView), { global: { plugins: [createPinia()] }, attachTo: document.body, }); await flushPromises(); const unlocks = w.findAll('[data-testid="endpoint-unlock"]'); expect(unlocks.length).toBeGreaterThan(0); for (const b of unlocks) { expect(b.attributes("disabled")).toBeUndefined(); } w.unmount(); }); it("只改名称时请求体没有 enabled", async () => { const spy = vi.spyOn(admin, "patchEndpoint"); const w = mount(wrap(EndpointsView), { global: { plugins: [createPinia()] }, attachTo: document.body, }); await flushPromises(); const editBtn = w.findAll("button").find((b) => b.text().trim() === "编辑"); await editBtn!.trigger("click"); await nextTick(); await flushPromises(); await w.find('[data-testid="edit-name"]').find("input").setValue("改名后"); await w.find('[data-testid="edit-submit"]').trigger("click"); await flushPromises(); expect(spy).toHaveBeenCalled(); const body = spy.mock.calls[0][1]; expect(body).toEqual({ name: "改名后" }); expect(body).not.toHaveProperty("enabled"); w.unmount(); }); it("默认延迟超上限时前端阻止提交", async () => { vi.spyOn(admin, "getSettings").mockResolvedValue({ listen: ":7443", admin_listen: "", session_idle_days: 30, record_retention_days: 7, idempotency_hours: 24, receipt_retention_days: 7, sqlite_synchronous: "FULL", limits: { max_schedule_seconds: 10 }, }); const createSpy = vi.spyOn(admin, "createEndpoint"); const w = mount(wrap(EndpointsView), { global: { plugins: [createPinia()] }, attachTo: document.body, }); await flushPromises(); const openBtn = w.findAll("button").find((b) => b.text().trim() === "开通"); await openBtn!.trigger("click"); await nextTick(); await flushPromises(); expect(w.find('[data-testid="create-delay-max"]').text()).toContain("上限 10 秒"); const delay = w.find('[data-testid="create-delay"]').find("input"); await delay.setValue("11"); await w.find('[data-testid="create-submit"]').trigger("click"); await flushPromises(); expect(createSpy.mock.calls.every((c) => ((c[0] as { default_delay_seconds?: number }).default_delay_seconds ?? 0) <= 10)).toBe(true); w.unmount(); }); });