diff --git a/src/_style.scss b/src/_style.scss index 625e09a9..860eebf5 100644 --- a/src/_style.scss +++ b/src/_style.scss @@ -20,7 +20,7 @@ $accent-a-light: #c9f2f5; min-width: 464px !important; } -.register-button-width { +.stateful-button-width { width: 12rem; } diff --git a/src/forgot-password/messages.js b/src/forgot-password/messages.js index 99502195..9dedb74b 100644 --- a/src/forgot-password/messages.js +++ b/src/forgot-password/messages.js @@ -105,8 +105,8 @@ const messages = defineMessages({ }, 'invalid.token.error.message': { id: 'invalid.token.error.message', - defaultMessage: 'This link has expired. Enter your email below to receive a new link.', - description: 'Alert message when reset password link has expired', + defaultMessage: 'This password reset link is invalid. It may have been used already. Enter your email below to receive a new link.', + description: 'Alert message when reset password link has expired or is invalid', }, 'token.validation.rate.limit.error.heading': { id: 'token.validation.rate.limit.error.heading', diff --git a/src/forgot-password/tests/ForgotPasswordPage.test.jsx b/src/forgot-password/tests/ForgotPasswordPage.test.jsx index 1445bf4e..23605491 100644 --- a/src/forgot-password/tests/ForgotPasswordPage.test.jsx +++ b/src/forgot-password/tests/ForgotPasswordPage.test.jsx @@ -1,16 +1,19 @@ import React from 'react'; + +import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { Provider } from 'react-redux'; import { MemoryRouter } from 'react-router-dom'; -import { mount } from 'enzyme'; import configureStore from 'redux-mock-store'; + +import * as analytics from '@edx/frontend-platform/analytics'; +import CookiePolicyBanner from '@edx/frontend-component-cookie-policy-banner'; import { mergeConfig } from '@edx/frontend-platform'; import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n'; -import CookiePolicyBanner from '@edx/frontend-component-cookie-policy-banner'; -import * as analytics from '@edx/frontend-platform/analytics'; import ForgotPasswordPage from '../ForgotPasswordPage'; import { INTERNAL_SERVER_ERROR } from '../../data/constants'; +import { PASSWORD_RESET } from '../../reset-password/data/constants'; jest.mock('@edx/frontend-platform/analytics'); @@ -20,7 +23,7 @@ const IntlForgotPasswordPage = injectIntl(ForgotPasswordPage); const mockStore = configureStore(); const initialState = { forgotPassword: { - status: null, + status: '', }, }; @@ -138,7 +141,7 @@ describe('ForgotPasswordPage', () => { expect(forgotPage.find()).toBeTruthy(); }); - it('should display success message after email is sent', async () => { + it('should display success message after email is sent', () => { store = mockStore({ ...initialState, forgotPassword: { @@ -152,4 +155,19 @@ describe('ForgotPasswordPage', () => { const wrapper = mount(reduxWrapper()); expect(wrapper.find('.alert-success').text()).toEqual(successMessage); }); + + it('should display invalid password reset link error', () => { + store = mockStore({ + ...initialState, + forgotPassword: { + status: PASSWORD_RESET.INVALID_TOKEN, + }, + }); + const successMessage = 'Invalid password reset link' + + 'This password reset link is invalid. It may have been used already. ' + + 'Enter your email below to receive a new link.'; + + const wrapper = mount(reduxWrapper()); + expect(wrapper.find('.alert-danger').text()).toEqual(successMessage); + }); }); diff --git a/src/login/tests/LoginPage.test.jsx b/src/login/tests/LoginPage.test.jsx index bc51162e..53d5a2f5 100644 --- a/src/login/tests/LoginPage.test.jsx +++ b/src/login/tests/LoginPage.test.jsx @@ -450,7 +450,7 @@ describe('LoginPage', () => { }, }); - renderer.create(reduxWrapper()); + renderer.create(reduxWrapper()); expect(document.cookie).toMatch(`${getConfig().USER_SURVEY_COOKIE_NAME}=login`); }); diff --git a/src/register/RegistrationPage.jsx b/src/register/RegistrationPage.jsx index 9427f012..556bb9a0 100644 --- a/src/register/RegistrationPage.jsx +++ b/src/register/RegistrationPage.jsx @@ -548,7 +548,7 @@ class RegistrationPage extends React.Component { { }} onClick={e => handleSubmit(e)} diff --git a/src/reset-password/tests/ResetPasswordPage.test.jsx b/src/reset-password/tests/ResetPasswordPage.test.jsx index 83ba02eb..77a6e518 100644 --- a/src/reset-password/tests/ResetPasswordPage.test.jsx +++ b/src/reset-password/tests/ResetPasswordPage.test.jsx @@ -1,5 +1,6 @@ import React from 'react'; +import { act } from 'react-dom/test-utils'; import { mount } from 'enzyme'; import configureStore from 'redux-mock-store'; import { Provider } from 'react-redux'; @@ -30,15 +31,6 @@ describe('ResetPasswordPage', () => { ); - const submitForm = (password) => { - const resetPasswordPage = mount(reduxWrapper()); - resetPasswordPage.find('input#newPassword').simulate('change', { target: { value: password, name: 'newPassword' } }); - resetPasswordPage.find('input#confirmPassword').simulate('change', { target: { value: password, name: 'confirmPassword' } }); - resetPasswordPage.find('button.btn-brand').simulate('click'); - - return resetPasswordPage; - }; - beforeEach(() => { store = mockStore(); props = { @@ -75,7 +67,13 @@ describe('ResetPasswordPage', () => { })); store.dispatch = jest.fn(store.dispatch); - const resetPasswordPage = submitForm(password); + const resetPasswordPage = mount(reduxWrapper()); + resetPasswordPage.find('input#newPassword').simulate('change', { target: { value: password, name: 'newPassword' } }); + resetPasswordPage.find('input#confirmPassword').simulate('change', { target: { value: password, name: 'confirmPassword' } }); + + await act(async () => { + await resetPasswordPage.find('button.btn-brand').simulate('click'); + }); expect(store.dispatch).toHaveBeenCalledWith(resetPassword( { new_password1: password, new_password2: password }, props.token, {},