|
|
@@ -1,6 +1,6 @@
|
|
|
import { render, fireEvent, waitFor } from '@testing-library/react'
|
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
|
-import { mockShowModal, mockShowToast, mockGetNetworkType } from '~/__mocks__/taroMock'
|
|
|
+import { mockShowModal, mockShowToast, mockGetNetworkType, mockGetEnv } from '~/__mocks__/taroMock'
|
|
|
import OrderButtonBar from '@/components/order/OrderButtonBar'
|
|
|
|
|
|
|
|
|
@@ -54,6 +54,8 @@ describe('OrderButtonBar', () => {
|
|
|
}
|
|
|
return Promise.resolve()
|
|
|
})
|
|
|
+ // 模拟环境检查
|
|
|
+ mockGetEnv.mockReturnValue('WEB')
|
|
|
})
|
|
|
|
|
|
it('should render cancel button for unpaid order', () => {
|
|
|
@@ -69,9 +71,7 @@ describe('OrderButtonBar', () => {
|
|
|
})
|
|
|
|
|
|
it('should show cancel reason dialog when cancel button is clicked', async () => {
|
|
|
- mockShowModal.mockResolvedValue({ confirm: true, content: '测试取消原因' })
|
|
|
-
|
|
|
- const { getByText } = render(
|
|
|
+ const { getByText, getByTestId } = render(
|
|
|
<TestWrapper>
|
|
|
<OrderButtonBar order={mockOrder} onViewDetail={jest.fn()} />
|
|
|
</TestWrapper>
|
|
|
@@ -80,32 +80,53 @@ describe('OrderButtonBar', () => {
|
|
|
fireEvent.click(getByText('取消订单'))
|
|
|
|
|
|
await waitFor(() => {
|
|
|
- expect(mockShowModal).toHaveBeenCalledWith({
|
|
|
- title: '取消订单',
|
|
|
- content: '请填写取消原因:',
|
|
|
- editable: true,
|
|
|
- placeholderText: '请输入取消原因(必填)'
|
|
|
- })
|
|
|
+ expect(getByTestId('cancel-reason-dialog')).toBeTruthy()
|
|
|
+ // 检查对话框内容
|
|
|
+ expect(getByText('请选择或填写取消原因,这将帮助我们改进服务')).toBeTruthy()
|
|
|
})
|
|
|
})
|
|
|
|
|
|
it('should call API when cancel order is confirmed', async () => {
|
|
|
const mockApiCall = require('@/api').orderClient.cancelOrder.$post as jest.Mock
|
|
|
|
|
|
- mockShowModal
|
|
|
- .mockResolvedValueOnce({ confirm: true, content: '测试取消原因' }) // 原因输入
|
|
|
- .mockResolvedValueOnce({ confirm: true }) // 确认取消
|
|
|
+ mockShowModal.mockResolvedValueOnce({ confirm: true }) // 确认取消
|
|
|
|
|
|
mockApiCall.mockResolvedValue({ status: 200, json: () => Promise.resolve({ success: true, message: '取消成功' }) })
|
|
|
|
|
|
- const { getByText } = render(
|
|
|
+ const { getByText, getByPlaceholderText, getByTestId } = render(
|
|
|
<TestWrapper>
|
|
|
<OrderButtonBar order={mockOrder} onViewDetail={jest.fn()} />
|
|
|
</TestWrapper>
|
|
|
)
|
|
|
|
|
|
+ // 打开取消对话框
|
|
|
fireEvent.click(getByText('取消订单'))
|
|
|
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(getByTestId('cancel-reason-dialog')).toBeTruthy()
|
|
|
+ })
|
|
|
+
|
|
|
+ // 输入取消原因
|
|
|
+ const reasonInput = getByPlaceholderText('请输入其他取消原因...')
|
|
|
+ fireEvent.change(reasonInput, { target: { value: '测试取消原因' } })
|
|
|
+
|
|
|
+ // 点击确认取消按钮
|
|
|
+ fireEvent.click(getByText('确认取消'))
|
|
|
+
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(mockShowModal).toHaveBeenCalledWith({
|
|
|
+ title: '确认取消',
|
|
|
+ content: '确定要取消订单吗?\n取消原因:测试取消原因',
|
|
|
+ success: expect.any(Function)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // 模拟确认对话框确认
|
|
|
+ const modalCall = mockShowModal.mock.calls[0][0]
|
|
|
+ if (modalCall.success) {
|
|
|
+ modalCall.success({ confirm: true })
|
|
|
+ }
|
|
|
+
|
|
|
await waitFor(() => {
|
|
|
expect(mockApiCall).toHaveBeenCalledWith({
|
|
|
json: {
|
|
|
@@ -117,42 +138,69 @@ describe('OrderButtonBar', () => {
|
|
|
})
|
|
|
|
|
|
it('should show error when cancel reason is empty', async () => {
|
|
|
- mockShowModal.mockResolvedValue({ confirm: true, content: '' })
|
|
|
-
|
|
|
- const { getByText } = render(
|
|
|
+ const { getByText, getByTestId } = render(
|
|
|
<TestWrapper>
|
|
|
<OrderButtonBar order={mockOrder} onViewDetail={jest.fn()} />
|
|
|
</TestWrapper>
|
|
|
)
|
|
|
|
|
|
+ // 打开取消对话框
|
|
|
fireEvent.click(getByText('取消订单'))
|
|
|
|
|
|
await waitFor(() => {
|
|
|
- expect(mockShowToast).toHaveBeenCalledWith({
|
|
|
- title: '请填写取消原因',
|
|
|
- icon: 'error',
|
|
|
- duration: 2000
|
|
|
- })
|
|
|
+ expect(getByTestId('cancel-reason-dialog')).toBeTruthy()
|
|
|
+ })
|
|
|
+
|
|
|
+ // 直接点击确认取消按钮(不输入原因)
|
|
|
+ fireEvent.click(getByText('确认取消'))
|
|
|
+
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(getByTestId('error-message')).toBeTruthy()
|
|
|
+ expect(getByText('请输入取消原因')).toBeTruthy()
|
|
|
})
|
|
|
})
|
|
|
|
|
|
it('should handle network error gracefully', async () => {
|
|
|
const mockApiCall = require('@/api').orderClient.cancelOrder.$post as jest.Mock
|
|
|
|
|
|
- mockShowModal
|
|
|
- .mockResolvedValueOnce({ confirm: true, content: '测试取消原因' })
|
|
|
- .mockResolvedValueOnce({ confirm: true })
|
|
|
+ mockShowModal.mockResolvedValueOnce({ confirm: true })
|
|
|
|
|
|
mockApiCall.mockRejectedValue(new Error('网络连接失败'))
|
|
|
|
|
|
- const { getByText } = render(
|
|
|
+ const { getByText, getByPlaceholderText, getByTestId } = render(
|
|
|
<TestWrapper>
|
|
|
<OrderButtonBar order={mockOrder} onViewDetail={jest.fn()} />
|
|
|
</TestWrapper>
|
|
|
)
|
|
|
|
|
|
+ // 打开取消对话框
|
|
|
fireEvent.click(getByText('取消订单'))
|
|
|
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(getByTestId('cancel-reason-dialog')).toBeTruthy()
|
|
|
+ })
|
|
|
+
|
|
|
+ // 输入取消原因
|
|
|
+ const reasonInput = getByPlaceholderText('请输入其他取消原因...')
|
|
|
+ fireEvent.change(reasonInput, { target: { value: '测试取消原因' } })
|
|
|
+
|
|
|
+ // 点击确认取消按钮
|
|
|
+ fireEvent.click(getByText('确认取消'))
|
|
|
+
|
|
|
+ // 模拟确认对话框确认
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(mockShowModal).toHaveBeenCalledWith({
|
|
|
+ title: '确认取消',
|
|
|
+ content: '确定要取消订单吗?\n取消原因:测试取消原因',
|
|
|
+ success: expect.any(Function)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ const modalCall = mockShowModal.mock.calls[0][0]
|
|
|
+ if (modalCall.success) {
|
|
|
+ modalCall.success({ confirm: true })
|
|
|
+ }
|
|
|
+
|
|
|
await waitFor(() => {
|
|
|
expect(mockShowToast).toHaveBeenCalledWith({
|
|
|
title: '网络连接失败,请检查网络后重试',
|
|
|
@@ -164,24 +212,47 @@ describe('OrderButtonBar', () => {
|
|
|
|
|
|
it('should disable cancel button during mutation', async () => {
|
|
|
// 模拟mutation正在进行中
|
|
|
- // mockUseMutation.mockReturnValueOnce({
|
|
|
- // mutate: jest.fn(),
|
|
|
- // mutateAsync: jest.fn(),
|
|
|
- // isLoading: true,
|
|
|
- // isPending: true,
|
|
|
- // isError: false,
|
|
|
- // isSuccess: false,
|
|
|
- // error: null,
|
|
|
- // data: null
|
|
|
- // })
|
|
|
+ const mockApiCall = require('@/api').orderClient.cancelOrder.$post as jest.Mock
|
|
|
+ mockApiCall.mockImplementation(() => new Promise(() => {})) // 永不resolve的promise
|
|
|
|
|
|
- const { getByText } = render(
|
|
|
+ const { getByText, getByPlaceholderText, getByTestId } = render(
|
|
|
<TestWrapper>
|
|
|
<OrderButtonBar order={mockOrder} onViewDetail={jest.fn()} />
|
|
|
</TestWrapper>
|
|
|
)
|
|
|
|
|
|
- expect(getByText('取消中...')).toBeTruthy()
|
|
|
+ // 打开取消对话框
|
|
|
+ fireEvent.click(getByText('取消订单'))
|
|
|
+
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(getByTestId('cancel-reason-dialog')).toBeTruthy()
|
|
|
+ })
|
|
|
+
|
|
|
+ // 输入取消原因
|
|
|
+ const reasonInput = getByPlaceholderText('请输入其他取消原因...')
|
|
|
+ fireEvent.change(reasonInput, { target: { value: '测试取消原因' } })
|
|
|
+
|
|
|
+ // 点击确认取消按钮
|
|
|
+ fireEvent.click(getByText('确认取消'))
|
|
|
+
|
|
|
+ // 模拟确认对话框确认
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(mockShowModal).toHaveBeenCalledWith({
|
|
|
+ title: '确认取消',
|
|
|
+ content: '确定要取消订单吗?\n取消原因:测试取消原因',
|
|
|
+ success: expect.any(Function)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ const modalCall = mockShowModal.mock.calls[0][0]
|
|
|
+ if (modalCall.success) {
|
|
|
+ modalCall.success({ confirm: true })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查按钮状态
|
|
|
+ await waitFor(() => {
|
|
|
+ expect(getByText('取消中...')).toBeTruthy()
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it('should not show cancel button for shipped order', () => {
|