From 3848fcffa478531ffb167049965122e7844c8175 Mon Sep 17 00:00:00 2001 From: Wouter Admiraal Date: Tue, 27 Apr 2021 15:51:18 +0200 Subject: [PATCH] SONAR-14604 Improve reset password form layout --- .../main/js/app/components/ResetPassword.css | 35 ----- .../main/js/app/components/ResetPassword.tsx | 39 +++--- .../__tests__/ResetPassword-test.tsx | 37 ++++++ .../__snapshots__/ResetPassword-test.tsx.snap | 57 +++++---- .../js/apps/account/components/Security.tsx | 9 +- .../__snapshots__/Security-test.tsx.snap | 32 +++-- .../ChangeAdminPasswordAppRenderer.tsx | 2 +- ...angeAdminPasswordAppRenderer-test.tsx.snap | 8 +- ...esetPassword.tsx => ResetPasswordForm.tsx} | 120 +++++++++--------- ...rd-test.tsx => ResetPasswordForm-test.tsx} | 6 +- .../__snapshots__/ResetPassword-test.tsx.snap | 81 ------------ .../ResetPasswordForm-test.tsx.snap | 71 +++++++++++ 12 files changed, 259 insertions(+), 238 deletions(-) delete mode 100644 server/sonar-web/src/main/js/app/components/ResetPassword.css rename server/sonar-web/src/main/js/components/common/{ResetPassword.tsx => ResetPasswordForm.tsx} (56%) rename server/sonar-web/src/main/js/components/common/__tests__/{ResetPassword-test.tsx => ResetPasswordForm-test.tsx} (93%) delete mode 100644 server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPassword-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPasswordForm-test.tsx.snap diff --git a/server/sonar-web/src/main/js/app/components/ResetPassword.css b/server/sonar-web/src/main/js/app/components/ResetPassword.css deleted file mode 100644 index e0a344a0a42..00000000000 --- a/server/sonar-web/src/main/js/app/components/ResetPassword.css +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2021 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -.reset-page { - padding-top: 10vh; -} - -.reset-page h1 { - line-height: 1.5; - font-size: 24px; - font-weight: 300; - text-align: center; -} - -.reset-form { - width: 300px; - margin-left: auto; - margin-right: auto; -} diff --git a/server/sonar-web/src/main/js/app/components/ResetPassword.tsx b/server/sonar-web/src/main/js/app/components/ResetPassword.tsx index 9a55f23a4d2..55ef8b4c88f 100644 --- a/server/sonar-web/src/main/js/app/components/ResetPassword.tsx +++ b/server/sonar-web/src/main/js/app/components/ResetPassword.tsx @@ -19,30 +19,37 @@ */ import * as React from 'react'; import { translate } from 'sonar-ui-common/helpers/l10n'; -import ResetPasswordForm from '../../components/common/ResetPassword'; +import ResetPasswordForm from '../../components/common/ResetPasswordForm'; import { whenLoggedIn } from '../../components/hoc/whenLoggedIn'; +import { getBaseUrl } from '../../helpers/system'; import GlobalMessagesContainer from './GlobalMessagesContainer'; -import './ResetPassword.css'; export interface ResetPasswordProps { currentUser: T.LoggedInUser; } -export function ResetPassword(props: ResetPasswordProps) { - const { currentUser } = props; - const redirect = () => { - window.location.href = `/`; // force a refresh for the backend to handle additional redirects - }; - +export function ResetPassword({ currentUser }: ResetPasswordProps) { return ( -
-

{translate('my_account.reset_password')}

-

- {translate('my_account.reset_password.explain')} -

- -
- +
+
+ + +

{translate('my_account.reset_password')}

+

+ {translate('my_account.reset_password.explain')} +

+ +
+

{translate('my_profile.password.title')}

+ + { + // Force a refresh for the backend to handle additional redirects. + window.location.href = getBaseUrl() + '/'; + }} + /> +
); diff --git a/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx index 0f3093f3f51..56b33efcc57 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx +++ b/server/sonar-web/src/main/js/app/components/__tests__/ResetPassword-test.tsx @@ -19,13 +19,50 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import ResetPasswordForm from '../../../components/common/ResetPasswordForm'; import { mockLoggedInUser } from '../../../helpers/testMocks'; import { ResetPassword, ResetPasswordProps } from '../ResetPassword'; +jest.mock('../../../helpers/system', () => ({ + getBaseUrl: jest.fn().mockReturnValue('/context') +})); + +const originalLocation = window.location; + +beforeAll(() => { + const location = { + ...window.location, + href: null + }; + Object.defineProperty(window, 'location', { + writable: true, + value: location + }); +}); + +afterAll(() => { + Object.defineProperty(window, 'location', { + writable: true, + value: originalLocation + }); +}); + it('should render correctly', () => { expect(shallowRender()).toMatchSnapshot(); }); +it('should navigate to the homepage after submission', () => { + const wrapper = shallowRender(); + const form = wrapper.find(ResetPasswordForm); + const { onPasswordChange } = form.props(); + + if (onPasswordChange) { + onPasswordChange(); + } + + expect(window.location.href).toBe('/context/'); +}); + function shallowRender(props: Partial = {}) { return shallow(); } diff --git a/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/ResetPassword-test.tsx.snap b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/ResetPassword-test.tsx.snap index ad2db130e85..cf445a7dcb5 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/ResetPassword-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/ResetPassword-test.tsx.snap @@ -2,34 +2,43 @@ exports[`should render correctly 1`] = `
-

- my_account.reset_password -

-

- my_account.reset_password.explain -

-
- +

+ my_account.reset_password +

+

+ my_account.reset_password.explain +

+
+

+ my_profile.password.title +

+ + /> +
`; diff --git a/server/sonar-web/src/main/js/apps/account/components/Security.tsx b/server/sonar-web/src/main/js/apps/account/components/Security.tsx index e6c0af20238..b5300960175 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Security.tsx +++ b/server/sonar-web/src/main/js/apps/account/components/Security.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { connect } from 'react-redux'; import { translate } from 'sonar-ui-common/helpers/l10n'; -import ResetPassword from '../../../components/common/ResetPassword'; +import ResetPasswordForm from '../../../components/common/ResetPasswordForm'; import { getCurrentUser, Store } from '../../../store/rootReducer'; import Tokens from './Tokens'; @@ -34,7 +34,12 @@ export function Security({ user }: SecurityProps) {
- {user.local && } + {user.local && ( +
+

{translate('my_profile.password.title')}

+ +
+ )}
); } diff --git a/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap b/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap index 4adb1b2c1c2..c120e9b1c33 100644 --- a/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Security-test.tsx.snap @@ -12,18 +12,28 @@ exports[`should render correctly: local user 1`] = ` - +

+ my_profile.password.title +

+ + /> +
`; diff --git a/server/sonar-web/src/main/js/apps/change-admin-password/ChangeAdminPasswordAppRenderer.tsx b/server/sonar-web/src/main/js/apps/change-admin-password/ChangeAdminPasswordAppRenderer.tsx index 0f01456ccba..cee0dce669e 100644 --- a/server/sonar-web/src/main/js/apps/change-admin-password/ChangeAdminPasswordAppRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/change-admin-password/ChangeAdminPasswordAppRenderer.tsx @@ -137,7 +137,7 @@ export default function ChangeAdminPasswordAppRenderer(props: ChangeAdminPasswor
- {translate('change_verb')} + {translate('update_verb')} {submitting && }
diff --git a/server/sonar-web/src/main/js/apps/change-admin-password/__tests__/__snapshots__/ChangeAdminPasswordAppRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/change-admin-password/__tests__/__snapshots__/ChangeAdminPasswordAppRenderer-test.tsx.snap index 5c5895a5782..836b65c7375 100644 --- a/server/sonar-web/src/main/js/apps/change-admin-password/__tests__/__snapshots__/ChangeAdminPasswordAppRenderer-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/change-admin-password/__tests__/__snapshots__/ChangeAdminPasswordAppRenderer-test.tsx.snap @@ -79,7 +79,7 @@ exports[`should render correctly: cannot submit 1`] = ` - change_verb + update_verb
@@ -164,7 +164,7 @@ exports[`should render correctly: default 1`] = ` - change_verb + update_verb @@ -249,7 +249,7 @@ exports[`should render correctly: submitting 1`] = ` - change_verb + update_verb @@ -368,7 +368,7 @@ exports[`should render correctly: trying to use default admin password 1`] = ` - change_verb + update_verb diff --git a/server/sonar-web/src/main/js/components/common/ResetPassword.tsx b/server/sonar-web/src/main/js/components/common/ResetPasswordForm.tsx similarity index 56% rename from server/sonar-web/src/main/js/components/common/ResetPassword.tsx rename to server/sonar-web/src/main/js/components/common/ResetPasswordForm.tsx index ff59d0a1173..8f46d2f8650 100644 --- a/server/sonar-web/src/main/js/components/common/ResetPassword.tsx +++ b/server/sonar-web/src/main/js/components/common/ResetPasswordForm.tsx @@ -26,6 +26,7 @@ import { translate } from 'sonar-ui-common/helpers/l10n'; import { changePassword } from '../../api/users'; interface Props { + className?: string; user: T.LoggedInUser; onPasswordChange?: () => void; } @@ -35,7 +36,7 @@ interface State { success: boolean; } -export default class ResetPassword extends React.Component { +export default class ResetPasswordForm extends React.Component { oldPassword: HTMLInputElement | null = null; password: HTMLInputElement | null = null; passwordConfirmation: HTMLInputElement | null = null; @@ -84,72 +85,69 @@ export default class ResetPassword extends React.Component { }; render() { + const { className } = this.props; const { success, errors } = this.state; return ( -
-

{translate('my_profile.password.title')}

+
+ {success && {translate('my_profile.password.changed')}} - - {success && {translate('my_profile.password.changed')}} + {errors && + errors.map((e, i) => ( + /* eslint-disable-next-line react/no-array-index-key */ + + {e} + + ))} - {errors && - errors.map((e, i) => ( - /* eslint-disable-next-line react/no-array-index-key */ - - {e} - - ))} + - - -
- - (this.oldPassword = elem)} - required={true} - type="password" - /> -
-
- - (this.password = elem)} - required={true} - type="password" - /> -
-
- - (this.passwordConfirmation = elem)} - required={true} - type="password" - /> -
-
- {translate('update_verb')} -
- -
+
+ + (this.oldPassword = elem)} + required={true} + type="password" + /> +
+
+ + (this.password = elem)} + required={true} + type="password" + /> +
+
+ + (this.passwordConfirmation = elem)} + required={true} + type="password" + /> +
+
+ {translate('update_verb')} +
+ ); } } diff --git a/server/sonar-web/src/main/js/components/common/__tests__/ResetPassword-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/ResetPasswordForm-test.tsx similarity index 93% rename from server/sonar-web/src/main/js/components/common/__tests__/ResetPassword-test.tsx rename to server/sonar-web/src/main/js/components/common/__tests__/ResetPasswordForm-test.tsx index 904f693ed69..e940f20395e 100644 --- a/server/sonar-web/src/main/js/components/common/__tests__/ResetPassword-test.tsx +++ b/server/sonar-web/src/main/js/components/common/__tests__/ResetPasswordForm-test.tsx @@ -22,7 +22,7 @@ import * as React from 'react'; import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; import { changePassword } from '../../../api/users'; import { mockEvent, mockLoggedInUser } from '../../../helpers/testMocks'; -import ResetPassword from '../ResetPassword'; +import ResetPasswordForm from '../ResetPasswordForm'; jest.mock('../../../api/users', () => ({ changePassword: jest.fn().mockResolvedValue({}) @@ -74,6 +74,6 @@ it('renders correctly', () => { expect(shallowRender()).toMatchSnapshot(); }); -function shallowRender(props?: Partial) { - return shallow(); +function shallowRender(props?: Partial) { + return shallow(); } diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPassword-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPassword-test.tsx.snap deleted file mode 100644 index f2fbe03c093..00000000000 --- a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPassword-test.tsx.snap +++ /dev/null @@ -1,81 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
-

- my_profile.password.title -

-
- -
- - -
-
- - -
-
- - -
-
- - update_verb - -
- -
-`; diff --git a/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPasswordForm-test.tsx.snap b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPasswordForm-test.tsx.snap new file mode 100644 index 00000000000..3f32833747d --- /dev/null +++ b/server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/ResetPasswordForm-test.tsx.snap @@ -0,0 +1,71 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + update_verb + +
+ +`; -- 2.39.5