Merge changes Ic7a5a3f9,I6d6da523,I6c88e9fd
* changes: Support for faster Gerrit CORS Add auth provider for GAPI OAUTH2 and tests Extract auth logic from gr-rest-api-interface
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
// 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.
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
// Prevent redefinition.
|
||||
if (window.GrGapiAuth) { return; }
|
||||
|
||||
const EMAIL_SCOPE = 'email';
|
||||
|
||||
function GrGapiAuth() {}
|
||||
|
||||
GrGapiAuth._loadGapiPromise = null;
|
||||
GrGapiAuth._setupPromise = null;
|
||||
GrGapiAuth._refreshTokenPromise = null;
|
||||
GrGapiAuth._sharedAuthToken = null;
|
||||
GrGapiAuth._oauthClientId = null;
|
||||
GrGapiAuth._oauthEmail = null;
|
||||
|
||||
GrGapiAuth.prototype.fetch = function(url, options) {
|
||||
options = Object.assign({}, options);
|
||||
return this._getAccessToken().then(
|
||||
token => window.FASTER_GERRIT_CORS ?
|
||||
this._fasterGerritCors(url, options, token) :
|
||||
this._defaultFetch(url, options, token)
|
||||
);
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._defaultFetch = function(url, options, token) {
|
||||
if (token) {
|
||||
options.headers = options.headers || new Headers();
|
||||
options.headers.append('Authorization', `Bearer ${token}`);
|
||||
if (!url.startsWith('/a/')) {
|
||||
url = '/a' + url;
|
||||
}
|
||||
}
|
||||
return fetch(url, options);
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._fasterGerritCors = function(url, options, token) {
|
||||
const method = options.method || 'GET';
|
||||
if (method === 'GET') {
|
||||
return fetch(url, options);
|
||||
}
|
||||
const params = [];
|
||||
if (token) {
|
||||
params.push(`access_token=${token}`);
|
||||
}
|
||||
const contentType = options.headers && options.headers.get('Content-Type');
|
||||
if (contentType) {
|
||||
options.headers.set('Content-Type', 'text/plain');
|
||||
params.push(`$ct=${encodeURIComponent(contentType)}`);
|
||||
}
|
||||
params.push(`$m=${method}`);
|
||||
url = url + (url.indexOf('?') === -1 ? '?' : '') + params.join('&');
|
||||
options.method = 'POST';
|
||||
return fetch(url, options);
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._getAccessToken = function() {
|
||||
if (this._isTokenValid(GrGapiAuth._sharedAuthToken)) {
|
||||
return Promise.resolve(GrGapiAuth._sharedAuthToken.access_token);
|
||||
}
|
||||
if (!GrGapiAuth._refreshTokenPromise) {
|
||||
GrGapiAuth._refreshTokenPromise = this._loadGapi()
|
||||
.then(() => this._configureOAuthLibrary())
|
||||
.then(() => this._refreshToken())
|
||||
.then(token => {
|
||||
GrGapiAuth._sharedAuthToken = token;
|
||||
GrGapiAuth._refreshTokenPromise = null;
|
||||
return this._getAccessToken();
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
return GrGapiAuth._refreshTokenPromise;
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._isTokenValid = function(token) {
|
||||
if (!token) { return false; }
|
||||
if (!token.access_token || !token.expires_at) { return false; }
|
||||
|
||||
const expiration = new Date(parseInt(token.expires_at, 10) * 1000);
|
||||
if (Date.now() >= expiration) { return false; }
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._loadGapi = function() {
|
||||
if (!GrGapiAuth._loadGapiPromise) {
|
||||
GrGapiAuth._loadGapiPromise = new Promise((resolve, reject) => {
|
||||
const scriptEl = document.createElement('script');
|
||||
scriptEl.defer = true;
|
||||
scriptEl.async = true;
|
||||
scriptEl.src = 'https://apis.google.com/js/platform.js';
|
||||
scriptEl.onerror = reject;
|
||||
scriptEl.onload = resolve;
|
||||
document.body.appendChild(scriptEl);
|
||||
});
|
||||
}
|
||||
return GrGapiAuth._loadGapiPromise;
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._configureOAuthLibrary = function() {
|
||||
if (!GrGapiAuth._setupPromise) {
|
||||
GrGapiAuth._setupPromise = new Promise(
|
||||
resolve => gapi.load('config_min', resolve)
|
||||
)
|
||||
.then(() => this._getOAuthConfig())
|
||||
.then(config => {
|
||||
if (config.hasOwnProperty('auth_url') && config.auth_url) {
|
||||
gapi.config.update('oauth-flow/authUrl', config.auth_url);
|
||||
}
|
||||
if (config.hasOwnProperty('proxy_url') && config.proxy_url) {
|
||||
gapi.config.update('oauth-flow/proxyUrl', config.proxy_url);
|
||||
}
|
||||
GrGapiAuth._oauthClientId = config.client_id;
|
||||
GrGapiAuth._oauthEmail = config.email;
|
||||
|
||||
// Loading auth has a side-effect. The URLs should be set before
|
||||
// loading it.
|
||||
return new Promise(
|
||||
resolve => gapi.load('auth', () => gapi.auth.init(resolve))
|
||||
);
|
||||
});
|
||||
}
|
||||
return GrGapiAuth._setupPromise;
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._refreshToken = function() {
|
||||
const opts = {
|
||||
client_id: GrGapiAuth._oauthClientId,
|
||||
immediate: true,
|
||||
scope: EMAIL_SCOPE,
|
||||
login_hint: GrGapiAuth._oauthEmail,
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
gapi.auth.authorize(opts, token => {
|
||||
if (!token) {
|
||||
reject('No token returned');
|
||||
} else if (token.error) {
|
||||
reject(token.error);
|
||||
} else {
|
||||
resolve(token);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._getOAuthConfig = function() {
|
||||
const authConfigURL = '/accounts/self/oauthconfig';
|
||||
const opts = {
|
||||
headers: new Headers({Accept: 'application/json'}),
|
||||
credentials: 'same-origin',
|
||||
};
|
||||
return fetch(authConfigURL, opts).then(response => {
|
||||
if (!response.ok) {
|
||||
console.error(response.statusText);
|
||||
if (response.body && response.body.then) {
|
||||
return response.body.then(text => {
|
||||
return Promise.reject(text);
|
||||
});
|
||||
}
|
||||
if (response.statusText) {
|
||||
return Promise.reject(response.statusText);
|
||||
} else {
|
||||
return Promise.reject('_getOAuthConfig' + response.status);
|
||||
}
|
||||
}
|
||||
return this._getResponseObject(response);
|
||||
});
|
||||
};
|
||||
|
||||
GrGapiAuth.prototype._getResponseObject = function(response) {
|
||||
const JSON_PREFIX = ')]}\'';
|
||||
return response.text().then(text => {
|
||||
return JSON.parse(text.substring(JSON_PREFIX.length));
|
||||
});
|
||||
},
|
||||
|
||||
window.GrGapiAuth = GrGapiAuth;
|
||||
})(window);
|
||||
@@ -0,0 +1,199 @@
|
||||
<!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-gapi-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"/>
|
||||
|
||||
<script src="gr-gapi-auth.js"></script>
|
||||
|
||||
<script>
|
||||
suite('gr-rest-api-interface tests', () => {
|
||||
let auth;
|
||||
let sandbox;
|
||||
|
||||
setup(() => {
|
||||
sandbox = sinon.sandbox.create();
|
||||
auth = new GrGapiAuth();
|
||||
window.gapi = {
|
||||
load: sandbox.stub().callsArg(1),
|
||||
config: {
|
||||
update: sandbox.stub(),
|
||||
},
|
||||
auth: {
|
||||
init: sandbox.stub().callsArg(0),
|
||||
authorize: sandbox.stub(),
|
||||
},
|
||||
};
|
||||
sandbox.stub(window, 'fetch').returns(Promise.resolve());
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
delete window.gapi;
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('exists', () => {
|
||||
assert.isOk(auth);
|
||||
});
|
||||
|
||||
test('fetch signed in', () => {
|
||||
sandbox.stub(auth, '_getAccessToken').returns(Promise.resolve('foo'));
|
||||
return auth.fetch('/url', {bar: 'bar'}).then(() => {
|
||||
assert.isTrue(auth._getAccessToken.called);
|
||||
const [url, options] = fetch.lastCall.args;
|
||||
assert.equal(url, '/a/url');
|
||||
assert.equal(options.bar, 'bar');
|
||||
assert.equal(options.headers.get('Authorization'), 'Bearer foo');
|
||||
});
|
||||
});
|
||||
|
||||
test('fetch not signed in', () => {
|
||||
sandbox.stub(auth, '_getAccessToken').returns(Promise.resolve());
|
||||
return auth.fetch('/url', {bar: 'bar'}).then(() => {
|
||||
assert.isTrue(auth._getAccessToken.called);
|
||||
const [url, options] = fetch.lastCall.args;
|
||||
assert.equal(url, '/url');
|
||||
assert.equal(options.bar, 'bar');
|
||||
assert.isUndefined(options.headers);
|
||||
});
|
||||
});
|
||||
|
||||
test('_getAccessToken returns valid shared token', () => {
|
||||
GrGapiAuth._sharedAuthToken = {access_token: 'foo'};
|
||||
sandbox.stub(auth, '_isTokenValid').returns(true);
|
||||
return auth._getAccessToken().then(token => {
|
||||
assert.equal(token, 'foo');
|
||||
});
|
||||
});
|
||||
|
||||
test('_getAccessToken refreshes token', () => {
|
||||
const token = {access_token: 'foo'};
|
||||
sandbox.stub(auth, '_loadGapi').returns(Promise.resolve());
|
||||
sandbox.stub(auth, '_configureOAuthLibrary').returns(Promise.resolve());
|
||||
sandbox.stub(auth, '_refreshToken').returns(Promise.resolve(token));
|
||||
sandbox.stub(auth, '_isTokenValid').returns(true)
|
||||
.onFirstCall().returns(false);
|
||||
return auth._getAccessToken().then(token => {
|
||||
assert.isTrue(auth._loadGapi.called);
|
||||
assert.isTrue(auth._configureOAuthLibrary.called);
|
||||
assert.isTrue(auth._refreshToken.called);
|
||||
assert.equal(token, 'foo');
|
||||
});
|
||||
});
|
||||
|
||||
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('_configureOAuthLibrary', () => {
|
||||
sandbox.stub(auth, '_getOAuthConfig').returns({
|
||||
auth_url: 'some_auth_url',
|
||||
proxy_url: 'some_proxy_url',
|
||||
client_id: 'some_client_id',
|
||||
email: 'some_email',
|
||||
});
|
||||
return auth._configureOAuthLibrary().then(() => {
|
||||
assert.isTrue(gapi.load.calledWith('config_min'));
|
||||
assert.isTrue(auth._getOAuthConfig.called);
|
||||
assert.isTrue(gapi.config.update.calledWith(
|
||||
'oauth-flow/authUrl', 'some_auth_url'));
|
||||
assert.isTrue(gapi.config.update.calledWith(
|
||||
'oauth-flow/proxyUrl', 'some_proxy_url'));
|
||||
assert.equal(GrGapiAuth._oauthClientId, 'some_client_id');
|
||||
assert.equal(GrGapiAuth._oauthEmail, 'some_email');
|
||||
assert.isTrue(gapi.auth.init.called);
|
||||
assert.isTrue(gapi.load.calledWith('auth'));
|
||||
});
|
||||
});
|
||||
|
||||
test('_refreshToken no token', () => {
|
||||
gapi.auth.authorize.callsArgWith(1, null);
|
||||
return auth._refreshToken().catch(reason => {
|
||||
assert.equal(reason, 'No token returned');
|
||||
});
|
||||
});
|
||||
|
||||
test('_refreshToken error', () => {
|
||||
gapi.auth.authorize.callsArgWith(1, {error: 'some error'});
|
||||
return auth._refreshToken().catch(reason => {
|
||||
assert.equal(reason, 'some error');
|
||||
});
|
||||
});
|
||||
|
||||
test('_refreshToken', () => {
|
||||
const token = {};
|
||||
gapi.auth.authorize.callsArgWith(1, token);
|
||||
return auth._refreshToken().then(t => {
|
||||
assert.strictEqual(token, t);
|
||||
});
|
||||
});
|
||||
|
||||
test('_getOAuthConfig', () => {
|
||||
const config = {};
|
||||
fetch.returns(Promise.resolve({ok: true}));
|
||||
sandbox.stub(auth, '_getResponseObject').returns(config);
|
||||
return auth._getOAuthConfig().then(c => {
|
||||
const [url, options] = fetch.lastCall.args;
|
||||
assert.equal(url, '/accounts/self/oauthconfig');
|
||||
assert.equal(options.credentials, 'same-origin');
|
||||
assert.equal(options.headers.get('Accept'), 'application/json');
|
||||
assert.strictEqual(c, config);
|
||||
});
|
||||
});
|
||||
|
||||
suite('faster gerrit cors', () => {
|
||||
setup(() => {
|
||||
window.FASTER_GERRIT_CORS = true;
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
delete window.FASTER_GERRIT_CORS;
|
||||
});
|
||||
|
||||
test('PUT works', () => {
|
||||
sandbox.stub(auth, '_getAccessToken').returns(Promise.resolve('foo'));
|
||||
const originalOptions = {
|
||||
method: 'PUT',
|
||||
headers: new Headers({'Content-Type': 'mail/pigeon'}),
|
||||
};
|
||||
return auth.fetch('/url', originalOptions).then(() => {
|
||||
assert.isTrue(auth._getAccessToken.called);
|
||||
const [url, options] = fetch.lastCall.args;
|
||||
assert.include(url, '$ct=mail%2Fpigeon');
|
||||
assert.include(url, '$m=PUT');
|
||||
assert.include(url, 'access_token=foo');
|
||||
assert.equal(options.method, 'POST');
|
||||
assert.equal(options.headers.get('Content-Type'), 'text/plain');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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.
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
// Prevent redefinition.
|
||||
if (window.GrGerritAuth) { return; }
|
||||
|
||||
function GrGerritAuth() {}
|
||||
|
||||
GrGerritAuth.prototype._getCookie = function(name) {
|
||||
const key = name + '=';
|
||||
let result = '';
|
||||
document.cookie.split(';').some(c => {
|
||||
c = c.trim();
|
||||
if (c.startsWith(key)) {
|
||||
result = c.substring(key.length);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
GrGerritAuth.prototype.fetch = function(url, opt_options) {
|
||||
const options = Object.assign({}, opt_options);
|
||||
if (options.method && options.method !== 'GET') {
|
||||
const token = this._getCookie('XSRF_TOKEN');
|
||||
if (token) {
|
||||
options.headers = options.headers || new Headers();
|
||||
options.headers.append('X-Gerrit-Auth', token);
|
||||
}
|
||||
}
|
||||
options.credentials = 'same-origin';
|
||||
return fetch(url, options);
|
||||
};
|
||||
|
||||
window.GrGerritAuth = GrGerritAuth;
|
||||
})(window);
|
||||
@@ -17,10 +17,14 @@ limitations under the License.
|
||||
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
|
||||
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<!-- NB: es6-promise Needed for IE11 and fetch polyfill support, see Issue 4308 -->
|
||||
<script src="../../../bower_components/es6-promise/dist/es6-promise.min.js"></script>
|
||||
<script src="../../../bower_components/fetch/fetch.js"></script>
|
||||
|
||||
<dom-module id="gr-rest-api-interface">
|
||||
<script src="gr-rest-api-interface.js"></script>
|
||||
<!-- NB: Order is important, because of namespaced classes. -->
|
||||
<script src="gr-gerrit-auth.js"></script>
|
||||
<script src="gr-gapi-auth.js"></script>
|
||||
<script src="gr-reviewer-updates-parser.js"></script>
|
||||
<script src="gr-rest-api-interface.js"></script>
|
||||
</dom-module>
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
SEND_DIFF_DRAFT: 'sendDiffDraft',
|
||||
};
|
||||
|
||||
let auth = null;
|
||||
|
||||
Polymer({
|
||||
is: 'gr-rest-api-interface',
|
||||
|
||||
@@ -62,20 +64,13 @@
|
||||
},
|
||||
},
|
||||
|
||||
fetchJSON(url, opt_errFn, opt_cancelCondition, opt_params,
|
||||
opt_opts) {
|
||||
opt_opts = opt_opts || {};
|
||||
// Issue 5715, This can be reverted back once
|
||||
// iOS 10.3 and mac os 10.12.4 has the fetch api fix.
|
||||
const fetchOptions = {
|
||||
credentials: 'same-origin',
|
||||
};
|
||||
if (opt_opts.headers !== undefined) {
|
||||
fetchOptions['headers'] = opt_opts.headers;
|
||||
}
|
||||
created() {
|
||||
auth = window.USE_GAPI_AUTH ? new GrGapiAuth() : new GrGerritAuth();
|
||||
},
|
||||
|
||||
fetchJSON(url, opt_errFn, opt_cancelCondition, opt_params) {
|
||||
const urlWithParams = this._urlWithParams(url, opt_params);
|
||||
return fetch(urlWithParams, fetchOptions).then(response => {
|
||||
return auth.fetch(urlWithParams).then(response => {
|
||||
if (opt_cancelCondition && opt_cancelCondition()) {
|
||||
response.body.cancel();
|
||||
return;
|
||||
@@ -716,22 +711,17 @@
|
||||
},
|
||||
|
||||
send(method, url, opt_body, opt_errFn, opt_ctx, opt_contentType) {
|
||||
const headers = new Headers({
|
||||
'X-Gerrit-Auth': this._getCookie('XSRF_TOKEN'),
|
||||
});
|
||||
const options = {
|
||||
method,
|
||||
headers,
|
||||
credentials: 'same-origin',
|
||||
};
|
||||
const options = {method};
|
||||
if (opt_body) {
|
||||
headers.append('Content-Type', opt_contentType || 'application/json');
|
||||
options.headers = new Headers({
|
||||
'Content-Type': opt_contentType || 'application/json',
|
||||
});
|
||||
if (typeof opt_body !== 'string') {
|
||||
opt_body = JSON.stringify(opt_body);
|
||||
}
|
||||
options.body = opt_body;
|
||||
}
|
||||
return fetch(this.getBaseUrl() + url, options).then(response => {
|
||||
return auth.fetch(this.getBaseUrl() + url, options).then(response => {
|
||||
if (!response.ok) {
|
||||
if (opt_errFn) {
|
||||
opt_errFn.call(opt_ctx || null, response);
|
||||
@@ -901,21 +891,6 @@
|
||||
});
|
||||
},
|
||||
|
||||
_getCookie(name) {
|
||||
const key = name + '=';
|
||||
const cookies = document.cookie.split(';');
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
let c = cookies[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.startsWith(key)) {
|
||||
return c.substring(key.length, c.length);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
getCommitInfo(project, commit) {
|
||||
return this.fetchJSON(
|
||||
'/projects/' + encodeURIComponent(project) +
|
||||
@@ -923,7 +898,7 @@
|
||||
},
|
||||
|
||||
_fetchB64File(url) {
|
||||
return fetch(this.getBaseUrl() + url, {credentials: 'same-origin'})
|
||||
return auth.fetch(this.getBaseUrl() + url)
|
||||
.then(response => {
|
||||
if (!response.ok) { return Promise.reject(response.statusText); }
|
||||
const type = response.headers.get('X-FYI-Content-Type');
|
||||
|
||||
@@ -658,5 +658,20 @@ limitations under the License.
|
||||
assert.isTrue(element._fetchSharedCacheURL.lastCall
|
||||
.calledWithExactly('/projects/?d&n=26&S=25&m=test'));
|
||||
});
|
||||
|
||||
test('gerrit auth is used by default', () => {
|
||||
sandbox.stub(GrGerritAuth.prototype, 'fetch').returns(Promise.resolve());
|
||||
element.fetchJSON('foo');
|
||||
assert(GrGerritAuth.prototype.fetch.called);
|
||||
});
|
||||
|
||||
test('gapi auth is enabled with USE_GAPI_AUTH', () => {
|
||||
window.USE_GAPI_AUTH = true;
|
||||
sandbox.stub(GrGapiAuth.prototype, 'fetch').returns(Promise.resolve());
|
||||
element = fixture('basic');
|
||||
element.fetchJSON('foo');
|
||||
assert(GrGapiAuth.prototype.fetch.called);
|
||||
delete window.USE_GAPI_AUTH;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -118,6 +118,7 @@ limitations under the License.
|
||||
'shared/gr-linked-chip/gr-linked-chip_test.html',
|
||||
'shared/gr-linked-text/gr-linked-text_test.html',
|
||||
'shared/gr-list-view/gr-list-view_test.html',
|
||||
'shared/gr-rest-api-interface/gr-gapi-auth_test.html',
|
||||
'shared/gr-rest-api-interface/gr-rest-api-interface_test.html',
|
||||
'shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html',
|
||||
'shared/gr-select/gr-select_test.html',
|
||||
|
||||
Reference in New Issue
Block a user