import { expect } from 'chai'
import { fireEvent, screen, render } from '@testing-library/react'
import fetchMock from 'fetch-mock'
import AccountInfoSection from '../../../../../frontend/js/features/settings/components/account-info-section'
import { UserProvider } from '../../../../../frontend/js/shared/context/user-context'
function renderSectionWithUserProvider() {
render(, {
wrapper: ({ children }) => {children},
})
}
describe('', function () {
beforeEach(function () {
window.metaAttributesCache = window.metaAttributesCache || new Map()
window.metaAttributesCache.set('ol-user', {
email: 'sherlock@holmes.co.uk',
first_name: 'Sherlock',
last_name: 'Holmes',
})
window.metaAttributesCache.set('ol-ExposedSettings', {
hasAffiliationsFeature: false,
})
window.metaAttributesCache.set(
'ol-isExternalAuthenticationSystemUsed',
false
)
window.metaAttributesCache.set('ol-shouldAllowEditingDetails', true)
})
afterEach(function () {
window.metaAttributesCache = new Map()
fetchMock.reset()
})
it('submits all inputs', async function () {
const updateMock = fetchMock.post('/user/settings', 200)
renderSectionWithUserProvider()
fireEvent.change(screen.getByLabelText('Email'), {
target: { value: 'john@watson.co.uk' },
})
fireEvent.change(screen.getByLabelText('First Name'), {
target: { value: 'John' },
})
fireEvent.change(screen.getByLabelText('Last Name'), {
target: { value: 'Watson' },
})
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
expect(updateMock.called()).to.be.true
expect(JSON.parse(updateMock.lastCall()![1]!.body as string)).to.deep.equal(
{
email: 'john@watson.co.uk',
first_name: 'John',
last_name: 'Watson',
}
)
})
it('disables button on invalid email', async function () {
const updateMock = fetchMock.post('/user/settings', 200)
renderSectionWithUserProvider()
fireEvent.change(screen.getByLabelText('Email'), {
target: { value: 'john' },
})
const button = screen.getByRole('button', {
name: 'Update',
}) as HTMLButtonElement
expect(button.disabled).to.be.true
fireEvent.click(button)
expect(updateMock.called()).to.be.false
})
it('shows inflight state and success message', async function () {
let finishUpdateCall: (value: any) => void = () => {}
fetchMock.post(
'/user/settings',
new Promise(resolve => (finishUpdateCall = resolve))
)
renderSectionWithUserProvider()
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
await screen.findByText('Saving…')
finishUpdateCall(200)
await screen.findByRole('button', {
name: 'Update',
})
screen.getByText('Thanks, your settings have been updated.')
})
it('shows server error', async function () {
fetchMock.post('/user/settings', 500)
renderSectionWithUserProvider()
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
await screen.findByText('Something went wrong. Please try again.')
})
it('shows invalid error', async function () {
fetchMock.post('/user/settings', 400)
renderSectionWithUserProvider()
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
await screen.findByText(
'Invalid Request. Please correct the data and try again.'
)
})
it('shows conflict error', async function () {
fetchMock.post('/user/settings', {
status: 409,
body: {
message: 'This email is already registered',
},
})
renderSectionWithUserProvider()
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
await screen.findByText('This email is already registered')
})
it('hides email input', async function () {
window.metaAttributesCache.set('ol-ExposedSettings', {
hasAffiliationsFeature: true,
})
const updateMock = fetchMock.post('/user/settings', 200)
renderSectionWithUserProvider()
expect(screen.queryByLabelText('Email')).to.not.exist
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
expect(JSON.parse(updateMock.lastCall()![1]!.body as string)).to.deep.equal(
{
first_name: 'Sherlock',
last_name: 'Holmes',
}
)
})
it('disables email input', async function () {
window.metaAttributesCache.set(
'ol-isExternalAuthenticationSystemUsed',
true
)
const updateMock = fetchMock.post('/user/settings', 200)
renderSectionWithUserProvider()
expect(screen.getByLabelText('Email')).to.have.property('readOnly', true)
expect(screen.getByLabelText('First Name')).to.have.property(
'readOnly',
false
)
expect(screen.getByLabelText('Last Name')).to.have.property(
'readOnly',
false
)
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
expect(JSON.parse(updateMock.lastCall()![1]!.body as string)).to.deep.equal(
{
first_name: 'Sherlock',
last_name: 'Holmes',
}
)
})
it('disables names input', async function () {
window.metaAttributesCache.set('ol-shouldAllowEditingDetails', false)
const updateMock = fetchMock.post('/user/settings', 200)
renderSectionWithUserProvider()
expect(screen.getByLabelText('Email')).to.have.property('readOnly', false)
expect(screen.getByLabelText('First Name')).to.have.property(
'readOnly',
true
)
expect(screen.getByLabelText('Last Name')).to.have.property(
'readOnly',
true
)
fireEvent.click(
screen.getByRole('button', {
name: 'Update',
})
)
expect(JSON.parse(updateMock.lastCall()![1]!.body as string)).to.deep.equal(
{
email: 'sherlock@holmes.co.uk',
}
)
})
})