chat.test.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import { expect } from 'chai'
  2. import {
  3. fireEvent,
  4. screen,
  5. waitForElementToBeRemoved,
  6. } from '@testing-library/react'
  7. import fetchMock from 'fetch-mock'
  8. import ChatPane from '../../../../../frontend/js/features/chat/components/chat-pane'
  9. import { renderWithEditorContext } from '../../../helpers/render-with-context'
  10. import { stubMathJax, tearDownMathJaxStubs } from './stubs'
  11. import { UserId } from '@ol-types/user'
  12. describe('<ChatPane />', function () {
  13. const user = {
  14. id: 'fake_user' as UserId,
  15. first_name: 'fake_user_first_name',
  16. email: 'fake@example.com',
  17. }
  18. beforeEach(function () {
  19. window.metaAttributesCache.set('ol-user', user)
  20. window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
  21. })
  22. afterEach(function () {
  23. fetchMock.removeRoutes().clearHistory()
  24. })
  25. const testMessages = [
  26. {
  27. id: 'msg_1',
  28. content: 'a message',
  29. user,
  30. timestamp: new Date().getTime(),
  31. },
  32. {
  33. id: 'msg_2',
  34. content: 'another message',
  35. user,
  36. timestamp: new Date().getTime(),
  37. },
  38. ]
  39. beforeEach(function () {
  40. fetchMock.removeRoutes().clearHistory()
  41. stubMathJax()
  42. })
  43. afterEach(function () {
  44. tearDownMathJaxStubs()
  45. })
  46. it('renders multiple messages', async function () {
  47. fetchMock.get(/messages/, testMessages)
  48. renderWithEditorContext(<ChatPane />, { user })
  49. await screen.findByText('a message')
  50. await screen.findByText('another message')
  51. })
  52. it('provides error message with reload button on FetchError', async function () {
  53. fetchMock.get(/messages/, 500)
  54. renderWithEditorContext(<ChatPane />, { user })
  55. // should have hit a FetchError and will prompt user to reconnect
  56. await screen.findByText('Try again')
  57. // bring chat back up
  58. fetchMock.removeRoutes().clearHistory()
  59. fetchMock.get(/messages/, [])
  60. const reconnectButton = screen.getByRole('button', {
  61. name: 'Try again',
  62. })
  63. expect(reconnectButton).to.exist
  64. // should now reconnect with placeholder message
  65. fireEvent.click(reconnectButton)
  66. await screen.findByText(
  67. 'Start the conversation by saying hello or sharing an update'
  68. )
  69. })
  70. it('a loading spinner is rendered while the messages are loading, then disappears', async function () {
  71. fetchMock.get(/messages/, [], { delay: 1000 })
  72. renderWithEditorContext(<ChatPane />, { user })
  73. // not displayed initially
  74. expect(screen.queryByText('Loading…')).to.not.exist
  75. // eventually displayed
  76. await screen.findByText('Loading…')
  77. // eventually removed when the fetch call returns
  78. await waitForElementToBeRemoved(() => screen.getByText('Loading…'))
  79. })
  80. describe('"send your first message" placeholder', function () {
  81. it('is rendered when there are no messages ', async function () {
  82. fetchMock.get(/messages/, [])
  83. renderWithEditorContext(<ChatPane />, { user })
  84. await screen.findByText(
  85. 'Start the conversation by saying hello or sharing an update'
  86. )
  87. })
  88. it('is not rendered when messages are displayed', function () {
  89. fetchMock.get(/messages/, testMessages)
  90. renderWithEditorContext(<ChatPane />, { user })
  91. expect(
  92. screen.queryByText(
  93. 'Start the conversation by saying hello or sharing an update'
  94. )
  95. ).to.not.exist
  96. })
  97. })
  98. })