Merge branch '22155-layout-bugs'
[arvados.git] / services / workbench2 / cypress / e2e / auth-action.cy.js
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 // import { getNewExtraToken, initAuth } from "../../src/store/auth/auth-action";
6 import { API_TOKEN_KEY } from 'services/auth-service/auth-service';
7
8 // import 'jest-localstorage-mock';
9 // import { ServiceRepository, createServices } from "services/services";
10 // import { configureStore, RootStore } from "../../src/store/store"; //causes tuppy failure
11 // import { createBrowserHistory } from "history";
12 // import { mockConfig } from 'common/config';
13 // import { ApiActions } from "services/api/api-actions";
14 import { ACCOUNT_LINK_STATUS_KEY } from 'services/link-account-service/link-account-service';
15 import Axios, { AxiosInstance } from 'axios';
16 // import MockAdapter from "axios-mock-adapter";
17 // import { ImportMock } from 'ts-mock-imports';
18 // import * as servicesModule from "services/services";
19 // import * as authActionSessionModule from "../../src/store/auth/auth-action-session";
20 // import { SessionStatus } from "models/session";
21 import { getRemoteHostConfig } from '../../src/store/auth/auth-action-session';
22
23 describe('auth-actions', () => {
24     // let axiosInst;
25     // let axiosMock;
26
27     // let store;
28     // let services;
29     // const config = {};
30     // const actions = {
31     //     progressFn: (id, working) => { },
32     //     errorFn: (id, message) => { }
33     // };
34     // let importMocks;
35
36     const localClusterTokenExpiration = '2020-01-01T00:00:00.000Z';
37     const loginClusterTokenExpiration = '2140-01-01T00:00:00.000Z';
38
39     let activeUser;
40     let adminUser;
41
42     before(function () {
43         // Only set up common users once. These aren't set up as aliases because
44         // aliases are cleaned up after every test. Also it doesn't make sense
45         // to set the same users on beforeEach() over and over again, so we
46         // separate a little from Cypress' 'Best Practices' here.
47         cy.getUser('admin', 'Admin', 'User', true, true)
48             .as('adminUser')
49             .then(function () {
50                 adminUser = this.adminUser;
51             });
52         cy.getUser('user', 'Active', 'User', false, true)
53             .as('activeUser')
54             .then(function () {
55                 activeUser = this.activeUser;
56             });
57     });
58
59     it('creates an extra token', () => {
60         let firstToken;
61         let firstExtraToken;
62
63         cy.loginAs(activeUser);
64         cy.waitForDom();
65         cy.waitForLocalStorage('arvadosStore').then((storedStore) => {
66             const store = JSON.parse(storedStore);
67
68             //check that no extra token was requested
69             expect(store.auth.apiToken).to.not.be.undefined;
70             expect(store.auth.extraApiToken).to.be.undefined;
71             firstToken = store.auth.apiToken;
72         });
73
74         //ask for an extra token
75         cy.get('[aria-label="Account Management"]').click();
76         cy.contains('Get API token').click();
77         cy.contains('GET NEW TOKEN').click();
78         cy.waitForLocalStorage('arvadosStore').then((storedStore) => {
79             const store = JSON.parse(storedStore);
80
81             // check that cached token is used
82             expect(store.auth.apiToken).to.equal(firstToken);
83             cy.waitForLocalStorageUpdate('arvadosStore');
84
85             //check that an extra token was requested
86             expect(store.auth.extraApiToken).to.not.be.undefined;
87             firstExtraToken = store.auth.extraApiToken;
88         });
89         //check that another request generates a new token
90         cy.contains('GET NEW TOKEN').click();
91         cy.waitForLocalStorageUpdate('arvadosStore');
92         cy.waitForLocalStorage('arvadosStore').then((storedStore) => {
93             const store = JSON.parse(storedStore);
94
95             expect(store.auth.apiToken).to.not.be.undefined;
96             expect(store.auth.extraApiToken).to.not.be.undefined;
97             expect(store.auth.extraApiToken).to.not.equal(firstExtraToken);
98         });
99     });
100
101     it('requests remote token and token expiration', () => {
102         cy.loginAs(adminUser);
103         cy.waitForLocalStorage('arvadosStore').then((storedStore) => {
104             const store = JSON.parse(storedStore);
105
106             // verify that the token is cached
107             expect(store.auth.apiToken).to.not.be.undefined;
108             expect(localClusterTokenExpiration).to.not.equal(loginClusterTokenExpiration);
109
110             const now = new Date();
111             const expiration = new Date(store.auth.apiTokenExpiration);
112             const expectedExpiration = new Date(now.getTime() + 24 * 60 * 60 * 1000 + 2000);
113             const timeDiff = Math.abs(expectedExpiration.getMilliseconds() - expiration.getMilliseconds());
114
115             // verify that the token expiration is ~24 hours from now (with a 2 second buffer)
116             expect(timeDiff).to.be.lessThan(2000);
117         });
118     });
119
120     //TODO: finish this test, maybe convert back to component test?
121
122     // it('should initialise state with user and api token from local storage', () => {
123     //     let apiToken;
124     //     cy.loginAs(activeUser);
125
126     //     cy.waitForLocalStorage('apiToken').then((storedToken) => {
127     //         apiToken = storedToken;
128
129     //         // logout
130     //         cy.get('[aria-label="Account Management"]').click();
131     //         cy.get('[data-cy=logout-menuitem]').click();
132
133     //         // verify logout
134     //         cy.window().then((win) => {
135     //             cy.contains('Please log in.').should('exist');
136     //             expect(win.localStorage.getItem('apiToken')).to.be.null;
137     //         });
138     //     });
139
140     //     cy.visit('/');
141     //     cy.waitForLocalStorage('arvadosStore').then((storedStore) => {
142     //         const store = JSON.parse(storedStore);
143     //         console.log(store);
144     //         const auth = store.auth;
145     //         console.log(JSON.stringify(auth.user));
146     //         expect(auth.user).to.deep.equal({
147     //             email: 'user@example.local',
148     //             firstName: 'Active',
149     //             lastName: 'User',
150     //             uuid: 'zzzzz-tpzed-wlme7goukc5495r',
151     //             ownerUuid: 'zzzzz-tpzed-000000000000000',
152     //             isAdmin: false,
153     //             isActive: true,
154     //             username: 'user',
155     //             canWrite: true,
156     //             canManage: true,
157     //             prefs: { profile: {} },
158     //         });
159     //     });
160     // });
161
162     // TODO: Add remaining action tests
163     /*
164        it('should fire external url to login', () => {
165        const initialState = undefined;
166        window.location.assign = jest.fn();
167        reducer(initialState, authActions.LOGIN());
168        expect(window.location.assign).toBeCalledWith(
169        `/login?return_to=${window.location.protocol}//${window.location.host}/token`
170        );
171        });
172
173        it('should fire external url to logout', () => {
174        const initialState = undefined;
175        window.location.assign = jest.fn();
176        reducer(initialState, authActions.LOGOUT());
177        expect(window.location.assign).toBeCalledWith(
178        `/logout?return_to=${location.protocol}//${location.host}`
179        );
180        });
181      */
182 });