From 9a35b0e3e65302ee4f6c1b4cc2c5db71df5b0a5d Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 15 Mar 2022 17:45:43 +0100 Subject: SONAR-15914 Clean up redux --- .../js/apps/sessions/components/LoginContainer.tsx | 31 ++++++++++------------ .../main/js/apps/sessions/components/Logout.tsx | 27 +++++++------------ .../components/__tests__/LoginContainer-test.tsx | 15 ++++++----- .../sessions/components/__tests__/Logout-test.tsx | 30 ++++++++++++++------- 4 files changed, 54 insertions(+), 49 deletions(-) (limited to 'server/sonar-web/src/main/js/apps/sessions') 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 197caadbd43..294c57e47e8 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 @@ -19,25 +19,18 @@ */ import { Location } from 'history'; import * as React from 'react'; -import { connect } from 'react-redux'; +import { logIn } from '../../../api/auth'; import { getIdentityProviders } from '../../../api/users'; +import addGlobalErrorMessage from '../../../app/utils/addGlobalErrorMessage'; import { getReturnUrl } from '../../../helpers/urls'; -import { doLogin } from '../../../store/rootActions'; import { IdentityProvider } from '../../../types/types'; import Login from './Login'; -interface OwnProps { +interface Props { location: Pick & { query: { advanced?: string; return_to?: string }; }; } - -interface DispatchToProps { - doLogin: (login: string, password: string) => Promise; -} - -type Props = OwnProps & DispatchToProps; - interface State { identityProviders?: IdentityProvider[]; } @@ -55,7 +48,9 @@ export class LoginContainer extends React.PureComponent { this.setState({ identityProviders }); } }, - () => {} + () => { + /* already handled */ + } ); } @@ -67,8 +62,13 @@ export class LoginContainer extends React.PureComponent { window.location.href = getReturnUrl(this.props.location); }; - handleSubmit = (login: string, password: string) => { - return this.props.doLogin(login, password).then(this.handleSuccessfulLogin, () => {}); + handleSubmit = (id: string, password: string) => { + return logIn(id, password) + .then(this.handleSuccessfulLogin) + .catch(() => { + addGlobalErrorMessage('Authentication failed'); + return Promise.reject(); + }); }; render() { @@ -89,7 +89,4 @@ export class LoginContainer extends React.PureComponent { } } -const mapStateToProps = null; -const mapDispatchToProps = { doLogin: doLogin as any }; - -export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer); +export default LoginContainer; diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Logout.tsx b/server/sonar-web/src/main/js/apps/sessions/components/Logout.tsx index 3d5d250ec47..4e4cae3b245 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/Logout.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/Logout.tsx @@ -18,26 +18,23 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { connect } from 'react-redux'; +import { logOut } from '../../../api/auth'; import GlobalMessagesContainer from '../../../app/components/GlobalMessagesContainer'; import RecentHistory from '../../../app/components/RecentHistory'; +import addGlobalErrorMessage from '../../../app/utils/addGlobalErrorMessage'; import { translate } from '../../../helpers/l10n'; import { getBaseUrl } from '../../../helpers/system'; -import { doLogout } from '../../../store/rootActions'; -interface Props { - doLogout: () => Promise; -} - -export class Logout extends React.PureComponent { +export class Logout extends React.PureComponent<{}> { componentDidMount() { - this.props.doLogout().then( - () => { + logOut() + .then(() => { RecentHistory.clear(); window.location.replace(getBaseUrl() + '/'); - }, - () => {} - ); + }) + .catch(() => { + addGlobalErrorMessage('Logout failed'); + }); } render() { @@ -50,8 +47,4 @@ export class Logout extends React.PureComponent { } } -const mapStateToProps = () => ({}); - -const mapDispatchToProps = { doLogout }; - -export default connect(mapStateToProps, mapDispatchToProps)(Logout as any); +export default Logout; 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 index f09d24aba35..510f7c4074f 100644 --- 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 @@ -19,6 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import { logIn } from '../../../../api/auth'; import { getIdentityProviders } from '../../../../api/users'; import { mockLocation } from '../../../../helpers/testMocks'; import { waitAndUpdate } from '../../../../helpers/testUtils'; @@ -33,6 +34,10 @@ jest.mock('../../../../api/users', () => { }; }); +jest.mock('../../../../api/auth', () => ({ + logIn: jest.fn().mockResolvedValue({}) +})); + beforeEach(jest.clearAllMocks); it('should render correctly', async () => { @@ -53,14 +58,12 @@ it('should not provide any options if no IdPs are present', async () => { }); it('should handle submission', () => { - const doLogin = jest.fn().mockResolvedValue(null); - const wrapper = shallowRender({ doLogin }); + (logIn as jest.Mock).mockResolvedValue(null); + const wrapper = shallowRender(); wrapper.instance().handleSubmit('user', 'pass'); - expect(doLogin).toBeCalledWith('user', 'pass'); + expect(logIn).toBeCalledWith('user', 'pass'); }); function shallowRender(props: Partial = {}) { - return shallow( - - ); + return shallow(); } diff --git a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/Logout-test.tsx b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/Logout-test.tsx index dcb44bf2ed9..5b0d0012913 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/__tests__/Logout-test.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/__tests__/Logout-test.tsx @@ -19,11 +19,21 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import { logOut } from '../../../../api/auth'; +import addGlobalErrorMessage from '../../../../app/utils/addGlobalErrorMessage'; import { waitAndUpdate } from '../../../../helpers/testUtils'; import { Logout } from '../Logout'; -const originalLocation = window.location; +jest.mock('../../../../api/auth', () => ({ + logOut: jest.fn().mockResolvedValue(true) +})); + +jest.mock('../../../../app/utils/addGlobalErrorMessage', () => ({ + __esModule: true, + default: jest.fn() +})); +const originalLocation = window.location; beforeAll(() => { const location = { ...window.location, @@ -47,26 +57,28 @@ afterAll(() => { }); it('should logout correctly', async () => { - const doLogout = jest.fn().mockResolvedValue(true); + (logOut as jest.Mock).mockResolvedValue(true); - const wrapper = shallowRender({ doLogout }); + const wrapper = shallowRender(); await waitAndUpdate(wrapper); - expect(doLogout).toHaveBeenCalled(); + expect(logOut).toHaveBeenCalled(); expect(window.location.replace).toHaveBeenCalledWith('/'); + expect(addGlobalErrorMessage).not.toHaveBeenCalled(); }); it('should not redirect if logout fails', async () => { - const doLogout = jest.fn().mockRejectedValue(false); + (logOut as jest.Mock).mockRejectedValue(false); - const wrapper = shallowRender({ doLogout }); + const wrapper = shallowRender(); await waitAndUpdate(wrapper); - expect(doLogout).toHaveBeenCalled(); + expect(logOut).toHaveBeenCalled(); expect(window.location.replace).not.toHaveBeenCalled(); + expect(addGlobalErrorMessage).toHaveBeenCalled(); expect(wrapper).toMatchSnapshot(); }); -function shallowRender(props: Partial = {}) { - return shallow(); +function shallowRender() { + return shallow(); } -- cgit v1.2.3