chat-pane.test.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 {
  10. renderWithChatContext,
  11. cleanUpContext,
  12. } from '../../../helpers/render-with-context'
  13. import { stubMathJax, tearDownMathJaxStubs } from './stubs'
  14. import sinon from 'sinon'
  15. describe('<ChatPane />', function () {
  16. const user = {
  17. id: 'fake_user',
  18. first_name: 'fake_user_first_name',
  19. email: 'fake@example.com',
  20. }
  21. beforeEach(function () {
  22. this.clock = sinon.useFakeTimers({
  23. toFake: ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'],
  24. })
  25. window.metaAttributesCache = new Map()
  26. window.metaAttributesCache.set('ol-user', user)
  27. })
  28. afterEach(function () {
  29. this.clock.runAll()
  30. this.clock.restore()
  31. fetchMock.reset()
  32. window.metaAttributesCache = new Map()
  33. })
  34. const testMessages = [
  35. {
  36. id: 'msg_1',
  37. content: 'a message',
  38. user,
  39. timestamp: new Date().getTime(),
  40. },
  41. {
  42. id: 'msg_2',
  43. content: 'another message',
  44. user,
  45. timestamp: new Date().getTime(),
  46. },
  47. ]
  48. beforeEach(function () {
  49. fetchMock.reset()
  50. cleanUpContext()
  51. stubMathJax()
  52. })
  53. afterEach(function () {
  54. tearDownMathJaxStubs()
  55. })
  56. it('renders multiple messages', async function () {
  57. fetchMock.get(/messages/, testMessages)
  58. renderWithChatContext(<ChatPane />, { user })
  59. await screen.findByText('a message')
  60. await screen.findByText('another message')
  61. })
  62. it('provides error message with reload button on FetchError', async function () {
  63. fetchMock.get(/messages/, 500)
  64. renderWithChatContext(<ChatPane />, { user })
  65. // should have hit a FetchError and will prompt user to reconnect
  66. await screen.findByText('Try again')
  67. // bring chat back up
  68. fetchMock.reset()
  69. fetchMock.get(/messages/, [])
  70. const reconnectButton = screen.getByRole('button', {
  71. name: 'Try again',
  72. })
  73. expect(reconnectButton).to.exist
  74. // should now reconnect with placeholder message
  75. fireEvent.click(reconnectButton)
  76. await screen.findByText('Send your first message to your collaborators')
  77. })
  78. it('a loading spinner is rendered while the messages are loading, then disappears', async function () {
  79. fetchMock.get(/messages/, [], { delay: 1000 })
  80. renderWithChatContext(<ChatPane />, { user })
  81. this.clock.tick(600) // wait for spinner to be displayed
  82. await screen.findByText('Loading…')
  83. this.clock.tick(1000) // wait for response to be received
  84. await waitForElementToBeRemoved(() => screen.getByText('Loading…'))
  85. })
  86. describe('"send your first message" placeholder', function () {
  87. it('is rendered when there are no messages ', async function () {
  88. fetchMock.get(/messages/, [])
  89. renderWithChatContext(<ChatPane />, { user })
  90. await screen.findByText('Send your first message to your collaborators')
  91. })
  92. it('is not rendered when messages are displayed', function () {
  93. fetchMock.get(/messages/, testMessages)
  94. renderWithChatContext(<ChatPane />, { user })
  95. expect(
  96. screen.queryByText('Send your first message to your collaborators')
  97. ).to.not.exist
  98. })
  99. })
  100. })