diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2020-01-03 09:29:51 +0100 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2020-01-06 20:46:13 +0100 |
commit | ccfd204b05b7e8b8c47273e5db78e9bd22128d60 (patch) | |
tree | 56c5adb3f0108f10d86f8169bb5375b2b8374756 /server/sonar-web/src/main/js/apps/sessions | |
parent | e5d9b437e9ba5bbe933ee068dd31d7c716824428 (diff) | |
download | sonarqube-ccfd204b05b7e8b8c47273e5db78e9bd22128d60.tar.gz sonarqube-ccfd204b05b7e8b8c47273e5db78e9bd22128d60.zip |
Improve test coverage
Diffstat (limited to 'server/sonar-web/src/main/js/apps/sessions')
7 files changed, 90 insertions, 427 deletions
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 index 893a586e3f6..1ba621cadb7 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx @@ -17,19 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { Location } from 'history'; import * as React from 'react'; import { connect } from 'react-redux'; import { getReturnUrl } from 'sonar-ui-common/helpers/urls'; import { getIdentityProviders } from '../../../api/users'; -import { isSonarCloud } from '../../../helpers/system'; import { doLogin } from '../../../store/rootActions'; import Login from './Login'; -import LoginSonarCloud from './LoginSonarCloud'; interface OwnProps { - location: { - hash?: string; - pathName: string; + location: Pick<Location, 'hash' | 'pathname' | 'query'> & { query: { advanced?: string; return_to?: string }; }; } @@ -44,7 +41,7 @@ interface State { identityProviders?: T.IdentityProvider[]; } -class LoginContainer extends React.PureComponent<Props, State> { +export class LoginContainer extends React.PureComponent<Props, State> { mounted = false; state: State = {}; @@ -52,11 +49,9 @@ class LoginContainer extends React.PureComponent<Props, State> { componentDidMount() { this.mounted = true; getIdentityProviders().then( - identityProvidersResponse => { + ({ identityProviders }) => { if (this.mounted) { - this.setState({ - identityProviders: identityProvidersResponse.identityProviders - }); + this.setState({ identityProviders }); } }, () => {} @@ -78,21 +73,11 @@ class LoginContainer extends React.PureComponent<Props, State> { render() { const { location } = this.props; const { identityProviders } = this.state; + if (!identityProviders) { return null; } - if (isSonarCloud()) { - return ( - <LoginSonarCloud - identityProviders={identityProviders} - onSubmit={this.handleSubmit} - returnTo={getReturnUrl(location)} - showForm={location.query['advanced'] !== undefined} - /> - ); - } - return ( <Login identityProviders={identityProviders} 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 deleted file mode 100644 index 5b21e3c8d5d..00000000000 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.css +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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-alert { - margin: 10vh auto 5vh auto; - width: 256px; -} - -.sonarcloud-login-page { - margin-top: 15vh; - width: 216px; - margin-left: auto; - margin-right: auto; - padding: calc(4 * var(--gridSize)) 20px; -} - -.sonarcloud-login-alert ~ .sonarcloud-login-page { - margin-top: 0; -} - -.sonarcloud-login-page-large { - width: 300px; -} - -.sonarcloud-login-title { - line-height: 1.5; - font-size: var(--bigFontSize); - font-weight: 300; - width: 135px; - margin: var(--gridSize) auto calc(3 * var(--gridSize)); -} - -.sonarcloud-oauth-providers.oauth-providers > ul { - width: 186px; -} - -.sonarcloud-oauth-providers.oauth-providers > ul > li { - margin-bottom: var(--gridSize); -} - -.sonarcloud-oauth-providers.oauth-providers .oauth-providers-help { - right: -22px; -} - -.sonarcloud-login-cancel { - text-align: center; -} 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 deleted file mode 100644 index c16147c3b5c..00000000000 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.tsx +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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 classNames from 'classnames'; -import * as React from 'react'; -import { connect } from 'react-redux'; -import { Alert } from 'sonar-ui-common/components/ui/Alert'; -import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n'; -import { getBaseUrl } from 'sonar-ui-common/helpers/urls'; -import { Store } from '../../../store/rootReducer'; -import LoginForm from './LoginForm'; -import './LoginSonarCloud.css'; -import OAuthProviders from './OAuthProviders'; - -interface Props { - identityProviders: T.IdentityProvider[]; - onSubmit: (login: string, password: string) => Promise<void>; - returnTo: string; - showForm?: boolean; - authorizationError?: boolean; - authenticationError?: boolean; -} - -function formatLabel(name: string) { - return translateWithParameters('login.with_x', name); -} - -export function LoginSonarCloud({ - showForm, - identityProviders, - returnTo, - onSubmit, - authorizationError, - authenticationError -}: Props) { - const displayForm = showForm || identityProviders.length <= 0; - const displayErrorAction = authorizationError || authenticationError; - return ( - <> - {displayErrorAction && ( - <Alert className="sonarcloud-login-alert" display="block" variant="warning"> - {translate('login.unauthorized_access_alert')} - </Alert> - )} - <div - className={classNames('sonarcloud-login-page boxed-group boxed-group-inner', { - 'sonarcloud-login-page-large': displayForm - })} - id="login_form"> - <div className="text-center"> - <img - alt="SonarCloud logo" - height={36} - src={`${getBaseUrl()}/images/sonarcloud-square-logo.svg`} - width={36} - /> - <h1 className="sonarcloud-login-title"> - {translate('login.login_or_signup_to_sonarcloud')} - </h1> - </div> - - {displayForm ? ( - <LoginForm onSubmit={onSubmit} returnTo={returnTo} /> - ) : ( - <OAuthProviders - className="sonarcloud-oauth-providers" - formatLabel={formatLabel} - identityProviders={identityProviders} - returnTo={returnTo} - /> - )} - - {displayErrorAction && ( - <div className="sonarcloud-login-cancel"> - <div className="horizontal-pipe-separator"> - <div className="horizontal-separator" /> - <span className="note">{translate('or')}</span> - <div className="horizontal-separator" /> - </div> - <a href={`${getBaseUrl()}/`}>{translate('go_back_to_homepage')}</a> - </div> - )} - </div> - </> - ); -} - -const mapStateToProps = (state: Store) => ({ - authorizationError: state.appState.authorizationError, - authenticationError: state.appState.authenticationError -}); - -export default connect(mapStateToProps)(LoginSonarCloud); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginContainer-test.tsx b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginContainer-test.tsx new file mode 100644 index 00000000000..81f0b90e9b7 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginContainer-test.tsx @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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 { shallow } from 'enzyme'; +import * as React from 'react'; +import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; +import { getIdentityProviders } from '../../../../api/users'; +import { mockLocation } from '../../../../helpers/testMocks'; +import { LoginContainer } from '../LoginContainer'; + +jest.mock('../../../../api/users', () => { + const { mockIdentityProvider } = jest.requireActual('../../../../helpers/testMocks'); + return { + getIdentityProviders: jest + .fn() + .mockResolvedValue({ identityProviders: [mockIdentityProvider()] }) + }; +}); + +beforeEach(jest.clearAllMocks); + +it('should render correctly', async () => { + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + expect(wrapper).toMatchSnapshot(); + expect(getIdentityProviders).toBeCalled(); +}); + +it('should not provide any options if no IdPs are present', async () => { + (getIdentityProviders as jest.Mock).mockResolvedValue({}); + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + expect(wrapper.type()).toBeNull(); + expect(getIdentityProviders).toBeCalled(); +}); + +it('should handle submission', () => { + const doLogin = jest.fn().mockResolvedValue(null); + const wrapper = shallowRender({ doLogin }); + wrapper.instance().handleSubmit('user', 'pass'); + expect(doLogin).toBeCalledWith('user', 'pass'); +}); + +function shallowRender(props: Partial<LoginContainer['props']> = {}) { + return shallow<LoginContainer>( + <LoginContainer doLogin={jest.fn()} location={mockLocation()} {...props} /> + ); +} 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 deleted file mode 100644 index f922a702efa..00000000000 --- a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginSonarCloud-test.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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 { shallow } from 'enzyme'; -import * as React from 'react'; -import { LoginSonarCloud } from '../LoginSonarCloud'; - -const identityProvider = { - backgroundColor: '#000', - iconPath: '/some/path', - key: 'foo', - name: 'foo' -}; - -it('logs in with identity provider', () => { - const wrapper = shallow( - <LoginSonarCloud identityProviders={[identityProvider]} onSubmit={jest.fn()} returnTo="" /> - ); - expect(wrapper).toMatchSnapshot(); -}); - -it('logs in with simple form', () => { - expect( - shallow( - <LoginSonarCloud - identityProviders={[identityProvider]} - onSubmit={jest.fn()} - returnTo="" - showForm={true} - /> - ) - ).toMatchSnapshot(); - expect( - shallow(<LoginSonarCloud identityProviders={[]} onSubmit={jest.fn()} returnTo="" />) - ).toMatchSnapshot(); -}); - -it("shows an warning message if there's an authorization error", () => { - const wrapper = shallow( - <LoginSonarCloud - authorizationError={true} - identityProviders={[identityProvider]} - onSubmit={jest.fn()} - returnTo="" - /> - ); - expect(wrapper).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginContainer-test.tsx.snap b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginContainer-test.tsx.snap new file mode 100644 index 00000000000..dd0cc38ae08 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginContainer-test.tsx.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` +<Login + identityProviders={ + Array [ + Object { + "backgroundColor": "#000000", + "iconPath": "/path/icon.svg", + "key": "github", + "name": "Github", + }, + ] + } + onSubmit={[Function]} + returnTo="/" +/> +`; 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 deleted file mode 100644 index 56308c07525..00000000000 --- a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginSonarCloud-test.tsx.snap +++ /dev/null @@ -1,170 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`logs in with identity provider 1`] = ` -<Fragment> - <div - className="sonarcloud-login-page boxed-group boxed-group-inner" - id="login_form" - > - <div - className="text-center" - > - <img - alt="SonarCloud logo" - height={36} - src="/images/sonarcloud-square-logo.svg" - width={36} - /> - <h1 - className="sonarcloud-login-title" - > - login.login_or_signup_to_sonarcloud - </h1> - </div> - <OAuthProviders - className="sonarcloud-oauth-providers" - formatLabel={[Function]} - identityProviders={ - Array [ - Object { - "backgroundColor": "#000", - "iconPath": "/some/path", - "key": "foo", - "name": "foo", - }, - ] - } - returnTo="" - /> - </div> -</Fragment> -`; - -exports[`logs in with simple form 1`] = ` -<Fragment> - <div - className="sonarcloud-login-page boxed-group boxed-group-inner sonarcloud-login-page-large" - id="login_form" - > - <div - className="text-center" - > - <img - alt="SonarCloud logo" - height={36} - src="/images/sonarcloud-square-logo.svg" - width={36} - /> - <h1 - className="sonarcloud-login-title" - > - login.login_or_signup_to_sonarcloud - </h1> - </div> - <LoginForm - onSubmit={[MockFunction]} - returnTo="" - /> - </div> -</Fragment> -`; - -exports[`logs in with simple form 2`] = ` -<Fragment> - <div - className="sonarcloud-login-page boxed-group boxed-group-inner sonarcloud-login-page-large" - id="login_form" - > - <div - className="text-center" - > - <img - alt="SonarCloud logo" - height={36} - src="/images/sonarcloud-square-logo.svg" - width={36} - /> - <h1 - className="sonarcloud-login-title" - > - login.login_or_signup_to_sonarcloud - </h1> - </div> - <LoginForm - onSubmit={[MockFunction]} - returnTo="" - /> - </div> -</Fragment> -`; - -exports[`shows an warning message if there's an authorization error 1`] = ` -<Fragment> - <Alert - className="sonarcloud-login-alert" - display="block" - variant="warning" - > - login.unauthorized_access_alert - </Alert> - <div - className="sonarcloud-login-page boxed-group boxed-group-inner" - id="login_form" - > - <div - className="text-center" - > - <img - alt="SonarCloud logo" - height={36} - src="/images/sonarcloud-square-logo.svg" - width={36} - /> - <h1 - className="sonarcloud-login-title" - > - login.login_or_signup_to_sonarcloud - </h1> - </div> - <OAuthProviders - className="sonarcloud-oauth-providers" - formatLabel={[Function]} - identityProviders={ - Array [ - Object { - "backgroundColor": "#000", - "iconPath": "/some/path", - "key": "foo", - "name": "foo", - }, - ] - } - returnTo="" - /> - <div - className="sonarcloud-login-cancel" - > - <div - className="horizontal-pipe-separator" - > - <div - className="horizontal-separator" - /> - <span - className="note" - > - or - </span> - <div - className="horizontal-separator" - /> - </div> - <a - href="/" - > - go_back_to_homepage - </a> - </div> - </div> -</Fragment> -`; |