1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 // import { getNewExtraToken, initAuth } from "../../src/store/auth/auth-action";
6 import { API_TOKEN_KEY } from 'services/auth-service/auth-service';
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';
23 describe('auth-actions', () => {
31 // progressFn: (id, working) => { },
32 // errorFn: (id, message) => { }
36 const localClusterTokenExpiration = '2020-01-01T00:00:00.000Z';
37 const loginClusterTokenExpiration = '2140-01-01T00:00:00.000Z';
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)
50 adminUser = this.adminUser;
52 cy.getUser('user', 'Active', 'User', false, true)
55 activeUser = this.activeUser;
59 it('creates an extra token', () => {
63 cy.loginAs(activeUser);
65 cy.waitForLocalStorage('arvadosStore').then((storedStore) => {
66 const store = JSON.parse(storedStore);
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;
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);
81 // check that cached token is used
82 expect(store.auth.apiToken).to.equal(firstToken);
83 cy.waitForLocalStorageUpdate('arvadosStore');
85 //check that an extra token was requested
86 expect(store.auth.extraApiToken).to.not.be.undefined;
87 firstExtraToken = store.auth.extraApiToken;
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);
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);
101 it('requests remote token and token expiration', () => {
102 cy.loginAs(adminUser);
103 cy.waitForLocalStorage('arvadosStore').then((storedStore) => {
104 const store = JSON.parse(storedStore);
106 // verify that the token is cached
107 expect(store.auth.apiToken).to.not.be.undefined;
108 expect(localClusterTokenExpiration).to.not.equal(loginClusterTokenExpiration);
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());
115 // verify that the token expiration is ~24 hours from now (with a 2 second buffer)
116 expect(timeDiff).to.be.lessThan(2000);
120 //TODO: finish this test, maybe convert back to component test?
122 // it('should initialise state with user and api token from local storage', () => {
124 // cy.loginAs(activeUser);
126 // cy.waitForLocalStorage('apiToken').then((storedToken) => {
127 // apiToken = storedToken;
130 // cy.get('[aria-label="Account Management"]').click();
131 // cy.get('[data-cy=logout-menuitem]').click();
134 // cy.window().then((win) => {
135 // cy.contains('Please log in.').should('exist');
136 // expect(win.localStorage.getItem('apiToken')).to.be.null;
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',
150 // uuid: 'zzzzz-tpzed-wlme7goukc5495r',
151 // ownerUuid: 'zzzzz-tpzed-000000000000000',
157 // prefs: { profile: {} },
162 // TODO: Add remaining action tests
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`
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}`