CancelReasonDialog.test.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import { render, fireEvent } from '@testing-library/react'
  2. import Taro from '@tarojs/taro'
  3. import CancelReasonDialog from '@/components/common/CancelReasonDialog'
  4. // Mock Taro API
  5. jest.mock('@tarojs/taro', () => ({
  6. showToast: jest.fn()
  7. }))
  8. describe('CancelReasonDialog', () => {
  9. const defaultProps = {
  10. visible: true,
  11. onCancel: jest.fn(),
  12. onConfirm: jest.fn(),
  13. loading: false
  14. }
  15. beforeEach(() => {
  16. jest.clearAllMocks()
  17. })
  18. it('should render dialog when visible is true', () => {
  19. const { getByText } = render(<CancelReasonDialog {...defaultProps} />)
  20. expect(getByText('取消订单')).toBeTruthy()
  21. expect(getByText('请选择或填写取消原因:')).toBeTruthy()
  22. expect(getByText('我不想买了')).toBeTruthy()
  23. expect(getByText('信息填写错误,重新下单')).toBeTruthy()
  24. expect(getByText('商家缺货')).toBeTruthy()
  25. expect(getByText('价格不合适')).toBeTruthy()
  26. expect(getByText('其他原因')).toBeTruthy()
  27. })
  28. it('should not render dialog when visible is false', () => {
  29. const { queryByText } = render(
  30. <CancelReasonDialog {...defaultProps} visible={false} />
  31. )
  32. expect(queryByText('取消订单')).toBeNull()
  33. })
  34. it('should select predefined reason when clicked', () => {
  35. const { getByText } = render(<CancelReasonDialog {...defaultProps} />)
  36. const reasonOption = getByText('我不想买了')
  37. fireEvent.click(reasonOption)
  38. // 检查样式变化(这里需要根据实际实现调整)
  39. expect(reasonOption).toBeTruthy()
  40. })
  41. it('should call onConfirm with reason when confirm button is clicked', () => {
  42. const { getByText } = render(<CancelReasonDialog {...defaultProps} />)
  43. const reasonOption = getByText('我不想买了')
  44. fireEvent.click(reasonOption)
  45. const confirmButton = getByText('确认取消')
  46. fireEvent.click(confirmButton)
  47. expect(defaultProps.onConfirm).toHaveBeenCalledWith('我不想买了')
  48. })
  49. it('should call onCancel when cancel button is clicked', () => {
  50. const { getByText } = render(<CancelReasonDialog {...defaultProps} />)
  51. const cancelButton = getByText('取消')
  52. fireEvent.click(cancelButton)
  53. expect(defaultProps.onCancel).toHaveBeenCalled()
  54. })
  55. it('should show error when confirming with empty reason', () => {
  56. const mockShowToast = Taro.showToast as jest.Mock
  57. const { getByText } = render(<CancelReasonDialog {...defaultProps} />)
  58. const confirmButton = getByText('确认取消')
  59. fireEvent.click(confirmButton)
  60. expect(mockShowToast).toHaveBeenCalledWith({
  61. title: '请填写取消原因',
  62. icon: 'error',
  63. duration: 2000
  64. })
  65. expect(defaultProps.onConfirm).not.toHaveBeenCalled()
  66. })
  67. it('should show error when reason exceeds 500 characters', () => {
  68. const mockShowToast = Taro.showToast as jest.Mock
  69. const { getByPlaceholderText, getByText } = render(
  70. <CancelReasonDialog {...defaultProps} />
  71. )
  72. const input = getByPlaceholderText('请输入其他取消原因...')
  73. fireEvent.input(input, { target: { value: 'a'.repeat(501) } })
  74. const confirmButton = getByText('确认取消')
  75. fireEvent.click(confirmButton)
  76. expect(mockShowToast).toHaveBeenCalledWith({
  77. title: '取消原因不能超过500字',
  78. icon: 'error',
  79. duration: 2000
  80. })
  81. expect(defaultProps.onConfirm).not.toHaveBeenCalled()
  82. })
  83. it('should handle custom reason input', () => {
  84. const { getByPlaceholderText, getByText } = render(
  85. <CancelReasonDialog {...defaultProps} />
  86. )
  87. const input = getByPlaceholderText('请输入其他取消原因...')
  88. fireEvent.input(input, { target: { value: '自定义取消原因' } })
  89. const confirmButton = getByText('确认取消')
  90. fireEvent.click(confirmButton)
  91. expect(defaultProps.onConfirm).toHaveBeenCalledWith('自定义取消原因')
  92. })
  93. it('should show loading state when loading is true', () => {
  94. const { getByText } = render(
  95. <CancelReasonDialog {...defaultProps} loading={true} />
  96. )
  97. expect(getByText('提交中...')).toBeTruthy()
  98. })
  99. it('should disable buttons when loading is true', () => {
  100. const { getByText } = render(
  101. <CancelReasonDialog {...defaultProps} loading={true} />
  102. )
  103. const cancelButton = getByText('取消')
  104. const confirmButton = getByText('提交中...')
  105. // 检查按钮是否被禁用(这里需要根据实际实现调整)
  106. expect(cancelButton).toBeTruthy()
  107. expect(confirmButton).toBeTruthy()
  108. })
  109. it('should reset state when dialog is closed', () => {
  110. const { getByText, rerender } = render(
  111. <CancelReasonDialog {...defaultProps} />
  112. )
  113. const reasonOption = getByText('我不想买了')
  114. fireEvent.click(reasonOption)
  115. // 重新渲染关闭的对话框
  116. rerender(<CancelReasonDialog {...defaultProps} visible={false} />)
  117. rerender(<CancelReasonDialog {...defaultProps} visible={true} />)
  118. // 检查状态是否重置
  119. const confirmButton = getByText('确认取消')
  120. fireEvent.click(confirmButton)
  121. expect(Taro.showToast).toHaveBeenCalledWith({
  122. title: '请填写取消原因',
  123. icon: 'error',
  124. duration: 2000
  125. })
  126. })
  127. })