chat.test.tsx 3.2 KB

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