Merge "Auth alert should have the highest priority among all error alerts"
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
index 9ef2461..5a7e58d 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.js
@@ -178,6 +178,8 @@
_showAlert(text, opt_actionText, opt_actionCallback,
opt_dismissOnNavigation) {
if (this._alertElement) {
+ // do not override auth alerts
+ if (this._alertElement.type === 'AUTH') return;
this._hideAlert();
}
@@ -212,10 +214,14 @@
}
_showAuthErrorAlert(errorText, actionText) {
- // TODO(viktard): close alert if it's not for auth error.
- if (this._alertElement) { return; }
+ // hide any existing alert like `reload`
+ // as auth error should have the highest priority
+ if (this._alertElement) {
+ this._alertElement.hide();
+ }
this._alertElement = this._createToastAlert();
+ this._alertElement.type = 'AUTH';
this._alertElement.show(errorText, actionText,
this._createLoginPopup.bind(this));
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
index a0a5731..72f5d5b 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
@@ -52,6 +52,7 @@
sandbox.stub(window, 'fetch')
.returns(Promise.resolve({ok: true, status: 204}));
element = fixture('basic');
+ element._authService.clearCache();
});
test('does not show auth error on 403 by default', done => {
@@ -184,7 +185,8 @@
);
assert.equal(window.fetch.callCount, 1);
flush(() => {
- // auth check again
+ // here needs two flush as there are two chanined
+ // promises on server-error handler and flush only flushes one
assert.equal(window.fetch.callCount, 2);
flush(() => {
// auth-error fired
@@ -238,6 +240,97 @@
});
});
+ test('auth toast should dismiss existing toast', done => {
+ // starts with authed state
+ element.$.restAPI.getLoggedIn();
+ const toastSpy = sandbox.spy(element, '_createToastAlert');
+ const responseText = Promise.resolve('Authentication required\n');
+
+ // fake an alert
+ element.fire('show-alert', {message: 'test reload', action: 'reload'});
+ const toast = toastSpy.lastCall.returnValue;
+ assert.isOk(toast);
+ assert.include(
+ Polymer.dom(toast.root).textContent, 'test reload');
+
+ // fake auth
+ window.fetch.returns(Promise.resolve({status: 403}));
+ element.fire('server-error',
+ {response: {status: 403, text() { return responseText; }}}
+ );
+ assert.equal(window.fetch.callCount, 1);
+ flush(() => {
+ // here needs two flush as there are two chanined
+ // promises on server-error handler and flush only flushes one
+ assert.equal(window.fetch.callCount, 2);
+ flush(() => {
+ // toast
+ const toast = toastSpy.lastCall.returnValue;
+ assert.include(
+ Polymer.dom(toast.root).textContent, 'Credentails expired.');
+ assert.include(
+ Polymer.dom(toast.root).textContent, 'Refresh credentials');
+ done();
+ });
+ });
+ });
+
+ test('regular toast should dismiss regular toast', () => {
+ // starts with authed state
+ element.$.restAPI.getLoggedIn();
+ const toastSpy = sandbox.spy(element, '_createToastAlert');
+
+ // fake an alert
+ element.fire('show-alert', {message: 'test reload', action: 'reload'});
+ let toast = toastSpy.lastCall.returnValue;
+ assert.isOk(toast);
+ assert.include(
+ Polymer.dom(toast.root).textContent, 'test reload');
+
+ // new alert
+ element.fire('show-alert', {message: 'second-test', action: 'reload'});
+
+ toast = toastSpy.lastCall.returnValue;
+ assert.include(Polymer.dom(toast.root).textContent, 'second-test');
+ });
+
+ test('regular toast should not dismiss auth toast', done => {
+ // starts with authed state
+ element.$.restAPI.getLoggedIn();
+ const toastSpy = sandbox.spy(element, '_createToastAlert');
+ const responseText = Promise.resolve('Authentication required\n');
+
+ // fake auth
+ window.fetch.returns(Promise.resolve({status: 403}));
+ element.fire('server-error',
+ {response: {status: 403, text() { return responseText; }}}
+ );
+ assert.equal(window.fetch.callCount, 1);
+ flush(() => {
+ // here needs two flush as there are two chanined
+ // promises on server-error handler and flush only flushes one
+ assert.equal(window.fetch.callCount, 2);
+ flush(() => {
+ let toast = toastSpy.lastCall.returnValue;
+ assert.include(
+ Polymer.dom(toast.root).textContent, 'Credentails expired.');
+ assert.include(
+ Polymer.dom(toast.root).textContent, 'Refresh credentials');
+
+ // fake an alert
+ element.fire('show-alert', {
+ message: 'test-alert', action: 'reload',
+ });
+ toast = toastSpy.lastCall.returnValue;
+ assert.isOk(toast);
+ assert.include(
+ Polymer.dom(toast.root).textContent, 'Credentails expired.');
+
+ done();
+ });
+ });
+ });
+
test('show alert', () => {
const alertObj = {message: 'foo'};
sandbox.stub(element, '_showAlert');
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
index 215f469..6a0769d 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
@@ -32,6 +32,8 @@
return {
text: String,
actionText: String,
+ /** @type {?string} */
+ type: String,
shown: {
type: Boolean,
value: true,