| <!DOCTYPE html> |
| <!-- |
| Copyright 2018 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> |
| <title>auth.js tests</title> |
| |
| <script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script> |
| <script src="../node_modules/web-component-tester/browser.js"></script> |
| <script id="platformJs" src="https://apis.google.com/js/platform.js"></script> |
| |
| <script type="module"> |
| import {assertRejects} from './test-util.js'; |
| import {Authenticator, initAuth, getAccessToken, resetAuthState} from '../src/main/resources/static/auth.js'; |
| |
| const platformJsElement = document.getElementById('platformJs'); |
| |
| suite('auth', () => { |
| let sandbox; |
| let authenticator; |
| let token; |
| |
| setup(() => { |
| sandbox = sinon.sandbox.create({}); |
| token = { |
| access_token: 'token', |
| expires_at: Date.now() + 60e3, |
| }; |
| |
| sandbox.stub(window, 'gapi', { |
| auth2: { |
| authorize: (opt, resolve) => resolve(token), |
| }, |
| }); |
| |
| authenticator = new Authenticator({ |
| client_id: 'client-id', |
| email: 'jane@example.com', |
| }); |
| }); |
| |
| teardown(() => { |
| sandbox.restore(); |
| }); |
| |
| test('getToken returns expected token object', async () => { |
| const actualToken = await authenticator.getToken(); |
| assert.equal(actualToken, token); |
| }); |
| |
| test('getToken rejects when there is no access_token', async () => { |
| token.access_token = null; |
| assertRejects(authenticator.getToken()); |
| }); |
| |
| test('getToken rejects if there is an error', async () => { |
| token.error = 'bad'; |
| assertRejects(authenticator.getToken(), 'bad'); |
| }); |
| |
| test('getToken rejects when token has no expiry date', async () => { |
| token.expires_at = null; |
| assertRejects(authenticator.getToken()); |
| }); |
| |
| test('getToken rejects when token is expired', async () => { |
| token.access_token = 1543620640; |
| assertRejects(authenticator.getToken()); |
| }); |
| |
| test('getToken rejects when authorize times out', async () => { |
| const forever = new Promise(() => {}); |
| sandbox.stub(gapi.auth2, 'authorize', forever); |
| assertRejects(authenticator.getToken(), 'timeout'); |
| }); |
| |
| test('getToken uses cached token', async () => { |
| sandbox.spy(gapi.auth2, 'authorize'); |
| const actualToken1 = await authenticator.getToken(); |
| const actualToken2 = await authenticator.getToken(); |
| assert.isTrue(gapi.auth2.authorize.calledOnce); |
| assert.equal(actualToken1, token); |
| assert.equal(actualToken2, token); |
| }); |
| |
| test('getToken uses cached token for two async calls', async () => { |
| sandbox.spy(gapi.auth2, 'authorize'); |
| const [actualToken1, actualToken2] = await Promise.all([ |
| authenticator.getToken(), |
| authenticator.getToken(), |
| ]); |
| assert.equal(actualToken1, token); |
| assert.equal(actualToken2, token); |
| assert.isTrue(gapi.auth2.authorize.calledOnce); |
| }); |
| }); |
| |
| suite('initAuth', () => { |
| let sandbox; |
| let plugin; |
| let loggedIn; |
| let cfg; |
| const accessToken = 'token'; |
| |
| setup(() => { |
| sandbox = sinon.sandbox.create({ |
| useFakeTimers: [1543620642, 'Date'], |
| }); |
| |
| loggedIn = true; |
| cfg = {}; |
| plugin = { |
| restApi: () => ({ |
| getLoggedIn: async () => loggedIn, |
| get: async (url) => cfg, |
| }), |
| }; |
| |
| sandbox.stub(window, 'gapi', { |
| auth2: { |
| init: (resolve) => resolve(), |
| }, |
| config: { |
| get: () => null, |
| update: () => {}, |
| }, |
| load: (modules, resolve) => resolve(), |
| }); |
| |
| sandbox.stub(Authenticator.prototype, 'getToken', () => ({ |
| access_token: accessToken, |
| })); |
| }); |
| |
| teardown(() => { |
| sandbox.restore(); |
| resetAuthState(); |
| }); |
| |
| test('initAuth sets access token which can then be gotten', async () => { |
| initAuth(plugin, platformJsElement); |
| const actualAccessToken = await getAccessToken(); |
| assert.equal(actualAccessToken, accessToken); |
| }); |
| |
| test('initAuth throws if called twice', async () => { |
| initAuth(plugin, platformJsElement); |
| assert.throws( |
| () => initAuth(plugin, platformJsElement), 'initAuth is called more than once'); |
| }); |
| |
| test('getAccessToken rejects if called before init', async () => { |
| assertRejects(getAccessToken(), 'initAuth was not called'); |
| }); |
| |
| test('initAuth sets up gapi', async () => { |
| sandbox.spy(gapi.config, 'update'); |
| sandbox.spy(gapi, 'load'); |
| cfg = { |
| auth_url: 'https://example.com/auth', |
| proxy_url: 'https://example.com/proxy', |
| }; |
| initAuth(plugin, platformJsElement); |
| await getAccessToken(); |
| |
| assert.isTrue( |
| gapi.config.update.calledWith('oauth-flow/authUrl', cfg.auth_url)); |
| assert.isTrue( |
| gapi.config.update.calledWith('oauth-flow/proxyUrl', cfg.proxy_url)); |
| |
| // `auth` must be loaded after config is updated. |
| assert.isTrue( |
| gapi.load.withArgs('auth2', sinon.match.any) |
| .calledAfter(gapi.config.update)); |
| }); |
| }); |
| </script> |