account-info-section.test.tsx 6.0 KB

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