| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- import { render, screen, fireEvent } from '@testing-library/react'
- import { expect } from 'chai'
- import fetchMock from 'fetch-mock'
- import { cloneDeep } from 'lodash'
- import EmailsRow from '../../../../../../frontend/js/features/settings/components/emails/row'
- import {
- professionalUserData,
- unconfirmedUserData,
- } from '../../fixtures/test-user-email-data'
- import { UserEmailData } from '../../../../../../types/user-email'
- import { UserEmailsProvider } from '../../../../../../frontend/js/features/settings/context/user-email-context'
- import { Affiliation } from '../../../../../../types/affiliation'
- import getMeta from '@/utils/meta'
- import { SplitTestProvider } from '@/shared/context/split-test-context'
- function renderEmailsRow(data: UserEmailData) {
- return render(
- <SplitTestProvider>
- <UserEmailsProvider>
- <EmailsRow userEmailData={data} />
- </UserEmailsProvider>
- </SplitTestProvider>
- )
- }
- function getByTextContent(text: string) {
- return screen.getAllByText(
- (content, node) =>
- content === text || node?.children[0]?.textContent === text
- )
- }
- describe('<EmailsRow/>', function () {
- beforeEach(function () {
- Object.assign(getMeta('ol-ExposedSettings'), {
- samlInitPath: '/saml',
- hasSamlBeta: true,
- })
- window.metaAttributesCache.set('ol-splitTestVariants', {})
- fetchMock.get('/user/emails?ensureAffiliation=true', [])
- })
- afterEach(function () {
- fetchMock.removeRoutes().clearHistory()
- })
- describe('with unaffiliated email data', function () {
- it('renders email info', function () {
- renderEmailsRow(unconfirmedUserData)
- screen.getByText('baz@overleaf.com')
- })
- it('renders actions', function () {
- renderEmailsRow(unconfirmedUserData)
- screen.getByRole('button', { name: 'Make primary' })
- })
- })
- describe('with affiliated email data', function () {
- it('renders email info', function () {
- renderEmailsRow(professionalUserData)
- screen.getByText('foo@overleaf.com')
- screen.getByText('Primary')
- })
- it('renders actions', function () {
- renderEmailsRow(professionalUserData)
- screen.getByRole('button', { name: 'Remove' })
- })
- it('renders institution info', function () {
- renderEmailsRow(professionalUserData)
- screen.getByText('Overleaf')
- screen.getByText('Reader, Art History')
- })
- })
- describe('with email data affiliated to an institution with SSO available', function () {
- let affiliatedEmail: UserEmailData & { affiliation: Affiliation }
- beforeEach(function () {
- window.metaAttributesCache.get('ol-ExposedSettings').hasSamlFeature = true
- // make sure the institution has SSO available
- affiliatedEmail = cloneDeep(professionalUserData)
- affiliatedEmail.affiliation.institution.confirmed = true
- affiliatedEmail.affiliation.institution.isUniversity = true
- affiliatedEmail.affiliation.institution.ssoEnabled = true
- })
- describe('when the email is not yet linked to the institution', function () {
- beforeEach(async function () {
- fetchMock.removeRoutes().clearHistory()
- fetchMock.get(/\/user\/emails/, [affiliatedEmail, unconfirmedUserData])
- await fetchMock.callHistory.flush(true)
- })
- it('prompts the user to link to their institutional account', function () {
- renderEmailsRow(affiliatedEmail)
- getByTextContent(
- 'You can now link your Overleaf account to your Overleaf institutional account.'
- )
- screen.getByRole('button', { name: 'Link accounts' })
- })
- })
- describe('when the email is already linked to the institution', function () {
- beforeEach(async function () {
- affiliatedEmail.samlProviderId = '1'
- fetchMock.removeRoutes().clearHistory()
- fetchMock.get(/\/user\/emails/, [affiliatedEmail, unconfirmedUserData])
- await fetchMock.callHistory.flush(true)
- })
- it('prompts the user to login using their institutional account', function () {
- renderEmailsRow(affiliatedEmail)
- getByTextContent(
- 'You can log in to Overleaf through your Overleaf institutional login.'
- )
- expect(screen.queryByRole('button', { name: 'Link accounts' })).to.be
- .null
- })
- it('shows unlink button and opens unlink modal', function () {
- renderEmailsRow(affiliatedEmail)
- fireEvent.click(screen.getByRole('button', { name: 'Unlink SSO' }))
- screen.getByRole('dialog')
- screen.getByText('Unlink institutional login')
- })
- })
- describe('and domain capture is also on for group and Commons SSO also enabled', function () {
- // scenario of a Commons account migrating to a group account
- let affiliatedEmailWithDomainCaptureAndCommons: UserEmailData & {
- affiliation: Affiliation
- }
- beforeEach(async function () {
- fetchMock.removeRoutes().clearHistory()
- affiliatedEmailWithDomainCaptureAndCommons = cloneDeep(affiliatedEmail)
- affiliatedEmailWithDomainCaptureAndCommons.affiliation.group = {
- _id: 'grou123',
- domainCaptureEnabled: true,
- managedUsersEnabled: true,
- }
- await fetchMock.callHistory.flush(true)
- })
- it('does not prompt the user to link to their institutional account', function () {
- renderEmailsRow(affiliatedEmailWithDomainCaptureAndCommons)
- expect(() =>
- getByTextContent(
- 'You can now link your Overleaf account to your Overleaf institutional account.'
- )
- ).to.throw('Unable to find an element with the text')
- expect(screen.queryByRole('button', { name: 'Link accounts' })).to.be
- .null
- })
- it('still shows users can log in via Commons SSO if already linked', function () {
- affiliatedEmailWithDomainCaptureAndCommons.samlProviderId = '1'
- renderEmailsRow(affiliatedEmailWithDomainCaptureAndCommons)
- getByTextContent(
- 'You can log in to Overleaf through your Overleaf institutional login.'
- )
- expect(screen.queryByRole('button', { name: 'Link accounts' })).to.be
- .null
- })
- it('uses `domainCapturedByGroup` when the feature flag is enabled', function () {
- affiliatedEmailWithDomainCaptureAndCommons.affiliation.group = {
- _id: 'grou123',
- domainCaptureEnabled: true,
- managedUsersEnabled: true,
- }
- affiliatedEmailWithDomainCaptureAndCommons.affiliation.domainCapturedByGroup = true
- window.metaAttributesCache.set('ol-splitTestVariants', {
- 'domain-captured-by-group': 'enabled',
- })
- renderEmailsRow(affiliatedEmailWithDomainCaptureAndCommons)
- expect(screen.queryByRole('button', { name: 'Link accounts' })).to.be
- .null
- })
- it('ignores group domain capture when the feature flag is enabled and the domain is not captured', function () {
- affiliatedEmailWithDomainCaptureAndCommons.affiliation.domainCapturedByGroup = false
- window.metaAttributesCache.set('ol-splitTestVariants', {
- 'domain-captured-by-group': 'enabled',
- })
- renderEmailsRow(affiliatedEmailWithDomainCaptureAndCommons)
- getByTextContent(
- 'You can now link your Overleaf account to your Overleaf institutional account.'
- )
- screen.getByRole('button', { name: 'Link accounts' })
- })
- })
- })
- })
|