overleaf-cep/services/web/test/frontend/features/settings/components/password-section.test.tsx
Antoine Clausse e0f3bea9ad [web] De-capitalize english translations (#24123)
* Create decapitalize.sh script

* Remove `text-capitalize` classes, rely on translations instead

* `Account Linking` -> `Account linking`

* `Account Settings` -> `Account settings`

* `Add Affiliation` -> `Add affiliation`

* `Add Email` -> `Add email`

* `Add Files` -> `Add files`

* `Add to Dictionary` -> `Add to dictionary`

* `All Projects` -> `All projects`

* `All Templates` -> `All templates`

* `Archive Projects` -> `Archive projects`

* `Archived Projects` -> `Archived projects`

* `Auto Compile` -> `Auto compile`

* `Back to Subscription` -> `Back to subscription`

* `Blank Project` -> `Blank project`

* `Change Password` -> `Change password`

* `Change Project Owner` -> `Change project owner`

* `Clear Sessions` -> `Clear sessions`

* `Company Name` -> `Company name`

* `Compile Error Handling` -> `Compile error handling`

* `Compile Mode` -> `Compile mode`

* `Compromised Password` -> `Compromised password`

* `Confirm Affiliation` -> `Confirm affiliation`

* `Confirm Email` -> `Confirm email`

* `Connected Users` -> `Connected users`

* `Contact Sales` -> `Contact sales`

* `Contact Support` -> `Contact support`

* `Contact Us` -> `Contact us`

* `Copy Project` -> `Copy project`

* `Delete Account` -> `Delete account`

* `Emails and Affiliations` -> `Emails and affiliations`

* `Git Integration` -> `Git integration`

* `Group Settings` -> `Group settings`

* `Link Accounts` -> `Link accounts`

* `Make Primary` -> `Make primary`

* `Mendeley Integration` -> `Mendeley integration`

* `Papers Integration` -> `Papers integration`

* `Project Synchronisation` -> `Project synchronisation`

* `Sessions Cleared` -> `Sessions cleared`

* `Stop Compilation` -> `Stop compilation`

* `Update Account Info` -> `Update account info`

* `the Sales team` -> `the sales team`

* `your Group settings` -> `your group settings`

* `Zotero Integration` -> `Zotero integration`

* Update decapitalize.sh

* Decapitalize some translations

* `Example Project` -> `Example project`

* `New Project` -> `New project`

* `New Tag` -> `New tag`

* `Trashed Projects` -> `Trashed projects`

* `Upload Project` -> `Upload project`

* `Your Projects` -> `Your projects`

* Revert "Create decapitalize.sh script"

This reverts commit 8c79f367096c206c704c7c01e3572a18f3961d5e.

* Revert changes to stories

* Fix tests

* `Contact us of` -> `Contact us if`

* Make `Contact us` bold in tex files

* `sales team` -> `Sales team`

* `Link accounts and Add email` -> `Link accounts and add email`

* `Make Private` -> `Make private`

* `contact support` -> `contact Support`

* Make `Make primary` tests case sensitive

* Use `add_email` translation string

* Revert changes to non-english locales

* Remove redundant `Account settings` translation

* `New project Name` -> `New project name`

GitOrigin-RevId: 675c46f96ddbf3d259a8d723fed62aa4a7ed40b7
2025-05-22 08:07:46 +00:00

213 lines
6 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { expect } from 'chai'
import { fireEvent, screen, render } from '@testing-library/react'
import fetchMock from 'fetch-mock'
import PasswordSection from '../../../../../frontend/js/features/settings/components/password-section'
import getMeta from '@/utils/meta'
describe('<PasswordSection />', function () {
beforeEach(function () {
Object.assign(getMeta('ol-ExposedSettings'), {
isOverleaf: true,
})
window.metaAttributesCache.set(
'ol-isExternalAuthenticationSystemUsed',
false
)
window.metaAttributesCache.set('ol-hasPassword', true)
})
afterEach(function () {
fetchMock.removeRoutes().clearHistory()
})
it('shows password managed externally message', async function () {
Object.assign(getMeta('ol-ExposedSettings'), {
isOverleaf: false,
})
window.metaAttributesCache.set(
'ol-isExternalAuthenticationSystemUsed',
true
)
render(<PasswordSection />)
screen.getByText('Password settings are managed externally')
})
it('shows no existing password message', async function () {
window.metaAttributesCache.set('ol-hasPassword', false)
render(<PasswordSection />)
screen.getByText('Please use the password reset form to set your password')
})
it('submits all inputs', async function () {
const updateMock = fetchMock.post('/user/password/update', 200)
render(<PasswordSection />)
submitValidForm()
expect(updateMock.callHistory.called()).to.be.true
expect(
JSON.parse(updateMock.callHistory.calls().at(-1)?.options.body as string)
).to.deep.equal({
currentPassword: 'foobar',
newPassword1: 'barbaz',
newPassword2: 'barbaz',
})
})
it('disables button on invalid form', async function () {
const updateMock = fetchMock.post('/user/password/update', 200)
render(<PasswordSection />)
fireEvent.click(
screen.getByRole('button', {
name: 'Change',
})
)
expect(updateMock.callHistory.called()).to.be.false
})
it('validates inputs', async function () {
render(<PasswordSection />)
const button = screen.getByRole('button', {
name: 'Change',
}) as HTMLButtonElement
expect(button.disabled).to.be.true
fireEvent.change(screen.getByLabelText('Current password'), {
target: { value: 'foobar' },
})
expect(button.disabled).to.be.true
fireEvent.change(screen.getByLabelText('New password'), {
target: { value: 'barbaz' },
})
expect(button.disabled).to.be.true
fireEvent.change(screen.getByLabelText('Confirm new password'), {
target: { value: 'bar' },
})
screen.getByText('Doesnt match')
expect(button.disabled).to.be.true
fireEvent.change(screen.getByLabelText('Confirm new password'), {
target: { value: 'barbaz' },
})
expect(button.disabled).to.be.false
})
it('sets browser validation attributes', async function () {
window.metaAttributesCache.set('ol-passwordStrengthOptions', {
length: {
min: 3,
},
})
render(<PasswordSection />)
const currentPasswordInput = screen.getByLabelText(
'Current password'
) as HTMLInputElement
const newPassword1Input = screen.getByLabelText(
'New password'
) as HTMLInputElement
const newPassword2Input = screen.getByLabelText(
'Confirm new password'
) as HTMLInputElement
expect(newPassword1Input.minLength).to.equal(3)
// not required before changes
expect(currentPasswordInput.required).to.be.false
expect(newPassword1Input.required).to.be.false
expect(newPassword2Input.required).to.be.false
fireEvent.change(currentPasswordInput, {
target: { value: 'foobar' },
})
fireEvent.change(newPassword1Input, {
target: { value: 'barbaz' },
})
fireEvent.change(newPassword2Input, {
target: { value: 'barbaz' },
})
expect(currentPasswordInput.required).to.be.true
expect(newPassword1Input.required).to.be.true
expect(newPassword2Input.required).to.be.true
})
it('shows inflight state and success message', async function () {
let finishUpdateCall: (value: any) => void = () => {}
fetchMock.post(
'/user/password/update',
new Promise(resolve => (finishUpdateCall = resolve))
)
render(<PasswordSection />)
submitValidForm()
await screen.findByRole('button', { name: 'Saving…' })
finishUpdateCall({
status: 200,
body: {
message: {
type: 'success',
email: 'tim.alby@overleaf.com',
text: 'Password changed',
},
},
})
await screen.findByRole('button', {
name: 'Change',
})
screen.getByText('Password changed')
})
it('shows server error', async function () {
fetchMock.post('/user/password/update', 500)
render(<PasswordSection />)
submitValidForm()
await screen.findByText('Something went wrong. Please try again.')
})
it('shows server error message', async function () {
fetchMock.post('/user/password/update', {
status: 400,
body: {
message: 'Your old password is wrong',
},
})
render(<PasswordSection />)
submitValidForm()
await screen.findByText('Your old password is wrong')
})
it('shows message when user cannot use password log in', async function () {
window.metaAttributesCache.set('ol-cannot-change-password', true)
render(<PasswordSection />)
await screen.findByRole('heading', { name: 'Change password' })
screen.getByText(
'You cant add or change your password because your group or organization uses',
{ exact: false }
)
screen.getByRole('link', { name: 'single sign-on (SSO)' })
})
})
function submitValidForm() {
fireEvent.change(screen.getByLabelText('Current password'), {
target: { value: 'foobar' },
})
fireEvent.change(screen.getByLabelText('New password'), {
target: { value: 'barbaz' },
})
fireEvent.change(screen.getByLabelText('Confirm new password'), {
target: { value: 'barbaz' },
})
fireEvent.click(
screen.getByRole('button', {
name: 'Change',
})
)
}