import { describe, expect, it } from "vitest"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; const readUsersView = () => readFileSync(resolve(__dirname, "./Users.vue"), "utf8"); const readUserForm = () => readFileSync(resolve(__dirname, "./UserForm.vue"), "utf8"); const readLocale = () => readFileSync(resolve(__dirname, "../../locales/zh-CN.ts"), "utf8"); describe("Admin users table labels", () => { it("shows clinical_department as 科室 in the account management table", () => { const viewSource = readUsersView(); const localeSource = readLocale(); expect(viewSource).toContain(':label="TEXT.modules.adminUsers.clinicalDepartmentLabel"'); expect(viewSource).not.toContain(':label="TEXT.common.fields.clinicalDepartment"'); expect(localeSource).toContain('clinicalDepartmentLabel: "科室"'); }); }); describe("Admin users table layout", () => { it("uses a wider name column, even remaining columns, and compact icon actions", () => { const viewSource = readUsersView(); expect(viewSource).toContain('table-layout="fixed"'); expect(viewSource).toContain(':label="TEXT.common.fields.name" width="360"'); expect(viewSource).not.toContain('width="20%"'); expect(viewSource).not.toContain('width="180"'); expect(viewSource).not.toContain('width="160"'); expect(viewSource).not.toContain('width="100"'); expect(viewSource).not.toContain('fixed="right"'); expect(viewSource).toContain('class="action-btn"'); expect(viewSource).toContain("width: 28px;"); expect(viewSource).toContain("gap: 4px;"); }); it("shows names without avatar icons in the account management table", () => { const viewSource = readUsersView(); expect(viewSource).not.toContain("user-avatar"); expect(viewSource).not.toContain("getInitials(scope.row.full_name)"); expect(viewSource).not.toContain("linear-gradient(135deg, #3f8f6b, #2d7a5a)"); }); }); describe("Admin users summary header", () => { it("keeps the management summary header compact", () => { const viewSource = readUsersView(); expect(viewSource).toContain("padding: 10px 16px;"); expect(viewSource).toContain("padding: 9px 12px;"); expect(viewSource).toContain("width: 32px;"); expect(viewSource).toContain("height: 32px;"); expect(viewSource).toContain("font-size: 20px;"); expect(viewSource).toContain("font-size: 11px;"); }); }); describe("Admin users filters", () => { it("applies keyword automatically and status filters from the first page", () => { const viewSource = readUsersView(); expect(viewSource).toContain("@keyup.enter=\"applyFilters\""); expect(viewSource).toContain("@change=\"applyFilters\""); expect(viewSource).not.toContain("@click=\"applyFilters\""); expect(viewSource).not.toContain(":icon=\"Refresh\""); expect(viewSource).not.toContain("Refresh } from"); expect(viewSource).toContain("watch(searchKeyword, () => {"); expect(viewSource).toContain("scheduleKeywordSearch();"); expect(viewSource).toContain("keywordSearchTimer = setTimeout(() => {"); expect(viewSource).toContain("}, 300);"); expect(viewSource).toContain("page.value = 1"); expect(viewSource).toContain("keyword: searchKeyword.value || undefined"); expect(viewSource).toContain("status: statusFilter.value || undefined"); }); }); describe("Admin user form autocomplete", () => { it("prevents browser credential autofill when creating a user", () => { const formSource = readUserForm(); expect(formSource).toContain('autocomplete="off"'); expect(formSource).toContain('name="ctms-create-initial-password"'); expect(formSource).toContain('autocomplete="new-password"'); expect(formSource).not.toContain("current_password"); expect(formSource).not.toContain("confirmPassword"); expect(formSource).not.toContain("TEXT.modules.profile.currentPassword"); expect(formSource).not.toContain("TEXT.modules.profile.confirmPassword"); }); }); describe("Admin user create form password", () => { it("requires an initial password before creating an account", () => { const formSource = readUserForm(); expect(formSource).toContain('v-if="!user" :label="TEXT.modules.adminUsers.passwordInitial" prop="password"'); expect(formSource).toContain("TEXT.modules.adminUsers.passwordInitialRequired"); expect(formSource).toContain("/^(?=.*[A-Za-z])(?=.*\\d).{8,}$/"); }); }); describe("Admin user edit form defaults", () => { it("hydrates the selected user immediately when the dialog is mounted open", () => { const formSource = readUserForm(); expect(formSource).toContain("immediate: true"); expect(formSource).not.toContain("current_password"); expect(formSource).not.toContain("confirmPassword"); expect(formSource).not.toContain("TEXT.modules.profile.currentPassword"); expect(formSource).not.toContain("TEXT.modules.profile.confirmPassword"); }); });