reconfirmation-info.test.tsx 5.3 KB

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