diff options
Diffstat (limited to 'polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html')
-rw-r--r-- | polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html new file mode 100644 index 0000000000..c254e62c72 --- /dev/null +++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html @@ -0,0 +1,186 @@ +<!DOCTYPE html> +<!-- +Copyright (C) 2017 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> +<title>gr-auth</title> + +<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> +<script src="../../../bower_components/web-component-tester/browser.js"></script> +<link rel="import" href="../../../test/common-test-setup.html"/> +<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html"> + +<script src="gr-auth.js"></script> + +<script> + suite('gr-auth', () => { + let auth; + let sandbox; + + setup(() => { + sandbox = sinon.sandbox.create(); + sandbox.stub(window, 'fetch').returns(Promise.resolve({ok: true})); + auth = Gerrit.Auth; + }); + + teardown(() => { + sandbox.restore(); + }); + + suite('default (xsrf token header)', () => { + test('GET', () => { + return auth.fetch('/url', {bar: 'bar'}).then(() => { + const [url, options] = fetch.lastCall.args; + assert.equal(url, '/url'); + assert.equal(options.credentials, 'same-origin'); + }); + }); + + test('POST', () => { + sandbox.stub(auth, '_getCookie') + .withArgs('XSRF_TOKEN') + .returns('foobar'); + return auth.fetch('/url', {method: 'POST'}).then(() => { + const [url, options] = fetch.lastCall.args; + assert.equal(url, '/url'); + assert.equal(options.credentials, 'same-origin'); + assert.equal(options.headers.get('X-Gerrit-Auth'), 'foobar'); + }); + }); + }); + + suite('cors (access token)', () => { + let getToken; + + const makeToken = opt_accessToken => { + return { + access_token: opt_accessToken || 'zbaz', + expires_at: new Date(Date.now() + 10e8).getTime(), + }; + }; + + setup(() => { + getToken = sandbox.stub(); + getToken.returns(Promise.resolve(makeToken())); + auth.setup(getToken); + }); + + test('base url support', () => { + const baseUrl = 'http://foo'; + sandbox.stub(Gerrit.BaseUrlBehavior, 'getBaseUrl').returns(baseUrl); + return auth.fetch(baseUrl + '/url', {bar: 'bar'}).then(() => { + const [url] = fetch.lastCall.args; + assert.equal(url, 'http://foo/a/url?access_token=zbaz'); + }); + }); + + test('fetch not signed in', () => { + getToken.returns(Promise.resolve()); + return auth.fetch('/url', {bar: 'bar'}).then(() => { + const [url, options] = fetch.lastCall.args; + assert.equal(url, '/url'); + assert.equal(options.bar, 'bar'); + assert.equal(Object.keys(options.headers).length, 0); + }); + }); + + test('fetch signed in', () => { + return auth.fetch('/url', {bar: 'bar'}).then(() => { + const [url, options] = fetch.lastCall.args; + assert.equal(url, '/a/url?access_token=zbaz'); + assert.equal(options.bar, 'bar'); + }); + }); + + test('getToken calls are cached', () => { + return Promise.all([ + auth.fetch('/url-one'), auth.fetch('/url-two')]).then(() => { + assert.equal(getToken.callCount, 1); + }); + }); + + test('getToken refreshes token', () => { + sandbox.stub(auth, '_isTokenValid'); + auth._isTokenValid + .onFirstCall().returns(true) + .onSecondCall().returns(false) + .onThirdCall().returns(true); + return auth.fetch('/url-one').then(() => { + getToken.returns(Promise.resolve(makeToken('bzzbb'))); + return auth.fetch('/url-two'); + }).then(() => { + const [[firstUrl], [secondUrl]] = fetch.args; + assert.equal(firstUrl, '/a/url-one?access_token=zbaz'); + assert.equal(secondUrl, '/a/url-two?access_token=bzzbb'); + }); + }); + + test('signed in token error falls back to anonymous', () => { + getToken.returns(Promise.resolve('rubbish')); + return auth.fetch('/url', {bar: 'bar'}).then(() => { + const [url, options] = fetch.lastCall.args; + assert.equal(url, '/url'); + assert.equal(options.bar, 'bar'); + }); + }); + + test('_isTokenValid', () => { + assert.isFalse(auth._isTokenValid()); + assert.isFalse(auth._isTokenValid({})); + assert.isFalse(auth._isTokenValid({access_token: 'foo'})); + assert.isFalse(auth._isTokenValid({ + access_token: 'foo', + expires_at: Date.now()/1000 - 1, + })); + assert.isTrue(auth._isTokenValid({ + access_token: 'foo', + expires_at: Date.now()/1000 + 1, + })); + }); + + test('HTTP PUT with content type', () => { + const originalOptions = { + method: 'PUT', + headers: new Headers({'Content-Type': 'mail/pigeon'}), + }; + return auth.fetch('/url', originalOptions).then(() => { + assert.isTrue(getToken.called); + const [url, options] = fetch.lastCall.args; + assert.include(url, '$ct=mail%2Fpigeon'); + assert.include(url, '$m=PUT'); + assert.include(url, 'access_token=zbaz'); + assert.equal(options.method, 'POST'); + assert.equal(options.headers.get('Content-Type'), 'text/plain'); + }); + }); + + test('HTTP PUT without content type', () => { + const originalOptions = { + method: 'PUT', + }; + return auth.fetch('/url', originalOptions).then(() => { + assert.isTrue(getToken.called); + const [url, options] = fetch.lastCall.args; + assert.include(url, '$ct=text%2Fplain'); + assert.include(url, '$m=PUT'); + assert.include(url, 'access_token=zbaz'); + assert.equal(options.method, 'POST'); + assert.equal(options.headers.get('Content-Type'), 'text/plain'); + }); + }); + }); + }); +</script> |