Merge pull request #23940 from overleaf/td-react-18
Upgrade to React 18 GitOrigin-RevId: 9b81936e6eea2bccd97fe5c2c5841f0b946371b8
This commit is contained in:
+10
-3
@@ -120,9 +120,16 @@ describe('<AddEmailInput/>', function () {
|
||||
describe('when there is a domain match', function () {
|
||||
beforeEach(async function () {
|
||||
fetchMock.get('express:/institutions/domains', testInstitutionData)
|
||||
fireEvent.change(screen.getByTestId('affiliations-email'), {
|
||||
target: { value: 'user@d' },
|
||||
})
|
||||
const input = await screen.findByTestId('affiliations-email')
|
||||
fireEvent.change(input, { target: { value: 'user@d' } })
|
||||
|
||||
// Wait for the request to complete and the domain cache to pouplate
|
||||
await waitFor(
|
||||
() =>
|
||||
expect(
|
||||
fetchMock.callHistory.called('express:/institutions/domains')
|
||||
).to.be.true
|
||||
)
|
||||
// Wait for component to process the change and update the shadow input
|
||||
await waitFor(() => {
|
||||
const shadowInput = screen.getByTestId(
|
||||
|
||||
+3
-1
@@ -61,7 +61,9 @@ function resetFetchMock() {
|
||||
}
|
||||
|
||||
async function confirmCodeForEmail(email: string) {
|
||||
screen.getByText(`Enter the 6-digit confirmation code sent to ${email}.`)
|
||||
await screen.findByText(
|
||||
`Enter the 6-digit confirmation code sent to ${email}.`
|
||||
)
|
||||
const inputCode = screen.getByLabelText(/6-digit confirmation code/i)
|
||||
fireEvent.change(inputCode, { target: { value: '123456' } })
|
||||
const submitCodeBtn = screen.getByRole<HTMLButtonElement>('button', {
|
||||
|
||||
+6
-4
@@ -139,16 +139,18 @@ describe('user role and institution', function () {
|
||||
departments: [fakeDepartment],
|
||||
})
|
||||
|
||||
fireEvent.click(
|
||||
screen.getByRole('button', { name: /add role and department/i })
|
||||
)
|
||||
const addRoleButton = await screen.findByRole('button', {
|
||||
name: /add role and department/i,
|
||||
})
|
||||
|
||||
fireEvent.click(addRoleButton)
|
||||
|
||||
await fetchMock.callHistory.flush(true)
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
|
||||
fireEvent.click(screen.getByRole('combobox', { name: /department/i }))
|
||||
|
||||
screen.getByText(fakeDepartment)
|
||||
await screen.findByText(fakeDepartment)
|
||||
})
|
||||
|
||||
it('adds new role and department', async function () {
|
||||
|
||||
+6
-13
@@ -13,7 +13,7 @@ import ReconfirmationInfo from '../../../../../../frontend/js/features/settings/
|
||||
import { ssoUserData } from '../../fixtures/test-user-email-data'
|
||||
import { UserEmailData } from '../../../../../../types/user-email'
|
||||
import { UserEmailsProvider } from '../../../../../../frontend/js/features/settings/context/user-email-context'
|
||||
import * as useLocationModule from '../../../../../../frontend/js/shared/hooks/use-location'
|
||||
import { location } from '@/shared/components/location'
|
||||
import getMeta from '@/utils/meta'
|
||||
|
||||
function renderReconfirmationInfo(data: UserEmailData) {
|
||||
@@ -25,25 +25,18 @@ function renderReconfirmationInfo(data: UserEmailData) {
|
||||
}
|
||||
|
||||
describe('<ReconfirmationInfo/>', function () {
|
||||
let assignStub: sinon.SinonStub
|
||||
|
||||
beforeEach(function () {
|
||||
Object.assign(getMeta('ol-ExposedSettings'), {
|
||||
samlInitPath: '/saml',
|
||||
})
|
||||
fetchMock.get('/user/emails?ensureAffiliation=true', [])
|
||||
assignStub = sinon.stub()
|
||||
this.locationStub = sinon.stub(useLocationModule, 'useLocation').returns({
|
||||
assign: assignStub,
|
||||
replace: sinon.stub(),
|
||||
reload: sinon.stub(),
|
||||
setHash: sinon.stub(),
|
||||
})
|
||||
this.locationWrapperSandbox = sinon.createSandbox()
|
||||
this.locationWrapperStub = this.locationWrapperSandbox.stub(location)
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
this.locationStub.restore()
|
||||
this.locationWrapperSandbox.restore()
|
||||
})
|
||||
|
||||
describe('reconfirmed via SAML', function () {
|
||||
@@ -115,9 +108,9 @@ describe('<ReconfirmationInfo/>', function () {
|
||||
await waitFor(() => {
|
||||
expect(confirmButton.disabled).to.be.true
|
||||
})
|
||||
sinon.assert.calledOnce(assignStub)
|
||||
sinon.assert.calledOnce(this.locationWrapperStub.assign)
|
||||
sinon.assert.calledWithMatch(
|
||||
assignStub,
|
||||
this.locationWrapperStub.assign,
|
||||
'/saml/init?university_id=2&reconfirm=/user/settings'
|
||||
)
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ import { fireEvent, screen, render, waitFor } from '@testing-library/react'
|
||||
import fetchMock, { type FetchMock } from 'fetch-mock'
|
||||
|
||||
import LeaveModalForm from '../../../../../../frontend/js/features/settings/components/leave/modal-form'
|
||||
import * as useLocationModule from '../../../../../../frontend/js/shared/hooks/use-location'
|
||||
import { location } from '@/shared/components/location'
|
||||
import getMeta from '@/utils/meta'
|
||||
|
||||
describe('<LeaveModalForm />', function () {
|
||||
@@ -51,25 +51,19 @@ describe('<LeaveModalForm />', function () {
|
||||
let setInFlight: sinon.SinonStub
|
||||
let setIsFormValid: sinon.SinonStub
|
||||
let deleteMock: FetchMock
|
||||
let assignStub: sinon.SinonStub
|
||||
|
||||
beforeEach(function () {
|
||||
setInFlight = sinon.stub()
|
||||
setIsFormValid = sinon.stub()
|
||||
deleteMock = fetchMock.post('/user/delete', 200)
|
||||
assignStub = sinon.stub()
|
||||
this.locationStub = sinon.stub(useLocationModule, 'useLocation').returns({
|
||||
assign: assignStub,
|
||||
replace: sinon.stub(),
|
||||
reload: sinon.stub(),
|
||||
setHash: sinon.stub(),
|
||||
})
|
||||
this.locationWrapperSandbox = sinon.createSandbox()
|
||||
this.locationWrapperStub = this.locationWrapperSandbox.stub(location)
|
||||
Object.assign(getMeta('ol-ExposedSettings'), { isOverleaf: true })
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
this.locationStub.restore()
|
||||
this.locationWrapperSandbox.restore()
|
||||
})
|
||||
|
||||
it('with valid form', async function () {
|
||||
@@ -86,6 +80,7 @@ describe('<LeaveModalForm />', function () {
|
||||
sinon.assert.calledOnce(setInFlight)
|
||||
sinon.assert.calledWithMatch(setInFlight, true)
|
||||
expect(deleteMock.callHistory.called()).to.be.true
|
||||
const assignStub = this.locationWrapperStub.assign
|
||||
await waitFor(() => {
|
||||
sinon.assert.calledTwice(setInFlight)
|
||||
sinon.assert.calledWithMatch(setInFlight, false)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { expect } from 'chai'
|
||||
import { renderHook } from '@testing-library/react-hooks'
|
||||
import { renderHook, waitFor } from '@testing-library/react'
|
||||
import {
|
||||
SSOProvider,
|
||||
useSSOContext,
|
||||
@@ -60,10 +60,11 @@ describe('SSOContext', function () {
|
||||
})
|
||||
|
||||
it('should unlink an existing subscription', async function () {
|
||||
const { result, waitForNextUpdate } = renderSSOContext()
|
||||
const { result } = renderSSOContext()
|
||||
result.current.unlink('google')
|
||||
await waitForNextUpdate()
|
||||
expect(result.current.subscriptions.google.linked).to.be.false
|
||||
await waitFor(
|
||||
() => expect(result.current.subscriptions.google.linked).to.be.false
|
||||
)
|
||||
})
|
||||
|
||||
it('when the provider is not linked, should do nothing', function () {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { expect } from 'chai'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { renderHook } from '@testing-library/react-hooks'
|
||||
import { waitFor } from '@testing-library/react'
|
||||
|
||||
import { renderHook, waitFor } from '@testing-library/react'
|
||||
import {
|
||||
EmailContextType,
|
||||
UserEmailsProvider,
|
||||
@@ -53,12 +51,14 @@ describe('UserEmailContext', function () {
|
||||
const { result } = renderUserEmailsContext()
|
||||
await fetchMock.callHistory.flush(true)
|
||||
expect(fetchMock.callHistory.calls()).to.have.lengthOf(1)
|
||||
expect(result.current.state.data.byId).to.deep.equal({
|
||||
'bar@overleaf.com': { ...untrustedUserData, ...confirmedUserData },
|
||||
'baz@overleaf.com': unconfirmedUserData,
|
||||
'foo@overleaf.com': professionalUserData,
|
||||
'qux@overleaf.com': unconfirmedCommonsUserData,
|
||||
})
|
||||
await waitFor(() =>
|
||||
expect(result.current.state.data.byId).to.deep.equal({
|
||||
'bar@overleaf.com': { ...untrustedUserData, ...confirmedUserData },
|
||||
'baz@overleaf.com': unconfirmedUserData,
|
||||
'foo@overleaf.com': professionalUserData,
|
||||
'qux@overleaf.com': unconfirmedCommonsUserData,
|
||||
})
|
||||
)
|
||||
expect(result.current.state.data.linkedInstitutionIds).to.have.lengthOf(0)
|
||||
|
||||
expect(result.current.isInitializing).to.equal(false)
|
||||
@@ -70,10 +70,8 @@ describe('UserEmailContext', function () {
|
||||
const { result } = renderUserEmailsContext()
|
||||
await fetchMock.callHistory.flush()
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.isInitializing).to.equal(false)
|
||||
expect(result.current.isInitializingError).to.equal(true)
|
||||
})
|
||||
await waitFor(() => expect(result.current.isInitializing).to.equal(false))
|
||||
expect(result.current.isInitializingError).to.equal(true)
|
||||
})
|
||||
|
||||
describe('state.isLoading', function () {
|
||||
@@ -82,12 +80,16 @@ describe('UserEmailContext', function () {
|
||||
expect(result.current.state.isLoading).to.equal(true)
|
||||
})
|
||||
|
||||
it('should be updated with `setLoading`', function () {
|
||||
it('should be updated with `setLoading`', async function () {
|
||||
const { result } = renderUserEmailsContext()
|
||||
result.current.setLoading(true)
|
||||
expect(result.current.state.isLoading).to.equal(true)
|
||||
await waitFor(() =>
|
||||
expect(result.current.state.isLoading).to.equal(true)
|
||||
)
|
||||
result.current.setLoading(false)
|
||||
expect(result.current.state.isLoading).to.equal(false)
|
||||
await waitFor(() =>
|
||||
expect(result.current.state.isLoading).to.equal(false)
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -106,15 +108,19 @@ describe('UserEmailContext', function () {
|
||||
fetchMock.removeRoutes().clearHistory()
|
||||
})
|
||||
|
||||
it('should set `isLoading === true`', function () {
|
||||
fetchMock.get(/\/user\/emails/, [
|
||||
{
|
||||
email: 'new@email.com',
|
||||
default: true,
|
||||
},
|
||||
])
|
||||
it('should set `isLoading === true`', async function () {
|
||||
fetchMock.get(
|
||||
/\/user\/emails/,
|
||||
[
|
||||
{
|
||||
email: 'new@email.com',
|
||||
default: true,
|
||||
},
|
||||
],
|
||||
{ delay: 100 }
|
||||
)
|
||||
result.current.getEmails()
|
||||
expect(result.current.state.isLoading).to.be.true
|
||||
await waitFor(() => expect(result.current.state.isLoading).to.be.true)
|
||||
})
|
||||
|
||||
it('requests a new set of emails', async function () {
|
||||
@@ -125,9 +131,11 @@ describe('UserEmailContext', function () {
|
||||
fetchMock.get(/\/user\/emails/, [emailData])
|
||||
result.current.getEmails()
|
||||
await fetchMock.callHistory.flush(true)
|
||||
expect(result.current.state.data.byId).to.deep.equal({
|
||||
'new@email.com': emailData,
|
||||
})
|
||||
await waitFor(() =>
|
||||
expect(result.current.state.data.byId).to.deep.equal({
|
||||
'new@email.com': emailData,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('should populate `linkedInstitutionIds`', async function () {
|
||||
@@ -138,42 +146,55 @@ describe('UserEmailContext', function () {
|
||||
])
|
||||
const { result } = renderUserEmailsContext()
|
||||
await fetchMock.callHistory.flush(true)
|
||||
expect(result.current.state.data.linkedInstitutionIds).to.deep.equal([
|
||||
'saml_provider_1',
|
||||
'saml_provider_2',
|
||||
])
|
||||
await waitFor(() =>
|
||||
expect(result.current.state.data.linkedInstitutionIds).to.deep.equal([
|
||||
'saml_provider_1',
|
||||
'saml_provider_2',
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('makePrimary()', function () {
|
||||
it('sets an email as `default`', function () {
|
||||
it('sets an email as `default`', async function () {
|
||||
expect(result.current.state.data.byId['bar@overleaf.com'].default).to.be
|
||||
.false
|
||||
result.current.makePrimary('bar@overleaf.com')
|
||||
expect(result.current.state.data.byId['bar@overleaf.com'].default).to.be
|
||||
.true
|
||||
await waitFor(
|
||||
() =>
|
||||
expect(result.current.state.data.byId['bar@overleaf.com'].default)
|
||||
.to.be.true
|
||||
)
|
||||
})
|
||||
|
||||
it('sets `default=false` for the current primary email ', function () {
|
||||
it('sets `default=false` for the current primary email ', async function () {
|
||||
expect(result.current.state.data.byId['foo@overleaf.com'].default).to.be
|
||||
.true
|
||||
result.current.makePrimary('bar@overleaf.com')
|
||||
expect(result.current.state.data.byId['foo@overleaf.com'].default).to.be
|
||||
.false
|
||||
await waitFor(
|
||||
() =>
|
||||
expect(result.current.state.data.byId['foo@overleaf.com'].default)
|
||||
.to.be.false
|
||||
)
|
||||
})
|
||||
|
||||
it('produces no effect when passing a non-existing email', function () {
|
||||
it('produces no effect when passing a non-existing email', async function () {
|
||||
const emails = cloneDeep(result.current.state.data.byId)
|
||||
result.current.makePrimary('non-existing@email.com')
|
||||
expect(result.current.state.data.byId).to.deep.equal(emails)
|
||||
await waitFor(() =>
|
||||
expect(result.current.state.data.byId).to.deep.equal(emails)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('deleteEmail()', function () {
|
||||
it('removes data from the deleted email', function () {
|
||||
it('removes data from the deleted email', async function () {
|
||||
result.current.deleteEmail('bar@overleaf.com')
|
||||
expect(result.current.state.data.byId['bar@overleaf.com']).to.be
|
||||
.undefined
|
||||
await waitFor(
|
||||
() =>
|
||||
expect(result.current.state.data.byId['bar@overleaf.com']).to.be
|
||||
.undefined
|
||||
)
|
||||
})
|
||||
|
||||
it('produces no effect when passing a non-existing email', function () {
|
||||
@@ -184,14 +205,20 @@ describe('UserEmailContext', function () {
|
||||
})
|
||||
|
||||
describe('setEmailAffiliationBeingEdited()', function () {
|
||||
it('sets an email as currently being edited', function () {
|
||||
it('sets an email as currently being edited', async function () {
|
||||
result.current.setEmailAffiliationBeingEdited('bar@overleaf.com')
|
||||
expect(result.current.state.data.emailAffiliationBeingEdited).to.equal(
|
||||
'bar@overleaf.com'
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
result.current.state.data.emailAffiliationBeingEdited
|
||||
).to.equal('bar@overleaf.com')
|
||||
)
|
||||
|
||||
result.current.setEmailAffiliationBeingEdited(null)
|
||||
expect(result.current.state.data.emailAffiliationBeingEdited).to.be.null
|
||||
await waitFor(
|
||||
() =>
|
||||
expect(result.current.state.data.emailAffiliationBeingEdited).to.be
|
||||
.null
|
||||
)
|
||||
})
|
||||
|
||||
it('produces no effect when passing a non-existing email', function () {
|
||||
@@ -202,15 +229,17 @@ describe('UserEmailContext', function () {
|
||||
})
|
||||
|
||||
describe('updateAffiliation()', function () {
|
||||
it('updates affiliation data for an email', function () {
|
||||
it('updates affiliation data for an email', async function () {
|
||||
result.current.updateAffiliation(
|
||||
'foo@overleaf.com',
|
||||
'new role',
|
||||
'new department'
|
||||
)
|
||||
expect(
|
||||
result.current.state.data.byId['foo@overleaf.com'].affiliation!.role
|
||||
).to.equal('new role')
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
result.current.state.data.byId['foo@overleaf.com'].affiliation!.role
|
||||
).to.equal('new role')
|
||||
)
|
||||
expect(
|
||||
result.current.state.data.byId['foo@overleaf.com'].affiliation!
|
||||
.department
|
||||
@@ -317,9 +346,11 @@ describe('UserEmailContext', function () {
|
||||
result.current.deleteEmail(affiliatedEmail1.email)
|
||||
result.current.resetLeaversSurveyExpiration(affiliatedEmail1)
|
||||
|
||||
expect(
|
||||
localStorage.getItem('showInstitutionalLeaversSurveyUntil')
|
||||
).to.be.greaterThan(Date.now())
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
localStorage.getItem('showInstitutionalLeaversSurveyUntil')
|
||||
).to.be.greaterThan(Date.now())
|
||||
)
|
||||
})
|
||||
|
||||
it("when the leaver has no institution license, it shouldn't reset the survey expiration date", async function () {
|
||||
|
||||
Reference in New Issue
Block a user