chat-pane.test.js 3.2 KB

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