aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/sessions
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2020-01-03 09:29:51 +0100
committerSonarTech <sonartech@sonarsource.com>2020-01-06 20:46:13 +0100
commitccfd204b05b7e8b8c47273e5db78e9bd22128d60 (patch)
tree56c5adb3f0108f10d86f8169bb5375b2b8374756 /server/sonar-web/src/main/js/apps/sessions
parente5d9b437e9ba5bbe933ee068dd31d7c716824428 (diff)
downloadsonarqube-ccfd204b05b7e8b8c47273e5db78e9bd22128d60.tar.gz
sonarqube-ccfd204b05b7e8b8c47273e5db78e9bd22128d60.zip
Improve test coverage
Diffstat (limited to 'server/sonar-web/src/main/js/apps/sessions')
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx27
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.css63
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/LoginSonarCloud.tsx109
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginContainer-test.tsx66
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/__tests__/LoginSonarCloud-test.tsx64
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginContainer-test.tsx.snap18
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/LoginSonarCloud-test.tsx.snap170
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>
-`;