account-info-section.test.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import { expect } from 'chai'
  2. import { fireEvent, screen, render } from '@testing-library/react'
  3. import fetchMock from 'fetch-mock'
  4. import AccountInfoSection from '../../../../../frontend/js/features/settings/components/account-info-section'
  5. describe('<AccountInfoSection />', function () {
  6. beforeEach(function () {
  7. window.metaAttributesCache = window.metaAttributesCache || new Map()
  8. window.metaAttributesCache.set('ol-usersEmail', 'sherlock@holmes.co.uk')
  9. window.metaAttributesCache.set('ol-firstName', 'Sherlock')
  10. window.metaAttributesCache.set('ol-lastName', 'Holmes')
  11. window.metaAttributesCache.set('ol-ExposedSettings', {
  12. hasAffiliationsFeature: false,
  13. })
  14. window.metaAttributesCache.set(
  15. 'ol-isExternalAuthenticationSystemUsed',
  16. false
  17. )
  18. window.metaAttributesCache.set('ol-shouldAllowEditingDetails', true)
  19. })
  20. afterEach(function () {
  21. window.metaAttributesCache = new Map()
  22. fetchMock.reset()
  23. })
  24. it('submits all inputs', async function () {
  25. const updateMock = fetchMock.post('/user/settings', 200)
  26. render(<AccountInfoSection />)
  27. fireEvent.change(screen.getByLabelText('Email'), {
  28. target: { value: 'john@watson.co.uk' },
  29. })
  30. fireEvent.change(screen.getByLabelText('First Name'), {
  31. target: { value: 'John' },
  32. })
  33. fireEvent.change(screen.getByLabelText('Last Name'), {
  34. target: { value: 'Watson' },
  35. })
  36. fireEvent.click(
  37. screen.getByRole('button', {
  38. name: 'Update',
  39. })
  40. )
  41. expect(updateMock.called()).to.be.true
  42. expect(JSON.parse(updateMock.lastCall()[1].body)).to.deep.equal({
  43. email: 'john@watson.co.uk',
  44. firstName: 'John',
  45. lastName: 'Watson',
  46. })
  47. })
  48. it('disables button on invalid email', async function () {
  49. const updateMock = fetchMock.post('/user/settings', 200)
  50. render(<AccountInfoSection />)
  51. fireEvent.change(screen.getByLabelText('Email'), {
  52. target: { value: 'john' },
  53. })
  54. const button = screen.getByRole('button', {
  55. name: 'Update',
  56. })
  57. expect(button.disabled).to.be.true
  58. fireEvent.click(button)
  59. expect(updateMock.called()).to.be.false
  60. })
  61. it('shows inflight state and success message', async function () {
  62. let finishUpdateCall
  63. fetchMock.post(
  64. '/user/settings',
  65. new Promise(resolve => (finishUpdateCall = resolve))
  66. )
  67. render(<AccountInfoSection />)
  68. fireEvent.click(
  69. screen.getByRole('button', {
  70. name: 'Update',
  71. })
  72. )
  73. await screen.findByText('Saving…')
  74. finishUpdateCall(200)
  75. await screen.findByRole('button', {
  76. name: 'Update',
  77. })
  78. screen.getByText('Thanks, your settings have been updated.')
  79. })
  80. it('shows server error', async function () {
  81. fetchMock.post('/user/settings', 500)
  82. render(<AccountInfoSection />)
  83. fireEvent.click(
  84. screen.getByRole('button', {
  85. name: 'Update',
  86. })
  87. )
  88. await screen.findByText(
  89. 'Something went wrong talking to the server :(. Please try again.'
  90. )
  91. })
  92. it('shows invalid error', async function () {
  93. fetchMock.post('/user/settings', 400)
  94. render(<AccountInfoSection />)
  95. fireEvent.click(
  96. screen.getByRole('button', {
  97. name: 'Update',
  98. })
  99. )
  100. await screen.findByText(
  101. 'Invalid Request. Please correct the data and try again.'
  102. )
  103. })
  104. it('shows conflict error', async function () {
  105. fetchMock.post('/user/settings', {
  106. status: 409,
  107. body: {
  108. message: 'This email is already registered',
  109. },
  110. })
  111. render(<AccountInfoSection />)
  112. fireEvent.click(
  113. screen.getByRole('button', {
  114. name: 'Update',
  115. })
  116. )
  117. await screen.findByText('This email is already registered')
  118. })
  119. it('hides email input', async function () {
  120. window.metaAttributesCache.set('ol-ExposedSettings', {
  121. hasAffiliationsFeature: true,
  122. })
  123. const updateMock = fetchMock.post('/user/settings', 200)
  124. render(<AccountInfoSection />)
  125. expect(screen.queryByLabelText('Email')).to.not.exist
  126. fireEvent.click(
  127. screen.getByRole('button', {
  128. name: 'Update',
  129. })
  130. )
  131. expect(JSON.parse(updateMock.lastCall()[1].body)).to.deep.equal({
  132. firstName: 'Sherlock',
  133. lastName: 'Holmes',
  134. })
  135. })
  136. it('disables email input', async function () {
  137. window.metaAttributesCache.set(
  138. 'ol-isExternalAuthenticationSystemUsed',
  139. true
  140. )
  141. const updateMock = fetchMock.post('/user/settings', 200)
  142. render(<AccountInfoSection />)
  143. expect(screen.getByLabelText('Email').readOnly).to.be.true
  144. expect(screen.getByLabelText('First Name').readOnly).to.be.false
  145. expect(screen.getByLabelText('Last Name').readOnly).to.be.false
  146. fireEvent.click(
  147. screen.getByRole('button', {
  148. name: 'Update',
  149. })
  150. )
  151. expect(JSON.parse(updateMock.lastCall()[1].body)).to.deep.equal({
  152. firstName: 'Sherlock',
  153. lastName: 'Holmes',
  154. })
  155. })
  156. it('disables names input', async function () {
  157. window.metaAttributesCache.set('ol-shouldAllowEditingDetails', false)
  158. const updateMock = fetchMock.post('/user/settings', 200)
  159. render(<AccountInfoSection />)
  160. expect(screen.getByLabelText('Email').readOnly).to.be.false
  161. expect(screen.getByLabelText('First Name').readOnly).to.be.true
  162. expect(screen.getByLabelText('Last Name').readOnly).to.be.true
  163. fireEvent.click(
  164. screen.getByRole('button', {
  165. name: 'Update',
  166. })
  167. )
  168. expect(JSON.parse(updateMock.lastCall()[1].body)).to.deep.equal({
  169. email: 'sherlock@holmes.co.uk',
  170. })
  171. })
  172. })