[ARVADOS-WORKBENCH2] created: 1.4.1-421-g847f1902

Git user git at public.arvados.org
Tue Sep 1 23:11:33 UTC 2020


        at  847f19027dbe050bdceb835f4c8c67d386159a72 (commit)


commit 847f19027dbe050bdceb835f4c8c67d386159a72
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Tue Sep 1 20:09:59 2020 -0300

    16679: Adds test for auth middleware's logout handling.
    
    This confirms that the API endpoint is being called and the token is removed
    from local storage.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/store/auth/auth-middleware.test.ts b/src/store/auth/auth-middleware.test.ts
new file mode 100644
index 00000000..1fe34381
--- /dev/null
+++ b/src/store/auth/auth-middleware.test.ts
@@ -0,0 +1,44 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import 'jest-localstorage-mock';
+import Axios, { AxiosInstance } from "axios";
+import { createBrowserHistory } from "history";
+
+import { authMiddleware } from "./auth-middleware";
+import { RootStore, configureStore } from "../store";
+import { ServiceRepository, createServices } from "~/services/services";
+import { ApiActions } from "~/services/api/api-actions";
+import { mockConfig } from "~/common/config";
+import { authActions } from "./auth-action";
+import { API_TOKEN_KEY } from '~/services/auth-service/auth-service';
+
+describe("AuthMiddleware", () => {
+    let store: RootStore;
+    let services: ServiceRepository;
+    let axiosInst: AxiosInstance;
+    const actions: ApiActions = {
+        progressFn: (id: string, working: boolean) => { },
+        errorFn: (id: string, message: string) => { }
+    };
+
+    beforeEach(() => {
+        axiosInst = Axios.create({ headers: {} });
+        services = createServices(mockConfig({}), actions, axiosInst);
+        store = configureStore(createBrowserHistory(), services);
+        localStorage.clear();
+    });
+
+    it("handles LOGOUT action", () => {
+        localStorage.setItem(API_TOKEN_KEY, 'someToken');
+        window.location.assign = jest.fn();
+        const next = jest.fn();
+        const middleware = authMiddleware(services)(store)(next);
+        middleware(authActions.LOGOUT({deleteLinkData: false}));
+        expect(window.location.assign).toBeCalledWith(
+            `/logout?return_to=${location.protocol}//${location.host}`
+        );
+        expect(localStorage.getItem(API_TOKEN_KEY)).toBeFalsy();
+    });
+});
\ No newline at end of file

commit d56a6b231e95cb9e512051b1dae5ac50f31ee6fe
Author: Lucas Di Pentima <lucas at di-pentima.com.ar>
Date:   Tue Sep 1 18:05:42 2020 -0300

    16679: Adds test on action dispatching when using the Logout menu item.
    
    Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas at di-pentima.com.ar>

diff --git a/src/store/auth/auth-action.ts b/src/store/auth/auth-action.ts
index 1060ec70..15fe3d4d 100644
--- a/src/store/auth/auth-action.ts
+++ b/src/store/auth/auth-action.ts
@@ -97,8 +97,8 @@ export const login = (uuidPrefix: string, homeCluster: string, loginCluster: str
         dispatch(authActions.LOGIN());
     };
 
-export const logout = (deleteLinkData: boolean = false) => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-    dispatch(authActions.LOGOUT({ deleteLinkData }));
-};
+export const logout = (deleteLinkData: boolean = false) =>
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) =>
+        dispatch(authActions.LOGOUT({ deleteLinkData }));
 
 export type AuthAction = UnionOf<typeof authActions>;
diff --git a/src/views-components/main-app-bar/account-menu.test.tsx b/src/views-components/main-app-bar/account-menu.test.tsx
new file mode 100644
index 00000000..4436f6a3
--- /dev/null
+++ b/src/views-components/main-app-bar/account-menu.test.tsx
@@ -0,0 +1,51 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import * as Adapter from 'enzyme-adapter-react-16';
+import {configure, shallow } from 'enzyme';
+
+import { AccountMenuComponent } from './account-menu';
+
+configure({ adapter: new Adapter() });
+
+describe('<AccountMenu />', () => {
+    let props;
+    let wrapper;
+
+    beforeEach(() => {
+      props = {
+        classes: {},
+        user: {
+            email: 'email at example.com',
+            firstName: 'User',
+            lastName: 'Test',
+            uuid: 'zzzzz-tpzed-testuseruuid',
+            ownerUuid: '',
+            username: 'testuser',
+            prefs: {},
+            isAdmin: false,
+            isActive: true
+        },
+        currentRoute: '',
+        workbenchURL: '',
+        localCluser: 'zzzzz',
+        dispatch: jest.fn(),
+      };
+    });
+
+    describe('Logout Menu Item', () => {
+        beforeEach(() => {
+            wrapper = shallow(<AccountMenuComponent {...props} />).dive();
+        });
+
+        it('should dispatch a logout action when clicked', () => {
+            wrapper.find('[data-cy="logout-menuitem"]').simulate('click');
+            expect(props.dispatch).toHaveBeenCalledWith({
+                payload: {deleteLinkData: true},
+                type: 'LOGOUT',
+            });
+        });
+    });
+});
diff --git a/src/views-components/main-app-bar/account-menu.tsx b/src/views-components/main-app-bar/account-menu.tsx
index 37702536..6e844cc8 100644
--- a/src/views-components/main-app-bar/account-menu.tsx
+++ b/src/views-components/main-app-bar/account-menu.tsx
@@ -9,7 +9,7 @@ import { User, getUserDisplayName } from "~/models/user";
 import { DropdownMenu } from "~/components/dropdown-menu/dropdown-menu";
 import { UserPanelIcon } from "~/components/icon/icon";
 import { DispatchProp, connect } from 'react-redux';
