account-info-section.test.tsx 6.0 KB

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