reconfirmation-info.test.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import {
  2. fireEvent,
  3. render,
  4. screen,
  5. waitFor,
  6. waitForElementToBeRemoved,
  7. } from '@testing-library/react'
  8. import sinon from 'sinon'
  9. import { expect } from 'chai'
  10. import fetchMock from 'fetch-mock'
  11. import { cloneDeep } from 'lodash'
  12. import ReconfirmationInfo from '../../../../../../frontend/js/features/settings/components/emails/reconfirmation-info'
  13. import { ssoUserData } from '../../fixtures/test-user-email-data'
  14. import { UserEmailData } from '../../../../../../types/user-email'
  15. import { UserEmailsProvider } from '../../../../../../frontend/js/features/settings/context/user-email-context'
  16. import { location } from '@/shared/components/location'
  17. import getMeta from '@/utils/meta'
  18. function renderReconfirmationInfo(data: UserEmailData) {
  19. return render(
  20. <UserEmailsProvider>
  21. <ReconfirmationInfo userEmailData={data} />
  22. </UserEmailsProvider>
  23. )
  24. }
  25. describe('<ReconfirmationInfo/>', function () {
  26. beforeEach(function () {
  27. Object.assign(getMeta('ol-ExposedSettings'), {
  28. samlInitPath: '/saml',
  29. })
  30. fetchMock.get('/user/emails?ensureAffiliation=true', [])
  31. this.locationWrapperSandbox = sinon.createSandbox()
  32. this.locationWrapperStub = this.locationWrapperSandbox.stub(location)
  33. })
  34. afterEach(function () {
  35. fetchMock.removeRoutes().clearHistory()
  36. this.locationWrapperSandbox.restore()
  37. })
  38. describe('reconfirmed via SAML', function () {
  39. beforeEach(function () {
  40. window.metaAttributesCache.set(
  41. 'ol-reconfirmedViaSAML',
  42. 'sso-prof-saml-id'
  43. )
  44. })
  45. it('show reconfirmed confirmation', function () {
  46. renderReconfirmationInfo(ssoUserData)
  47. screen.getByText('SSO University')
  48. screen.getByText(/affiliation is confirmed/)
  49. screen.getByText(/Thank you!/)
  50. })
  51. })
  52. describe('in reconfirm notification period', function () {
  53. let inReconfirmUserData: UserEmailData
  54. beforeEach(function () {
  55. Object.assign(getMeta('ol-ExposedSettings'), {
  56. samlInitPath: '/saml',
  57. })
  58. inReconfirmUserData = cloneDeep(ssoUserData)
  59. if (inReconfirmUserData.affiliation) {
  60. inReconfirmUserData.affiliation.inReconfirmNotificationPeriod = true
  61. }
  62. })
  63. it('renders prompt', function () {
  64. renderReconfirmationInfo(inReconfirmUserData)
  65. screen.getByText(/Are you still at/)
  66. screen.getByText('SSO University')
  67. screen.getByText(
  68. /Please take a moment to confirm your institutional email address/
  69. )
  70. screen.getByRole('link', { name: 'Learn more' })
  71. expect(screen.queryByText(/add a new primary email address/)).to.not.exist
  72. })
  73. it('renders default emails prompt', function () {
  74. inReconfirmUserData.default = true
  75. renderReconfirmationInfo(inReconfirmUserData)
  76. screen.getByText(/add a new primary email address/)
  77. })
  78. describe('SAML reconfirmations', function () {
  79. beforeEach(function () {
  80. Object.assign(getMeta('ol-ExposedSettings'), {
  81. hasSamlFeature: true,
  82. samlInitPath: '/saml/init',
  83. })
  84. })
  85. it('redirects to SAML flow', async function () {
  86. renderReconfirmationInfo(inReconfirmUserData)
  87. const confirmButton = screen.getByRole('button', {
  88. name: 'Confirm affiliation',
  89. }) as HTMLButtonElement
  90. await waitFor(() => {
  91. expect(confirmButton.disabled).to.be.false
  92. })
  93. fireEvent.click(confirmButton)
  94. await waitFor(() => {
  95. expect(confirmButton.disabled).to.be.true
  96. })
  97. sinon.assert.calledOnce(this.locationWrapperStub.assign)
  98. sinon.assert.calledWithMatch(
  99. this.locationWrapperStub.assign,
  100. '/saml/init?university_id=2&reconfirm=/user/settings'
  101. )
  102. })
  103. })
  104. describe('Email reconfirmations', function () {
  105. beforeEach(function () {
  106. Object.assign(getMeta('ol-ExposedSettings'), {
  107. hasSamlFeature: false,
  108. })
  109. fetchMock.post('/user/emails/send-reconfirmation', 200)
  110. })
  111. it('sends and resends confirmation email', async function () {
  112. renderReconfirmationInfo(inReconfirmUserData)
  113. const confirmButton = (await screen.findByRole('button', {
  114. name: 'Confirm affiliation',
  115. })) as HTMLButtonElement
  116. await waitFor(() => {
  117. expect(confirmButton.disabled).to.be.false
  118. })
  119. fireEvent.click(confirmButton)
  120. await waitFor(() => {
  121. expect(confirmButton.disabled).to.be.true
  122. })
  123. expect(fetchMock.callHistory.called()).to.be.true
  124. // the confirmation text should now be displayed
  125. await screen.findByText(/Please check your email inbox to confirm/)
  126. // try the resend button
  127. fetchMock.clearHistory()
  128. const resendButton = await screen.findByRole('button', {
  129. name: 'Resend confirmation email',
  130. })
  131. fireEvent.click(resendButton)
  132. // commented out as it's already gone by this point
  133. // await screen.findByText(/Sending/)
  134. expect(fetchMock.callHistory.called()).to.be.true
  135. await waitForElementToBeRemoved(() => screen.getByText('Sending…'))
  136. await screen.findByRole('button', {
  137. name: 'Resend confirmation email',
  138. })
  139. })
  140. })
  141. })
  142. })