import React from 'react' import { render, screen, fireEvent, waitFor } from '@testing-library/react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import AddressManagePage from '@/pages/address-manage/index' // 导入Taro mock函数 import { mockGetCurrentPages, mockNavigateTo, mockShowModal } from '~/__mocks__/taroMock' // Mock API client jest.mock('@/api', () => ({ deliveryAddressClient: { $get: jest.fn(), $post: jest.fn(), ':id': { $put: jest.fn(), $delete: jest.fn(), }, }, })) // Mock auth hook jest.mock('@/utils/auth', () => ({ useAuth: () => ({ user: { id: 1 }, }), })) // Mock components jest.mock('@/components/ui/navbar', () => ({ Navbar: ({ title, onClickLeft }: { title: string; onClickLeft: () => void }) => (
{title}
), })) jest.mock('@/components/ui/button', () => ({ Button: ({ children, onClick, disabled, className }: any) => ( ), })) describe('AddressManagePage', () => { let queryClient: QueryClient beforeEach(() => { queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false }, }, }) // Reset all mocks jest.clearAllMocks() // 设置 getCurrentPages 的默认返回值 mockGetCurrentPages.mockReturnValue([{ route: 'pages/address-manage/index' }]) }) const renderWithProviders = (component: React.ReactElement) => { return render( {component} ) } const mockAddresses = [ { id: 1, name: '张三', phone: '13812345678', province: { name: '广东省' }, city: { name: '深圳市' }, district: { name: '南山区' }, town: { name: '科技园' }, address: '科技大厦A座', isDefault: 1, }, { id: 2, name: '李四', phone: '13987654321', province: { name: '北京市' }, city: { name: '北京市' }, district: { name: '朝阳区' }, town: { name: '' }, address: '国贸中心', isDefault: 0, }, ] it('渲染页面标题和布局', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: [] }), } as any) renderWithProviders() expect(screen.getByTestId('navbar')).toBeInTheDocument() expect(screen.getByText('收货地址')).toBeInTheDocument() }) it('显示地址列表', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: mockAddresses }), } as any) renderWithProviders() await waitFor(() => { expect(screen.getByText('张三')).toBeInTheDocument() expect(screen.getByText('李四')).toBeInTheDocument() expect(screen.getByText('138****5678')).toBeInTheDocument() expect(screen.getByText('139****4321')).toBeInTheDocument() expect(screen.getByText('默认')).toBeInTheDocument() }) }) it('显示空状态', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: [] }), } as any) renderWithProviders() await waitFor(() => { expect(screen.getByText('暂无收货地址')).toBeInTheDocument() }) }) it('显示地址数量限制提示', async () => { const { deliveryAddressClient } = await import('@/api') const addresses = Array.from({ length: 20 }, (_, i) => ({ id: i + 1, name: `用户${i + 1}`, phone: '13812345678', province: { name: '广东省' }, city: { name: '深圳市' }, district: { name: '南山区' }, address: '测试地址', isDefault: i === 0 ? 1 : 0, })) ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: addresses }), } as any) renderWithProviders() await waitFor(() => { expect(screen.getByText('最多可添加20个收货地址')).toBeInTheDocument() }) }) it('点击添加地址按钮', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: [] }), } as any) renderWithProviders() await waitFor(() => { const addButton = screen.getByText('添加新地址') fireEvent.click(addButton) expect(mockNavigateTo).toHaveBeenCalledWith({ url: '/pages/address-edit/index', }) }) }) it('点击编辑地址按钮', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: mockAddresses }), } as any) renderWithProviders() await waitFor(() => { const editButtons = screen.getAllByText('编辑') fireEvent.click(editButtons[0]) expect(mockNavigateTo).toHaveBeenCalledWith({ url: '/pages/address-edit/index?id=1', }) }) }) it('点击设为默认按钮', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: mockAddresses }), } as any) ;(deliveryAddressClient[':id'].$put as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({}), } as any) renderWithProviders() await waitFor(() => { const setDefaultButtons = screen.getAllByText('设为默认') fireEvent.click(setDefaultButtons[0]) expect(deliveryAddressClient[':id'].$put).toHaveBeenCalledWith({ param: { id: 2 }, json: { isDefault: 1 }, }) }) }) it('点击删除按钮', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: mockAddresses }), } as any) ;(deliveryAddressClient[':id'].$delete as jest.Mock).mockResolvedValue({ status: 204, json: async () => ({}), } as any) renderWithProviders() await waitFor(() => { const deleteButtons = screen.getAllByText('删除') fireEvent.click(deleteButtons[0]) expect(mockShowModal).toHaveBeenCalled() }) }) it('验证样式类名应用', async () => { const { deliveryAddressClient } = await import('@/api') ;(deliveryAddressClient.$get as jest.Mock).mockResolvedValue({ status: 200, json: async () => ({ data: mockAddresses }), } as any) renderWithProviders() await waitFor(() => { const container = document.querySelector('.address-container') expect(container).toBeInTheDocument() const addressList = document.querySelector('.address-list') expect(addressList).toBeInTheDocument() const addressItems = document.querySelectorAll('.address-item') expect(addressItems).toHaveLength(2) const bottomFixed = document.querySelector('.bottom-fixed') expect(bottomFixed).toBeInTheDocument() }) }) })