CancelReasonDialog.test.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { render, fireEvent } from '@testing-library/react'
  2. import { mockShowToast } from '~/__mocks__/taroMock'
  3. import CancelReasonDialog from '@/components/common/CancelReasonDialog'
  4. describe('CancelReasonDialog', () => {
  5. const defaultProps = {
  6. open: true,
  7. onOpenChange: jest.fn(),
  8. onConfirm: jest.fn(),
  9. loading: false
  10. }
  11. beforeEach(() => {
  12. jest.clearAllMocks()
  13. })
  14. it('应该渲染对话框当可见时为true', () => {
  15. const { getByText, getAllByText } = render(<CancelReasonDialog {...defaultProps} />)
  16. expect(getByText('取消订单')).toBeTruthy()
  17. expect(getByText('请选择或填写取消原因,这将帮助我们改进服务')).toBeTruthy()
  18. expect(getByText('我不想买了')).toBeTruthy()
  19. expect(getByText('信息填写错误,重新下单')).toBeTruthy()
  20. expect(getByText('商家缺货')).toBeTruthy()
  21. expect(getByText('价格不合适')).toBeTruthy()
  22. // 有多个"其他原因"文本,使用getAllByText
  23. expect(getAllByText('其他原因').length).toBeGreaterThan(0)
  24. })
  25. it('不应该渲染对话框当open为false时', () => {
  26. const { queryByText } = render(
  27. <CancelReasonDialog {...defaultProps} open={false} />
  28. )
  29. expect(queryByText('取消订单')).toBeNull()
  30. })
  31. it.each([
  32. '我不想买了',
  33. '信息填写错误,重新下单',
  34. '商家缺货',
  35. '价格不合适',
  36. '其他原因'
  37. ])('应该选择预定义原因 %s 当点击时', (reason) => {
  38. const { getByTestId } = render(<CancelReasonDialog {...defaultProps} />)
  39. const reasonOption = getByTestId(`cancel-reason-${reason}`)
  40. fireEvent.click(reasonOption)
  41. const confirmButton = getByTestId('confirm-cancel-button')
  42. fireEvent.click(confirmButton)
  43. expect(defaultProps.onConfirm).toHaveBeenCalledWith(reason)
  44. })
  45. it('应该调用onConfirm当确认按钮被点击时', () => {
  46. const { getByTestId } = render(<CancelReasonDialog {...defaultProps} />)
  47. const reasonOption = getByTestId('cancel-reason-我不想买了')
  48. fireEvent.click(reasonOption)
  49. const confirmButton = getByTestId('confirm-cancel-button')
  50. fireEvent.click(confirmButton)
  51. expect(defaultProps.onConfirm).toHaveBeenCalledWith('我不想买了')
  52. })
  53. it('应该调用onOpenChange当取消按钮被点击时', () => {
  54. const { getByText } = render(<CancelReasonDialog {...defaultProps} />)
  55. const cancelButton = getByText('取消')
  56. fireEvent.click(cancelButton)
  57. expect(defaultProps.onOpenChange).toHaveBeenCalledWith(false)
  58. })
  59. it('应该显示错误当确认空原因时', () => {
  60. const { getByTestId, getByText } = render(<CancelReasonDialog {...defaultProps} />)
  61. const confirmButton = getByTestId('confirm-cancel-button')
  62. fireEvent.click(confirmButton)
  63. // 使用更精确的查询方式查找错误消息
  64. const errorMessage = getByText('请输入取消原因')
  65. expect(errorMessage).toBeTruthy()
  66. expect(defaultProps.onConfirm).not.toHaveBeenCalled()
  67. })
  68. it('应该显示错误当原因超过200字符时', () => {
  69. const { getByPlaceholderText, getByTestId, getByText } = render(
  70. <CancelReasonDialog {...defaultProps} />
  71. )
  72. const input = getByPlaceholderText('请输入其他取消原因...')
  73. fireEvent.input(input, { target: { value: 'a'.repeat(201) } })
  74. const confirmButton = getByTestId('confirm-cancel-button')
  75. fireEvent.click(confirmButton)
  76. const errorMessage = getByText('取消原因不能超过200个字符')
  77. expect(errorMessage).toBeTruthy()
  78. expect(defaultProps.onConfirm).not.toHaveBeenCalled()
  79. })
  80. it('应该处理自定义原因输入', () => {
  81. const { getByPlaceholderText, getByTestId } = render(
  82. <CancelReasonDialog {...defaultProps} />
  83. )
  84. const input = getByPlaceholderText('请输入其他取消原因...')
  85. fireEvent.input(input, { target: { value: '自定义取消原因' } })
  86. const confirmButton = getByTestId('confirm-cancel-button')
  87. fireEvent.click(confirmButton)
  88. expect(defaultProps.onConfirm).toHaveBeenCalledWith('自定义取消原因')
  89. })
  90. it('应该显示加载状态当loading为true时', () => {
  91. const { getByTestId } = render(
  92. <CancelReasonDialog {...defaultProps} loading={true} />
  93. )
  94. const confirmButton = getByTestId('confirm-cancel-button')
  95. expect(confirmButton).toHaveTextContent('提交中...')
  96. })
  97. it('应该禁用按钮当loading为true时', () => {
  98. const { getByText, getByTestId } = render(
  99. <CancelReasonDialog {...defaultProps} loading={true} />
  100. )
  101. const cancelButton = getByText('取消')
  102. const confirmButton = getByTestId('confirm-cancel-button')
  103. // 检查按钮是否被禁用
  104. expect(cancelButton).toBeTruthy()
  105. expect(confirmButton).toBeTruthy()
  106. })
  107. it('应该重置状态当对话框关闭时', () => {
  108. const { getByTestId, getByText, rerender } = render(
  109. <CancelReasonDialog {...defaultProps} />
  110. )
  111. const reasonOption = getByTestId('cancel-reason-我不想买了')
  112. fireEvent.click(reasonOption)
  113. // 重新渲染关闭的对话框
  114. rerender(<CancelReasonDialog {...defaultProps} open={false} />)
  115. // 重新渲染打开的对话框
  116. rerender(<CancelReasonDialog {...defaultProps} open={true} />)
  117. // 检查状态是否重置 - 直接点击确认按钮应该显示错误
  118. const confirmButton = getByTestId('confirm-cancel-button')
  119. fireEvent.click(confirmButton)
  120. const errorMessage = getByText('请输入取消原因')
  121. expect(errorMessage).toBeTruthy()
  122. })
  123. })