| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import { fireEvent, render, screen } from '@testing-library/react';
- import { beforeEach, expect, test, vi } from 'vitest';
- import ServicesPage from '@/pages/Services';
- import { apiRequest } from '@/services/api';
- vi.mock('@/services/api', () => ({
- apiRequest: vi.fn(),
- jsonOptions: vi.fn((method, body) => ({ method, body: JSON.stringify(body) })),
- }));
- const emptyPage = { items: [], total: 0, page: 1, page_size: 20 };
- beforeEach(() => {
- vi.mocked(apiRequest).mockImplementation(async (path) => {
- if (path === '/directory/fulfillment-metrics') {
- return {
- counts: {},
- valid_requests: 12,
- quoted_requests: 9,
- confirmed_requests: 6,
- request_submission_rate: 1,
- quote_rate: 0.75,
- customer_confirmation_rate: 0.6667,
- match_success_rate: 0.5,
- fulfillment_rate: 0.8333,
- cancellation_rate: 0.1,
- cancellation_distribution: { customer: 1, technician: 0 },
- scope_note: '仅统计平台服务单;直接 Telegram 私聊成交不在统计范围。',
- };
- }
- if (path === '/directory/service-settings') {
- return {
- customer_max_open_orders: 3,
- customer_daily_request_limit: 10,
- review_qr_expiry_hours: 24,
- };
- }
- if (path.startsWith('/directory/package-templates')) {
- return {
- items: [
- {
- template_id: 'tpl1',
- version: 2,
- name: '基础护理模板',
- status: 'enabled',
- sort_order: 1,
- created_at: '2026-07-26T00:00:00Z',
- updated_at: '2026-07-26T00:00:00Z',
- package: {
- package_id: 'pkg1',
- name: '基础护理',
- category: '护理',
- description: '标准服务',
- tags: ['护理'],
- service_modes: ['at_store'],
- price_mode: 'fixed',
- currency: 'CNY',
- price_unit: 'per_service',
- min_price: '100.00',
- max_price: '100.00',
- addons: [],
- travel_fee: { mode: 'quoted' },
- },
- },
- ],
- total: 1,
- };
- }
- if (path.startsWith('/directory/service-orders')) return emptyPage;
- if (path.startsWith('/directory/reviews')) return emptyPage;
- if (path.startsWith('/directory/review-qrs')) return emptyPage;
- if (path.startsWith('/directory/leaderboard')) return emptyPage;
- if (path.startsWith('/directory/customer-blocks')) return emptyPage;
- if (path.startsWith('/directory/reports')) return emptyPage;
- if (path === '/directory/review-template') {
- return {
- template_id: 'review1',
- version: 1,
- status: 'active',
- published_at: '2026-07-26T00:00:00Z',
- rating_questions: [
- { question_id: 'effect', label: '服务效果', required: true, weight: 100 },
- ],
- text_questions: [],
- };
- }
- throw new Error(`Unexpected request: ${path}`);
- });
- });
- test('展示履约漏斗、统计边界和套餐模板', async () => {
- render(<ServicesPage />);
- expect(screen.getByText('技师服务')).toBeInTheDocument();
- expect(screen.getByText('最小履约闭环')).toBeInTheDocument();
- expect(await screen.findByText('12')).toBeInTheDocument();
- expect(screen.getByText('仅统计平台服务单;直接 Telegram 私聊成交不在统计范围。')).toBeInTheDocument();
- fireEvent.click(screen.getByRole('tab', { name: /套餐模板/ }));
- expect(await screen.findByText('基础护理模板')).toBeInTheDocument();
- expect(screen.getByText('护理 · V2')).toBeInTheDocument();
- fireEvent.click(screen.getByRole('button', { name: '新建模板' }));
- expect(await screen.findByText('标准加项(最多 10 个)')).toBeInTheDocument();
- expect(screen.getByRole('button', { name: '增加标准加项' })).toBeInTheDocument();
- });
|