-import { logout } from '~/store/auth/auth-action';
+import { authActions } from '~/store/auth/auth-action';
 import { RootState } from "~/store/store";
 import { openCurrentTokenDialog } from '~/store/current-token-dialog/current-token-dialog-actions';
 import { openRepositoriesPanel } from "~/store/repositories/repositories-actions";
@@ -56,32 +56,36 @@ const styles: StyleRulesCallback<CssRules> = () => ({
     }
 });
 
-export const AccountMenu = withStyles(styles)(
-    connect(mapStateToProps)(
-        ({ user, dispatch, currentRoute, workbenchURL, apiToken, localCluster, classes }: AccountMenuProps & DispatchProp<any> & WithStyles<CssRules>) =>
-            user
-                ? <DropdownMenu
-                    icon={<UserPanelIcon />}
-                    id="account-menu"
-                    title="Account Management"
-                    key={currentRoute}>
-                    <MenuItem disabled>
-                        {getUserDisplayName(user)} {user.uuid.substr(0, 5) !== localCluster && `(${user.uuid.substr(0, 5)})`}
-                    </MenuItem>
-                    {user.isActive ? <>
-                        <MenuItem onClick={() => dispatch(openUserVirtualMachines())}>Virtual Machines</MenuItem>
-                        {!user.isAdmin && <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</MenuItem>}
-                        <MenuItem onClick={() => dispatch(openCurrentTokenDialog)}>Current token</MenuItem>
-                        <MenuItem onClick={() => dispatch(navigateToSshKeysUser)}>Ssh Keys</MenuItem>
-                        <MenuItem onClick={() => dispatch(navigateToSiteManager)}>Site Manager</MenuItem>
-                        <MenuItem onClick={() => dispatch(navigateToMyAccount)}>My account</MenuItem>
-                        <MenuItem onClick={() => dispatch(navigateToLinkAccount)}>Link account</MenuItem>
-                    </> : null}
-                    <MenuItem>
-                        <a href={`${workbenchURL.replace(/\/$/, "")}/${wb1URL(currentRoute)}?api_token=${apiToken}`}
-                            className={classes.link}>
-                            Switch to Workbench v1</a></MenuItem>
-                    <Divider />
-                    <MenuItem onClick={() => dispatch(logout(true))}>Logout</MenuItem>
-                </DropdownMenu>
-                : null));
+export const AccountMenuComponent =
+    ({ user, dispatch, currentRoute, workbenchURL, apiToken, localCluster, classes }: AccountMenuProps & DispatchProp<any> & WithStyles<CssRules>) =>
+        user
+        ? <DropdownMenu
+            icon={<UserPanelIcon />}
+            id="account-menu"
+            title="Account Management"
+            key={currentRoute}>
+            <MenuItem disabled>
+                {getUserDisplayName(user)} {user.uuid.substr(0, 5) !== localCluster && `(${user.uuid.substr(0, 5)})`}
+            </MenuItem>
+            {user.isActive ? <>
+                <MenuItem onClick={() => dispatch(openUserVirtualMachines())}>Virtual Machines</MenuItem>
+                {!user.isAdmin && <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</MenuItem>}
+                <MenuItem onClick={() => dispatch(openCurrentTokenDialog)}>Current token</MenuItem>
+                <MenuItem onClick={() => dispatch(navigateToSshKeysUser)}>Ssh Keys</MenuItem>
+                <MenuItem onClick={() => dispatch(navigateToSiteManager)}>Site Manager</MenuItem>
+                <MenuItem onClick={() => dispatch(navigateToMyAccount)}>My account</MenuItem>
+                <MenuItem onClick={() => dispatch(navigateToLinkAccount)}>Link account</MenuItem>
+            </> : null}
+            <MenuItem>
+                <a href={`${workbenchURL.replace(/\/$/, "")}/${wb1URL(currentRoute)}?api_token=${apiToken}`}
+                    className={classes.link}>
+                    Switch to Workbench v1</a></MenuItem>
+            <Divider />
+            <MenuItem data-cy="logout-menuitem"
+                onClick={() => dispatch(authActions.LOGOUT({deleteLinkData: true}))}>
+                Logout
+            </MenuItem>
+        </DropdownMenu>
+        : null;
+
+export const AccountMenu = withStyles(styles)( connect(mapStateToProps)(AccountMenuComponent) );

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list