Files
clinicpro/assets/admin/components/ui/TourButton.test.tsx
T
hamed 20c8eaaad9 feat: add TourProgressController and related entities for user tour progress tracking
- Implemented TourProgressController to handle API endpoints for tracking guided tours seen by users.
- Created UserTourProgress entity to store the highest version of tours seen by each user.
- Developed UserTourProgressRepository for database interactions related to user tour progress.
- Introduced TourProgressService to manage business logic for marking tours as seen and retrieving seen maps.
- Added comprehensive tests for API endpoints and entity behavior to ensure functionality and data integrity.
2026-08-10 09:34:14 +03:30

81 lines
3.0 KiB
TypeScript

import { describe, it, expect, beforeEach, vi } from 'vitest';
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { renderWithProviders } from '@/test/utils';
vi.mock('@/lib/api', () => ({
api: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), put: vi.fn(), delete: vi.fn() },
ApiError: class extends Error {},
}));
const drive = vi.fn();
vi.mock('driver.js', () => ({ driver: vi.fn(() => ({ drive })) }));
vi.mock('driver.js/dist/driver.css', () => ({}));
import { api } from '@/lib/api';
import TourButton from './TourButton';
import PageHeader from './PageHeader';
import { appointmentsTour } from '@/lib/tour/tours/appointments';
const get = api.get as ReturnType<typeof vi.fn>;
beforeEach(() => {
get.mockReset();
get.mockResolvedValue({ data: { seen: {} } });
drive.mockReset();
document.body.innerHTML = '';
});
describe('TourButton', () => {
it('برای تور ثبت‌شده دکمهٔ راهنما می‌آورد', () => {
renderWithProviders(<TourButton tourId="appointments" />);
expect(screen.getByRole('button', { name: 'راهنمای این صفحه' })).toBeInTheDocument();
});
it('برای شناسهٔ ناشناس یا بدون شناسه چیزی رندر نمی‌کند', () => {
const { container } = renderWithProviders(<TourButton tourId="does-not-exist" />);
expect(container).toBeEmptyDOMElement();
const { container: bare } = renderWithProviders(<TourButton />);
expect(bare).toBeEmptyDOMElement();
});
it('کلیک، تور را روی المان‌های موجود اجرا می‌کند', async () => {
const user = userEvent.setup();
renderWithProviders(
<>
<TourButton tourId="appointments" />
{appointmentsTour.steps.map((s) => (
<div key={s.anchor} data-tour={s.anchor} />
))}
</>,
);
await user.click(screen.getByRole('button', { name: 'راهنمای این صفحه' }));
expect(drive).toHaveBeenCalledTimes(1);
});
});
describe('PageHeader', () => {
it('با tourId دکمهٔ راهنما را کنار عنوان می‌گذارد', () => {
renderWithProviders(<PageHeader title="نوبت‌ها" tourId="appointments" />);
expect(screen.getByRole('heading', { name: 'نوبت‌ها' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'راهنمای این صفحه' })).toBeInTheDocument();
});
it('بدون tourId هیچ دکمهٔ راهنمایی ندارد', () => {
renderWithProviders(<PageHeader title="نوبت‌ها" />);
expect(screen.queryByRole('button', { name: 'راهنمای این صفحه' })).toBeNull();
});
it('صفحهٔ بدون تور هیچ درخواستی برای وضعیت تورها نمی‌فرستد', () => {
renderWithProviders(<PageHeader title="نوبت‌ها" />);
expect(get).not.toHaveBeenCalled();
});
});