Files
clinicpro/assets/admin/pages/MySecretariesPage.test.tsx
T
hamedandClaude Opus 4.8 89e23a2c0d feat: port secretaries tab from tauri to admin my-secretaries page
- Redesign MySecretariesPage pixel-perfect to clinic-pro-tauri (active/previous
  tabs, desktop table, mobile cards, add/edit/view modal with permission
  accordions, deactivate confirm)
- Permission sections based on existing admin pages (appointments, patients,
  payments, insurances, addresses, clinic_info)
- Extend DoctorSecretary with national_code + address columns (+migration);
  wire create/update in SecretaryController; add patients/payments to
  DEFAULT_PERMISSIONS
- Extend Secretary/SecretaryPermissions types; update admin SecretariesPage
- Backend + frontend tests; update docs/api/secretary.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 12:23:17 +03:30

111 lines
4.6 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from "vitest";
import { screen, fireEvent } from "@testing-library/react";
import { renderWithProviders } from "../test/utils";
vi.mock("sonner", () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
vi.mock("../lib/api", () => ({
api: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), put: vi.fn(), delete: vi.fn() },
ApiError: class extends Error {},
}));
vi.mock("../stores/authStore", () => ({
useAuthStore: () => ({ doctorUuid: "doc-1", dbUuid: "doc-1", primaryRole: "doctor" }),
}));
vi.mock("../hooks/useSubscription", () => ({
useSubscription: () => ({ maxSecretaries: 5 }),
}));
import { api } from "../lib/api";
import MySecretariesPage from "./MySecretariesPage";
const get = api.get as ReturnType<typeof vi.fn>;
const fullPerms = {
appointments: { view: true, create: false, cancel: false, update_status: false },
patients: { view: false, create: false, update: false, delete: false },
payments: { view: false, create: false, update: false, delete: false },
insurances: { view: false, create: false, update: false, delete: false },
addresses: { view: false, create: false, update: false, delete: false },
clinic_info: { view: false, update: false },
};
const activeSecretary = {
uuid: "sec-1",
user_name: "سارا احمدی",
mobile_number: "09121234567",
doctor_name: "دکتر تست",
doctor_uuid: "doc-1",
is_active: true,
national_code: "1234567890",
address: "یزد",
permissions: fullPerms,
created_at: 1700000000,
};
const previousSecretary = {
...activeSecretary,
uuid: "sec-2",
user_name: "مینا رضایی",
mobile_number: "09129876543",
is_active: false,
national_code: "9999999999",
};
function mockData(rows = [activeSecretary, previousSecretary]) {
get.mockImplementation((url: string) => {
if (url.includes("/secretaries/")) return Promise.resolve({ success: true, data: rows });
return Promise.resolve({ success: true, data: [] });
});
}
beforeEach(() => {
get.mockReset();
mockData();
});
describe("MySecretariesPage", () => {
it("renders the title and both tabs", async () => {
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
expect(await screen.findByText("لیست منشی ها")).toBeInTheDocument();
expect(screen.getByText("منشی های فعلی")).toBeInTheDocument();
expect(screen.getByText("منشی های قبلی")).toBeInTheDocument();
});
it("shows active secretaries with national code on the default tab", async () => {
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
expect(await screen.findAllByText("سارا احمدی")).not.toHaveLength(0);
expect(screen.getAllByText("1234567890").length).toBeGreaterThan(0);
// inactive secretary is hidden on the active tab
expect(screen.queryByText("مینا رضایی")).not.toBeInTheDocument();
});
it("switches to the previous tab and lists inactive secretaries", async () => {
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
await screen.findAllByText("سارا احمدی");
fireEvent.click(screen.getByText("منشی های قبلی"));
expect(await screen.findAllByText("مینا رضایی")).not.toHaveLength(0);
expect(screen.queryByText("سارا احمدی")).not.toBeInTheDocument();
});
it("shows an empty state when there are no active secretaries", async () => {
mockData([previousSecretary]);
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
expect(await screen.findByText("هنوز منشی فعالی اضافه نشده است")).toBeInTheDocument();
});
it("opens the add modal with permission sections based on existing pages", async () => {
renderWithProviders(<MySecretariesPage />, { route: "/admin/my-secretaries" });
await screen.findAllByText("سارا احمدی");
fireEvent.click(screen.getByText("اضافه کردن منشی"));
expect(await screen.findByText("اضافه کردن منشی جدید")).toBeInTheDocument();
expect(screen.getByText("مجوزهای دسترسی")).toBeInTheDocument();
expect(screen.getByText("مدیریت نوبت‌ها")).toBeInTheDocument();
expect(screen.getByText("پرونده بیماران")).toBeInTheDocument();
expect(screen.getByText("مدیریت پرداخت‌ها")).toBeInTheDocument();
expect(screen.getByText("مدیریت بیمه‌ها")).toBeInTheDocument();
});
});