From 8af40aed474778f0b490cdd6186ddb1c49d2bd8e Mon Sep 17 00:00:00 2001 From: SleepWalker Date: Sun, 29 Dec 2019 15:26:07 +0200 Subject: [PATCH] Cover change email with e2e tests and fix bugs --- .../profile/changeEmail/ChangeEmail.tsx | 30 ++- .../integration/profile/change-email.test.ts | 186 ++++++++++++++++++ .../profile/change-password.test.ts | 4 +- .../profile/change-username.test.ts | 2 +- .../cypress/integration/profile/i18n.test.ts | 2 +- 5 files changed, 212 insertions(+), 12 deletions(-) create mode 100644 tests-e2e/cypress/integration/profile/change-email.test.ts diff --git a/packages/app/components/profile/changeEmail/ChangeEmail.tsx b/packages/app/components/profile/changeEmail/ChangeEmail.tsx index 3c76b75..cbb2bfa 100644 --- a/packages/app/components/profile/changeEmail/ChangeEmail.tsx +++ b/packages/app/components/profile/changeEmail/ChangeEmail.tsx @@ -61,7 +61,7 @@ export default class ChangeEmail extends React.Component { return { activeStep: typeof props.step === 'number' ? props.step : state.activeStep, - code: props.code || '', + code: props.code || state.code, }; } @@ -75,7 +75,10 @@ export default class ChangeEmail extends React.Component { onSubmit={this.onFormSubmit} onInvalid={() => this.forceUpdate()} > -
+
@@ -158,7 +161,7 @@ export default class ChangeEmail extends React.Component { renderStep0({ email, form }) { return ( -
+

@@ -182,7 +185,7 @@ export default class ChangeEmail extends React.Component { renderStep1({ email, form, code, isCodeSpecified, isActiveStep }) { return ( -

+

{ const { newEmail } = this.state; return ( -

+

{newEmail ? ( @@ -296,17 +299,21 @@ export default class ChangeEmail extends React.Component { return this.state.activeStep + 1 === STEPS_TOTAL; } - onSwitchStep = event => { + onSwitchStep = (event: React.MouseEvent) => { event.preventDefault(); this.nextStep(); }; - onCodeInput = event => { + onCodeInput = (event: React.ChangeEvent) => { const { value } = event.target; + if (this.props.code) { + return; + } + this.setState({ - code: this.props.code || value, + code: value, }); }; @@ -320,7 +327,12 @@ export default class ChangeEmail extends React.Component { } promise.then( - () => this.nextStep(), + () => { + this.nextStep(); + this.setState({ + code: '', + }); + }, resp => { if (resp.errors) { form.setErrors(resp.errors); diff --git a/tests-e2e/cypress/integration/profile/change-email.test.ts b/tests-e2e/cypress/integration/profile/change-email.test.ts new file mode 100644 index 0000000..e84a896 --- /dev/null +++ b/tests-e2e/cypress/integration/profile/change-email.test.ts @@ -0,0 +1,186 @@ +import { openSectionByName, confirmWithPassword } from './utils'; + +describe('Profile — Change Email', () => { + it('should change email', () => { + const key = 'key123'; + const key2 = 'key1232'; + + cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => { + cy.server(); + cy.route({ + method: 'POST', + url: `/api/v1/accounts/${account.id}/email-verification`, + }).as('requestEmailChange'); + cy.route({ + method: 'POST', + url: `/api/v1/accounts/${account.id}/new-email-verification`, + response: { success: true }, + }).as('verifyNewEmail'); + cy.route({ + method: 'POST', + url: `/api/v1/accounts/${account.id}/email`, + response: { success: true }, + }).as('saveEmail'); + + cy.visit('/'); + + openSectionByName('E‑mail'); + + cy.location('pathname').should('eq', '/profile/change-email'); + + cy.contains('Send E‑mail').click(); + + cy.wait('@requestEmailChange') + .its('requestBody') + .should( + 'eq', + new URLSearchParams({ + password: '', + }).toString(), + ); + + cy.route({ + method: 'POST', + url: `/api/v1/accounts/${account.id}/email-verification`, + response: { success: true }, + }).as('requestEmailChange'); + + confirmWithPassword(account.password); + + cy.wait('@requestEmailChange') + .its('requestBody') + .should( + 'eq', + new URLSearchParams({ + password: account.password, + }).toString(), + ); + + cy.location('pathname').should('eq', '/profile/change-email/step2'); + + cy.getByTestId('step2') + .find('[name=key]') + .type(key); + cy.getByTestId('step2') + .find('[name=email]') + .type(`${account.email}{enter}`); + + cy.wait('@verifyNewEmail') + .its('requestBody') + .should( + 'eq', + new URLSearchParams({ + email: account.email, + key, + }).toString(), + ); + cy.location('pathname').should('eq', '/profile/change-email/step3'); + + cy.getByTestId('step3') + .find('[name=key]') + .should('have.value', ''); + cy.getByTestId('step3') + .find('[name=key]') + .type(`${key2}{enter}`); + + cy.wait('@saveEmail') + .its('requestBody') + .should( + 'eq', + new URLSearchParams({ + key: key2, + }).toString(), + ); + cy.location('pathname').should('eq', '/'); + }); + }); + + it('should allow to skip steps', () => { + cy.login({ accounts: ['default'] }); + + cy.visit('/profile/change-email'); + + cy.contains('Already received code').click(); + + cy.visit('/profile/change-email/step2'); + + cy.contains('Already received code').click(); + + cy.visit('/profile/change-email/step3'); + }); + + it('should read code from url on step2', () => { + const key = 'key123'; + + cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => { + cy.server(); + cy.route({ + method: 'POST', + url: `/api/v1/accounts/${account.id}/new-email-verification`, + response: { success: true }, + }).as('verifyNewEmail'); + + cy.visit(`/profile/change-email/step2/${key}`); + + cy.getByTestId('step2') + .find('[name=key]') + .should('have.value', key); + cy.getByTestId('step2') + .find('[name=key]') + .should('be.disabled'); + cy.getByTestId('step2') + .find('[name=email]') + .type(`${account.email}{enter}`); + + cy.wait('@verifyNewEmail') + .its('requestBody') + .should( + 'eq', + new URLSearchParams({ + email: account.email, + key, + }).toString(), + ); + cy.location('pathname').should('eq', '/profile/change-email/step3'); + cy.getByTestId('step3') + .find('[name=key]') + .should('have.value', ''); + }); + }); + + it('should read code from url on step3', () => { + const key = 'key123'; + + cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => { + cy.server(); + cy.route({ + method: 'POST', + url: `/api/v1/accounts/${account.id}/email`, + response: { success: true }, + }).as('saveEmail'); + + cy.visit(`/profile/change-email/step3/${key}`); + + cy.getByTestId('step3') + .find('[name=key]') + .should('have.value', key); + cy.getByTestId('step3') + .find('[name=key]') + .should('be.disabled'); + + cy.getByTestId('change-email') + .find('[type=submit]') + .click(); + + cy.wait('@saveEmail') + .its('requestBody') + .should( + 'eq', + new URLSearchParams({ + key, + }).toString(), + ); + cy.location('pathname').should('eq', '/'); + }); + }); +}); diff --git a/tests-e2e/cypress/integration/profile/change-password.test.ts b/tests-e2e/cypress/integration/profile/change-password.test.ts index 53305f1..14c5820 100644 --- a/tests-e2e/cypress/integration/profile/change-password.test.ts +++ b/tests-e2e/cypress/integration/profile/change-password.test.ts @@ -1,6 +1,6 @@ import { openSectionByName, confirmWithPassword } from './utils'; -describe('Change password', () => { +describe('Profile — Change password', () => { it('should change password', () => { cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => { cy.server(); @@ -12,6 +12,8 @@ describe('Change password', () => { openSectionByName('Password'); + cy.location('pathname').should('eq', '/profile/change-password'); + cy.get('[name=newPassword]').type(account.password); cy.get('[name=newRePassword]').type(account.password); cy.get('[name=logoutAll]').should('be.checked'); diff --git a/tests-e2e/cypress/integration/profile/change-username.test.ts b/tests-e2e/cypress/integration/profile/change-username.test.ts index 913728a..e9c0955 100644 --- a/tests-e2e/cypress/integration/profile/change-username.test.ts +++ b/tests-e2e/cypress/integration/profile/change-username.test.ts @@ -1,6 +1,6 @@ import { openSectionByName, confirmWithPassword } from './utils'; -describe('Change username', () => { +describe('Profile — Change Username', () => { it('should change username', () => { cy.server(); diff --git a/tests-e2e/cypress/integration/profile/i18n.test.ts b/tests-e2e/cypress/integration/profile/i18n.test.ts index 7acb431..1385032 100644 --- a/tests-e2e/cypress/integration/profile/i18n.test.ts +++ b/tests-e2e/cypress/integration/profile/i18n.test.ts @@ -1,4 +1,4 @@ -describe('Change locales', () => { +describe('Change locale', () => { it('should change locale from footer', () => { cy.visit('/');