From: Grégoire Aubert Date: Fri, 27 Apr 2018 07:19:46 +0000 (+0200) Subject: SONAR-10646 SONAR-10325 Update SonarCloud login page style X-Git-Tag: 7.5~1280 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=77e7e1c7c278a1798ffcff3da1a4cd34ae1f0e0e;p=sonarqube.git SONAR-10646 SONAR-10325 Update SonarCloud login page style --- diff --git a/server/sonar-web/public/images/sc-icon.svg b/server/sonar-web/public/images/sc-icon.svg new file mode 100644 index 00000000000..bc3d84e95d0 --- /dev/null +++ b/server/sonar-web/public/images/sc-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Login.css b/server/sonar-web/src/main/js/apps/sessions/components/Login.css new file mode 100644 index 00000000000..e5d49d403a1 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/Login.css @@ -0,0 +1,30 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +.login-page { + padding-top: 10vh; +} + +.login-title { + margin-bottom: 40px; + line-height: 1.5; + font-size: 24px; + font-weight: 300; + text-align: center; +} diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx b/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx new file mode 100644 index 00000000000..7af866cade5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/Login.tsx @@ -0,0 +1,45 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +import * as React from 'react'; +import LoginForm from './LoginForm'; +import OAuthProviders from './OAuthProviders'; +import { IdentityProvider } from '../../../app/types'; +import { translate } from '../../../helpers/l10n'; +import './Login.css'; + +interface Props { + identityProviders: IdentityProvider[]; + onSubmit: (login: string, password: string) => Promise; + returnTo: string; +} + +export default function Login({ identityProviders, onSubmit, returnTo }: Props) { + return ( +
+

{translate('login.login_to_sonarqube')}

+ + {identityProviders.length > 0 && ( + + )} + + 0} onSubmit={onSubmit} returnTo={returnTo} /> +
+ ); +} diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx b/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx new file mode 100644 index 00000000000..04396a37d99 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx @@ -0,0 +1,115 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +import * as React from 'react'; +import * as PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import Login from './Login'; +import LoginSonarCloud from './LoginSonarCloud'; +import { doLogin } from '../../../store/rootActions'; +import { getIdentityProviders } from '../../../api/users'; +import { IdentityProvider } from '../../../app/types'; +import { getBaseUrl } from '../../../helpers/urls'; + +interface Props { + doLogin: (login: string, password: string) => Promise; + location: { + hash?: string; + pathName: string; + query: { + return_to?: string; // eslint-disable-line camelcase + }; + }; +} + +interface State { + identityProviders?: IdentityProvider[]; +} + +class LoginContainer extends React.PureComponent { + mounted = false; + + static contextTypes = { + onSonarCloud: PropTypes.bool + }; + + state: State = {}; + + componentDidMount() { + this.mounted = true; + getIdentityProviders().then( + identityProvidersResponse => { + if (this.mounted) { + this.setState({ + identityProviders: identityProvidersResponse.identityProviders + }); + } + }, + () => {} + ); + } + + componentWillUnmount() { + this.mounted = false; + } + + getReturnUrl = () => { + const { location } = this.props; + const queryReturnTo = location.query['return_to']; + return queryReturnTo ? `${queryReturnTo}${location.hash}` : `${getBaseUrl()}/`; + }; + + handleSuccessfulLogin = () => { + window.location.href = this.getReturnUrl(); + }; + + handleSubmit = (login: string, password: string) => { + return this.props.doLogin(login, password).then(this.handleSuccessfulLogin, () => {}); + }; + + render() { + const { identityProviders } = this.state; + if (!identityProviders) { + return null; + } + + if (this.context.onSonarCloud) { + return ( + + ); + } + + return ( + + ); + } +} + +const mapStateToProps = null; +const mapDispatchToProps = { doLogin }; + +export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer as any); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.css b/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.css index fc74e4bba23..7eafbdb4e75 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.css +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.css @@ -17,9 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -.login-page { - padding-top: 10vh; -} .login-form { width: 300px; @@ -27,14 +24,6 @@ margin-right: auto; } -.login-title { - margin-bottom: 40px; - line-height: 1.5; - font-size: 24px; - font-weight: 300; - text-align: center; -} - .login-input { width: 100% !important; height: auto !important; diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.tsx b/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.tsx index 6cdc0087e02..ab0cecf826e 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.tsx @@ -19,18 +19,14 @@ */ import * as React from 'react'; import { Link } from 'react-router'; -import * as classNames from 'classnames'; -import OAuthProviders from './OAuthProviders'; +import DeferredSpinner from '../../../components/common/DeferredSpinner'; import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer'; -import { IdentityProvider } from '../../../app/types'; import { SubmitButton } from '../../../components/ui/buttons'; import { translate } from '../../../helpers/l10n'; -import DeferredSpinner from '../../../components/common/DeferredSpinner'; import './LoginForm.css'; interface Props { - onSonarCloud: boolean; - identityProviders: IdentityProvider[]; + collapsed?: boolean; onSubmit: (login: string, password: string) => Promise; returnTo: string; } @@ -46,7 +42,7 @@ export default class LoginForm extends React.PureComponent { constructor(props: Props) { super(props); this.state = { - collapsed: props.identityProviders.length > 0, + collapsed: Boolean(props.collapsed), loading: false, login: '', password: '' @@ -57,7 +53,7 @@ export default class LoginForm extends React.PureComponent { this.setState({ loading: false }); }; - handleSubmit = (event: React.SyntheticEvent) => { + handleSubmit = (event: React.FormEvent) => { event.preventDefault(); this.setState({ loading: true }); this.props @@ -65,94 +61,80 @@ export default class LoginForm extends React.PureComponent { .then(this.stopLoading, this.stopLoading); }; - handleMoreOptionsClick = (event: React.SyntheticEvent) => { + handleMoreOptionsClick = (event: React.MouseEvent) => { event.preventDefault(); this.setState({ collapsed: false }); }; - handleLoginChange = (event: React.SyntheticEvent) => + handleLoginChange = (event: React.ChangeEvent) => this.setState({ login: event.currentTarget.value }); - handlePwdChange = (event: React.SyntheticEvent) => + handlePwdChange = (event: React.ChangeEvent) => this.setState({ password: event.currentTarget.value }); render() { - const loginTitle = this.props.onSonarCloud - ? translate('login.login_to_sonarcloud') - : translate('login.login_to_sonarqube'); - + if (this.state.collapsed) { + return ( + + ); + } return ( -
-

{loginTitle}

+
+ - {this.props.identityProviders.length > 0 && ( - + + - )} - - {this.state.collapsed ? ( - - ) : ( - - - -
- - -
+
-
- - -
+
+ + +
-
-
- - - {translate('sessions.log_in')} - - - {translate('cancel')} - -
-
- - )} - +
+
+ + + {translate('sessions.log_in')} + + + {translate('cancel')} + +
+
+ ); } } diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.tsx b/server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.tsx deleted file mode 100644 index 63c3f7b998a..00000000000 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 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. - */ -import * as React from 'react'; -import * as PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import LoginForm from './LoginForm'; -import { doLogin } from '../../../store/rootActions'; -import { getIdentityProviders } from '../../../api/users'; -import { IdentityProvider } from '../../../app/types'; -import { getBaseUrl } from '../../../helpers/urls'; - -interface Props { - doLogin: (login: string, password: string) => Promise; - location: { hash?: string; pathName: string; query: { return_to?: string } }; -} - -interface State { - identityProviders?: IdentityProvider[]; -} - -class LoginFormContainer extends React.PureComponent { - mounted = false; - - static contextTypes = { - onSonarCloud: PropTypes.bool - }; - - state: State = {}; - - componentDidMount() { - this.mounted = true; - getIdentityProviders().then( - identityProvidersResponse => { - if (this.mounted) { - this.setState({ - identityProviders: identityProvidersResponse.identityProviders - }); - } - }, - () => {} - ); - } - - componentWillUnmount() { - this.mounted = false; - } - - getReturnUrl = () => { - const { location } = this.props; - const queryReturnTo = location.query['return_to']; - return queryReturnTo ? `${queryReturnTo}${location.hash}` : `${getBaseUrl()}/`; - }; - - handleSuccessfulLogin = () => { - window.location.href = this.getReturnUrl(); - }; - - handleSubmit = (login: string, password: string) => { - return this.props.doLogin(login, password).then(this.handleSuccessfulLogin, () => {}); - }; - - render() { - const { identityProviders } = this.state; - if (!identityProviders) { - return null; - } - - return ( - - ); - } -} - -const mapStateToProps = null; -const mapDispatchToProps = { doLogin }; - -export default connect(mapStateToProps, mapDispatchToProps)(LoginFormContainer as any); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.css b/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.css new file mode 100644 index 00000000000..b618673b4db --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.css @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +.sonarcloud-login-page { + margin-top: 15vh; + width: 200px; + margin-left: auto; + margin-right: auto; + padding: calc(2 * var(--gridSize)) 20px; +} + +.sonarcloud-login-title { + line-height: 1.5; + font-size: var(--bigFontSize); + font-weight: 300; + width: 135px; + margin: var(--gridSize) auto calc(2 * var(--gridSize)); +} + +.sonarcloud-oauth-providers.oauth-providers > ul > li { + margin-bottom: var(--gridSize); +} + +.sonarcloud-oauth-providers.oauth-providers > ul > li > a > span { + font-weight: 600; + padding-left: calc(1.5 * var(--gridSize)); +} + +.sonarcloud-oauth-providers.oauth-providers > ul > li > a > span::before { + content: ''; + border-left: 1px var(--gray71) solid; + height: 10px; + opacity: 0.4; + margin-right: calc(1.5 * var(--gridSize)); +} + +.sonarcloud-oauth-providers.oauth-providers .oauth-providers-help { + right: -22px; +} diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.tsx b/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.tsx new file mode 100644 index 00000000000..9df3ffd6a56 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.tsx @@ -0,0 +1,59 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +import * as React from 'react'; +import OAuthProviders from './OAuthProviders'; +import { IdentityProvider } from '../../../app/types'; +import { getHostUrl } from '../../../helpers/urls'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; +import './LoginSonarCloud.css'; + +interface Props { + identityProviders: IdentityProvider[]; + returnTo: string; +} + +export default function LoginSonarCloud({ identityProviders, returnTo }: Props) { + return ( +
+
+ SonarCloud logo +

+ {translate('login.login_or_signup_to_sonarcloud')} +

+
+ + +
+ ); +} + +function formatLabel(name: string) { + return translateWithParameters('login.with_x', name); +} diff --git a/server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.tsx b/server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.tsx index 5664080f828..817cb3d2ade 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.tsx @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; +import * as classNames from 'classnames'; import { translateWithParameters } from '../../../helpers/l10n'; import * as theme from '../../../app/theme'; import { IdentityProvider } from '../../../app/types'; @@ -28,13 +29,16 @@ import { getBaseUrl } from '../../../helpers/urls'; import './OAuthProviders.css'; interface Props { + className?: string; + formatLabel?: (name: string) => React.ReactNode; identityProviders: IdentityProvider[]; returnTo: string; } export default function OAuthProviders(props: Props) { + const formatFunction = props.formatLabel || defaultFormatLabel; return ( -
+
    {props.identityProviders.map(identityProvider => (
  • @@ -49,11 +53,11 @@ export default function OAuthProviders(props: Props) { }}> {identityProvider.name} - {defaultFormatLabel(identityProvider.name)} + {formatFunction(identityProvider.name)} {identityProvider.helpMessage && ( diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/EmailAlreadyExists-test.tsx b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/EmailAlreadyExists-test.tsx index 81b2176c785..1540dd3e55f 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/EmailAlreadyExists-test.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/EmailAlreadyExists-test.tsx @@ -30,7 +30,7 @@ jest.mock('../../../../api/users', () => ({ key: 'bitbucket', name: 'Bitbucket', iconPath: '/static/authbitbucket/bitbucket.svg', - backgroundColor: '#205081' + backgroundColor: '#0052cc' }, { key: 'github', diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/Login-test.tsx b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/Login-test.tsx new file mode 100644 index 00000000000..82dcc6e37be --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/Login-test.tsx @@ -0,0 +1,41 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import Login from '../Login'; + +const identityProvider = { + backgroundColor: '#000', + iconPath: '/some/path', + key: 'foo', + name: 'foo' +}; + +it('logs in with form alone', () => { + const wrapper = shallow(); + expect(wrapper).toMatchSnapshot(); +}); + +it('logs in with identity provider', () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginForm-test.tsx b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginForm-test.tsx index 8ba3c8e1d8f..e1cbea70b3a 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginForm-test.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginForm-test.tsx @@ -22,18 +22,9 @@ import { shallow } from 'enzyme'; import LoginForm from '../LoginForm'; import { change, click, submit, waitAndUpdate } from '../../../../helpers/testUtils'; -const identityProvider = { - backgroundColor: '#000', - iconPath: '/some/path', - key: 'foo', - name: 'foo' -}; - it('logs in with simple credentials', () => { const onSubmit = jest.fn(() => Promise.resolve()); - const wrapper = shallow( - - ); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); change(wrapper.find('#login'), 'admin'); @@ -45,9 +36,7 @@ it('logs in with simple credentials', () => { it('should display a spinner and disabled button while loading', async () => { const onSubmit = jest.fn(() => Promise.resolve()); - const wrapper = shallow( - - ); + const wrapper = shallow(); change(wrapper.find('#login'), 'admin'); change(wrapper.find('#password'), 'admin'); @@ -58,27 +47,8 @@ it('should display a spinner and disabled button while loading', async () => { await waitAndUpdate(wrapper); }); -it('logs in with identity provider', () => { - const wrapper = shallow( - - ); - expect(wrapper).toMatchSnapshot(); -}); - it('expands more options', () => { - const wrapper = shallow( - - ); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); click(wrapper.find('.js-more-options')); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginSonarCloud-test.tsx b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginSonarCloud-test.tsx new file mode 100644 index 00000000000..0fa5c7ae1da --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginSonarCloud-test.tsx @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import LoginSonarCloud from '../LoginSonarCloud'; + +const identityProvider = { + backgroundColor: '#000', + iconPath: '/some/path', + key: 'foo', + name: 'foo' +}; + +it('logs in with identity provider', () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/OAuthProviders-test.tsx b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/OAuthProviders-test.tsx new file mode 100644 index 00000000000..65755a26b81 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/OAuthProviders-test.tsx @@ -0,0 +1,56 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import OAuthProviders from '../OAuthProviders'; + +const identityProviders = [ + { + backgroundColor: '#000', + iconPath: '/some/path', + key: 'foo', + name: 'Foo' + }, + { + backgroundColor: '#00F', + helpMessage: 'Help message!', + iconPath: '/icon/path', + key: 'bar', + name: 'Bar' + } +]; + +it('should render correctly', () => { + expect( + shallow() + ).toMatchSnapshot(); +}); + +it('should use the custom label formatter', () => { + expect( + shallow( + 'custom_format.' + name} + identityProviders={[identityProviders[0]]} + returnTo="" + /> + ) + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/EmailAlreadyExists-test.tsx.snap b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/EmailAlreadyExists-test.tsx.snap index 096b7135b1c..f2da9104731 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/EmailAlreadyExists-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/EmailAlreadyExists-test.tsx.snap @@ -31,7 +31,7 @@ exports[`render 1`] = ` className="identity-provider" style={ Object { - "backgroundColor": "#205081", + "backgroundColor": "#0052cc", "color": "#fff", } } diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/Login-test.tsx.snap b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/Login-test.tsx.snap new file mode 100644 index 00000000000..1d254a9eed4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/Login-test.tsx.snap @@ -0,0 +1,50 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`logs in with form alone 1`] = ` +
    +

    + login.login_to_sonarqube +

    + +
    +`; + +exports[`logs in with identity provider 1`] = ` +
    +

    + login.login_to_sonarqube +

    + + +
    +`; diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginForm-test.tsx.snap index c2082daeaff..aa19aded41e 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginForm-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginForm-test.tsx.snap @@ -2,342 +2,239 @@ exports[`expands more options 1`] = `
    -

    - login.login_to_sonarqube -

    - - + login.more_options +
    `; exports[`expands more options 2`] = ` -
    -

    +
    - login.login_to_sonarqube -

    - -
    + login + + +
    +
    - -
    - - -
    + password + + +
    +
    - - -
    -
    -
    - - - sessions.log_in - - - cancel - -
    + sessions.log_in + + + cancel +
    - -
    + + `; -exports[`logs in with identity provider 1`] = ` -
    -

    - login.login_to_sonarqube -

    - + -
    -`; - -exports[`logs in with simple credentials 1`] = ` -
    -

    - login.login_to_sonarqube -

    -
    - -
    - - -
    + password + + +
    +
    - - -
    -
    -
    - - - sessions.log_in - - - cancel - -
    + sessions.log_in + + + cancel +
    - -
    + + `; exports[`should display a spinner and disabled button while loading 1`] = ` -
    -

    +
    - login.login_to_sonarqube -

    -
    + login + + +
    +
    - -
    - - -
    + password + + +
    +
    - - -
    -
    -
    - - - sessions.log_in - - - cancel - -
    + sessions.log_in + + + cancel +
    - -
    + + `; diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginSonarCloud-test.tsx.snap b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginSonarCloud-test.tsx.snap new file mode 100644 index 00000000000..a14d1983c52 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginSonarCloud-test.tsx.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`logs in with identity provider 1`] = ` +
    +
    + SonarCloud logo +

    + login.login_or_signup_to_sonarcloud +

    +
    + +
    +`; diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/OAuthProviders-test.tsx.snap b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/OAuthProviders-test.tsx.snap new file mode 100644 index 00000000000..e7adf301d2c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/OAuthProviders-test.tsx.snap @@ -0,0 +1,99 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` +
    + +
    +`; + +exports[`should use the custom label formatter 1`] = ` +
    + +
    +`; diff --git a/server/sonar-web/src/main/js/apps/sessions/routes.ts b/server/sonar-web/src/main/js/apps/sessions/routes.ts index 92b4d569909..31b74819be8 100644 --- a/server/sonar-web/src/main/js/apps/sessions/routes.ts +++ b/server/sonar-web/src/main/js/apps/sessions/routes.ts @@ -23,7 +23,7 @@ const routes = [ { path: 'new', getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { - import('./components/LoginFormContainer').then(i => callback(null, i.default)); + import('./components/LoginContainer').then(i => callback(null, i.default)); } }, { diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index d75b929ec54..8a5e3264176 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1380,9 +1380,10 @@ user.password_doesnt_match_confirmation=Password doesn't match confirmation. user.login_or_email_used_as_scm_account=Login and email are automatically considered as SCM accounts login.login_to_sonarqube=Log In to SonarQube -login.login_to_sonarcloud=Log In to SonarCloud -login.more_options=More options +login.login_or_signup_to_sonarcloud=Log in or Sign up to SonarCloud login.login_with_x=Log in with {0} +login.more_options=More options +login.with_x=With {0} unauthorized.message=You're not authorized to access this page. Please contact the administrator. unauthorized.reason=Reason: