mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Merge pull request #33202 from overleaf/jel-domain-captured-by-group-settings-page
[Domain capture] Check `domainCapturedByGroup` for existing emails on user settings GitOrigin-RevId: 5ac86b89969b186cce0cac410c2957e5aa1b9703
This commit is contained in:
@@ -117,7 +117,11 @@ async function settingsPage(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await SplitTestHandler.promises.getAssignment(req, res, 'email-notifications')
|
await SplitTestHandler.promises.getAssignment(req, res, 'email-notifications')
|
||||||
|
await SplitTestHandler.promises.getAssignment(
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
'domain-captured-by-group'
|
||||||
|
)
|
||||||
res.render('user/settings', {
|
res.render('user/settings', {
|
||||||
title: 'account_settings',
|
title: 'account_settings',
|
||||||
user: {
|
user: {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import Actions from './actions'
|
|||||||
import { institutionAlreadyLinked } from '../../utils/selectors'
|
import { institutionAlreadyLinked } from '../../utils/selectors'
|
||||||
import { useUserEmailsContext } from '../../context/user-email-context'
|
import { useUserEmailsContext } from '../../context/user-email-context'
|
||||||
import getMeta from '../../../../utils/meta'
|
import getMeta from '../../../../utils/meta'
|
||||||
|
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
||||||
import { ssoAvailableForInstitution } from '../../utils/sso'
|
import { ssoAvailableForInstitution } from '../../utils/sso'
|
||||||
import ReconfirmationInfo from './reconfirmation-info'
|
import ReconfirmationInfo from './reconfirmation-info'
|
||||||
import { useLocation } from '../../../../shared/hooks/use-location'
|
import { useLocation } from '../../../../shared/hooks/use-location'
|
||||||
@@ -71,6 +72,10 @@ function SSOAffiliationInfo({ userEmailData }: SSOAffiliationInfoProps) {
|
|||||||
const [linkAccountsButtonDisabled, setLinkAccountsButtonDisabled] =
|
const [linkAccountsButtonDisabled, setLinkAccountsButtonDisabled] =
|
||||||
useState(false)
|
useState(false)
|
||||||
|
|
||||||
|
const domainCapturedByGroupRolloutFlagEnabled = useFeatureFlag(
|
||||||
|
'domain-captured-by-group'
|
||||||
|
)
|
||||||
|
|
||||||
function handleLinkAccountsButtonClick() {
|
function handleLinkAccountsButtonClick() {
|
||||||
setLinkAccountsButtonDisabled(true)
|
setLinkAccountsButtonDisabled(true)
|
||||||
location.assign(
|
location.assign(
|
||||||
@@ -140,7 +145,10 @@ function SSOAffiliationInfo({ userEmailData }: SSOAffiliationInfoProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const domainAlsoForGroupWithDomainCapture =
|
const domainAlsoForGroupWithDomainCapture =
|
||||||
|
domainCapturedByGroupRolloutFlagEnabled
|
||||||
|
? userEmailData?.affiliation?.domainCapturedByGroup &&
|
||||||
userEmailData?.affiliation?.group?.domainCaptureEnabled
|
userEmailData?.affiliation?.group?.domainCaptureEnabled
|
||||||
|
: userEmailData?.affiliation?.group?.domainCaptureEnabled
|
||||||
|
|
||||||
if (domainAlsoForGroupWithDomainCapture) {
|
if (domainAlsoForGroupWithDomainCapture) {
|
||||||
// user is not linked via Commons and should link via groups
|
// user is not linked via Commons and should link via groups
|
||||||
|
|||||||
@@ -4,10 +4,15 @@ import '@/utils/webpack-public-path'
|
|||||||
import '@/infrastructure/error-reporter'
|
import '@/infrastructure/error-reporter'
|
||||||
import '@/i18n'
|
import '@/i18n'
|
||||||
import SettingsPageRoot from '@/features/settings/components/root'
|
import SettingsPageRoot from '@/features/settings/components/root'
|
||||||
|
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||||
|
|
||||||
// For react-google-recaptcha
|
// For react-google-recaptcha
|
||||||
window.recaptchaOptions = {
|
window.recaptchaOptions = {
|
||||||
enterprise: true,
|
enterprise: true,
|
||||||
useRecaptchaNet: true,
|
useRecaptchaNet: true,
|
||||||
}
|
}
|
||||||
renderInReactLayout('settings-page-root', () => <SettingsPageRoot />)
|
renderInReactLayout('settings-page-root', () => (
|
||||||
|
<SplitTestProvider>
|
||||||
|
<SettingsPageRoot />
|
||||||
|
</SplitTestProvider>
|
||||||
|
))
|
||||||
|
|||||||
@@ -11,12 +11,15 @@ import { UserEmailData } from '../../../../../../types/user-email'
|
|||||||
import { UserEmailsProvider } from '../../../../../../frontend/js/features/settings/context/user-email-context'
|
import { UserEmailsProvider } from '../../../../../../frontend/js/features/settings/context/user-email-context'
|
||||||
import { Affiliation } from '../../../../../../types/affiliation'
|
import { Affiliation } from '../../../../../../types/affiliation'
|
||||||
import getMeta from '@/utils/meta'
|
import getMeta from '@/utils/meta'
|
||||||
|
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||||
|
|
||||||
function renderEmailsRow(data: UserEmailData) {
|
function renderEmailsRow(data: UserEmailData) {
|
||||||
return render(
|
return render(
|
||||||
|
<SplitTestProvider>
|
||||||
<UserEmailsProvider>
|
<UserEmailsProvider>
|
||||||
<EmailsRow userEmailData={data} />
|
<EmailsRow userEmailData={data} />
|
||||||
</UserEmailsProvider>
|
</UserEmailsProvider>
|
||||||
|
</SplitTestProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +36,7 @@ describe('<EmailsRow/>', function () {
|
|||||||
samlInitPath: '/saml',
|
samlInitPath: '/saml',
|
||||||
hasSamlBeta: true,
|
hasSamlBeta: true,
|
||||||
})
|
})
|
||||||
|
window.metaAttributesCache.set('ol-splitTestVariants', {})
|
||||||
fetchMock.get('/user/emails?ensureAffiliation=true', [])
|
fetchMock.get('/user/emails?ensureAffiliation=true', [])
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -165,6 +169,37 @@ describe('<EmailsRow/>', function () {
|
|||||||
expect(screen.queryByRole('button', { name: 'Link accounts' })).to.be
|
expect(screen.queryByRole('button', { name: 'Link accounts' })).to.be
|
||||||
.null
|
.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' })
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import EmailsSection from '../../../../../../frontend/js/features/settings/compo
|
|||||||
import { Institution } from '../../../../../../types/institution'
|
import { Institution } from '../../../../../../types/institution'
|
||||||
import { Affiliation } from '../../../../../../types/affiliation'
|
import { Affiliation } from '../../../../../../types/affiliation'
|
||||||
import getMeta from '@/utils/meta'
|
import getMeta from '@/utils/meta'
|
||||||
|
import { SplitTestProvider } from '@/shared/context/split-test-context'
|
||||||
|
|
||||||
const userEmailData: UserEmailData = {
|
const userEmailData: UserEmailData = {
|
||||||
confirmedAt: '2022-03-10T10:59:44.139Z',
|
confirmedAt: '2022-03-10T10:59:44.139Z',
|
||||||
@@ -32,6 +33,14 @@ const userEmailData2: UserEmailData & { affiliation: Affiliation } = {
|
|||||||
default: false,
|
default: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderEmailsSection() {
|
||||||
|
return render(<EmailsSection />, {
|
||||||
|
wrapper: ({ children }) => (
|
||||||
|
<SplitTestProvider>{children}</SplitTestProvider>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
describe('email actions - make primary', function () {
|
describe('email actions - make primary', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
Object.assign(getMeta('ol-ExposedSettings'), {
|
Object.assign(getMeta('ol-ExposedSettings'), {
|
||||||
@@ -49,7 +58,7 @@ describe('email actions - make primary', function () {
|
|||||||
const userEmailDataCopy = { ...userEmailData2 }
|
const userEmailDataCopy = { ...userEmailData2 }
|
||||||
const { confirmedAt: _, ...userEmailData } = userEmailDataCopy
|
const { confirmedAt: _, ...userEmailData } = userEmailDataCopy
|
||||||
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const button = (await screen.findByRole('button', {
|
const button = (await screen.findByRole('button', {
|
||||||
name: /make primary/i,
|
name: /make primary/i,
|
||||||
@@ -66,7 +75,7 @@ describe('email actions - make primary', function () {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
|
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const button = (await screen.findByRole('button', {
|
const button = (await screen.findByRole('button', {
|
||||||
name: /make primary/i,
|
name: /make primary/i,
|
||||||
@@ -86,7 +95,7 @@ describe('email actions - make primary', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
|
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const button = (await screen.findByRole('button', {
|
const button = (await screen.findByRole('button', {
|
||||||
name: /make primary/i,
|
name: /make primary/i,
|
||||||
@@ -103,7 +112,7 @@ describe('email actions - make primary', function () {
|
|||||||
const userEmailDataCopy = { ...userEmailData2 }
|
const userEmailDataCopy = { ...userEmailData2 }
|
||||||
|
|
||||||
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
|
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const button = (await screen.findByRole('button', {
|
const button = (await screen.findByRole('button', {
|
||||||
name: /make primary/i,
|
name: /make primary/i,
|
||||||
@@ -144,7 +153,7 @@ describe('email actions - make primary', function () {
|
|||||||
userEmailDataCopy1,
|
userEmailDataCopy1,
|
||||||
userEmailDataCopy2,
|
userEmailDataCopy2,
|
||||||
])
|
])
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const buttons = (await screen.findAllByRole('button', {
|
const buttons = (await screen.findAllByRole('button', {
|
||||||
name: /make primary/i,
|
name: /make primary/i,
|
||||||
@@ -177,7 +186,7 @@ describe('email actions - make primary', function () {
|
|||||||
|
|
||||||
it('shows confirmation modal and closes it', async function () {
|
it('shows confirmation modal and closes it', async function () {
|
||||||
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const button = await screen.findByRole('button', {
|
const button = await screen.findByRole('button', {
|
||||||
name: /make primary/i,
|
name: /make primary/i,
|
||||||
@@ -205,7 +214,7 @@ describe('email actions - make primary', function () {
|
|||||||
fetchMock
|
fetchMock
|
||||||
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
||||||
.post('/user/emails/default?delete-unconfirmed-primary', 200)
|
.post('/user/emails/default?delete-unconfirmed-primary', 200)
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
await confirmPrimaryEmail()
|
await confirmPrimaryEmail()
|
||||||
|
|
||||||
@@ -221,7 +230,7 @@ describe('email actions - make primary', function () {
|
|||||||
fetchMock
|
fetchMock
|
||||||
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
||||||
.post('/user/emails/default?delete-unconfirmed-primary', 503)
|
.post('/user/emails/default?delete-unconfirmed-primary', 503)
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
await confirmPrimaryEmail()
|
await confirmPrimaryEmail()
|
||||||
|
|
||||||
@@ -241,13 +250,14 @@ describe('email actions - delete', function () {
|
|||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
fetchMock.removeRoutes().clearHistory()
|
fetchMock.removeRoutes().clearHistory()
|
||||||
|
window.metaAttributesCache.set('ol-splitTestVariants', {})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shows loader when deleting and removes the row', async function () {
|
it('shows loader when deleting and removes the row', async function () {
|
||||||
fetchMock
|
fetchMock
|
||||||
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
||||||
.post('/user/emails/delete', 200)
|
.post('/user/emails/delete', 200)
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const button = await screen.findByRole('button', { name: /remove/i })
|
const button = await screen.findByRole('button', { name: /remove/i })
|
||||||
fireEvent.click(button)
|
fireEvent.click(button)
|
||||||
@@ -261,7 +271,7 @@ describe('email actions - delete', function () {
|
|||||||
fetchMock
|
fetchMock
|
||||||
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
.get('/user/emails?ensureAffiliation=true', [userEmailData])
|
||||||
.post('/user/emails/delete', 503)
|
.post('/user/emails/delete', 503)
|
||||||
render(<EmailsSection />)
|
renderEmailsSection()
|
||||||
|
|
||||||
const button = await screen.findByRole('button', { name: /remove/i })
|
const button = await screen.findByRole('button', { name: /remove/i })
|
||||||
fireEvent.click(button)
|
fireEvent.click(button)
|
||||||
|
|||||||
Reference in New Issue
Block a user