Commit 4b606a4d authored by Archana Simha's avatar Archana Simha Committed by Commit Bot

Update button reloads local extensions on chrome://extensions page.

Bug: 986368
Change-Id: I2fe3a93d911bfac94f04ba62863bf80fad830514
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1924724
Commit-Queue: Archana Simha <archanasimha@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726615}
parent f9d983d6
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
dev-mode-controlled-by-policy="[[devModeControlledByPolicy]]" dev-mode-controlled-by-policy="[[devModeControlledByPolicy]]"
delegate="[[delegate]]" on-cr-toolbar-menu-tap="onMenuButtonTap_" delegate="[[delegate]]" on-cr-toolbar-menu-tap="onMenuButtonTap_"
on-search-changed="onFilterChanged_" on-search-changed="onFilterChanged_"
extensions="[[extensions_]]"
<if expr="chromeos"> <if expr="chromeos">
on-kiosk-tap="onKioskTap_" on-kiosk-tap="onKioskTap_"
kiosk-enabled="[[kioskEnabled_]]" kiosk-enabled="[[kioskEnabled_]]"
......
...@@ -329,11 +329,34 @@ export class Service { ...@@ -329,11 +329,34 @@ export class Service {
} }
/** @override */ /** @override */
updateAllExtensions() { updateAllExtensions(extensions) {
/**
* Attempt to reload local extensions. If an extension fails to load, the
* user is prompted to try updating the broken extension using loadUnpacked
* and we skip reloading the remaining local extensions.
*/
return new Promise((resolve) => { return new Promise((resolve) => {
chrome.developerPrivate.autoUpdate(resolve); chrome.developerPrivate.autoUpdate(resolve);
chrome.metricsPrivate.recordUserAction('Options_UpdateExtensions'); chrome.metricsPrivate.recordUserAction('Options_UpdateExtensions');
}); })
.then(() => {
return new Promise((resolve, reject) => {
const loadLocalExtensions = async () => {
for (const extension of extensions) {
if (extension.location === 'UNPACKED') {
try {
await this.reloadItem(extension.id);
} catch (loadError) {
reject(loadError);
break;
}
}
}
resolve('Loaded local extensions.');
};
loadLocalExtensions();
});
});
} }
/** @override */ /** @override */
......
...@@ -33,9 +33,10 @@ export class ToolbarDelegate { ...@@ -33,9 +33,10 @@ export class ToolbarDelegate {
/** /**
* Updates all extensions. * Updates all extensions.
* @param {!Array<!chrome.developerPrivate.ExtensionInfo>} extensions
* @return {!Promise} * @return {!Promise}
*/ */
updateAllExtensions() {} updateAllExtensions(extensions) {}
} }
Polymer({ Polymer({
...@@ -44,6 +45,9 @@ Polymer({ ...@@ -44,6 +45,9 @@ Polymer({
_template: html`{__html_template__}`, _template: html`{__html_template__}`,
properties: { properties: {
/** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */
extensions: Array,
/** @type {ToolbarDelegate} */ /** @type {ToolbarDelegate} */
delegate: Object, delegate: Object,
...@@ -188,16 +192,18 @@ Polymer({ ...@@ -188,16 +192,18 @@ Polymer({
// Keep the toast open indefinitely. // Keep the toast open indefinitely.
toastManager.duration = 0; toastManager.duration = 0;
toastManager.show(this.i18n('toolbarUpdatingToast')); toastManager.show(this.i18n('toolbarUpdatingToast'));
this.delegate.updateAllExtensions().then( this.delegate.updateAllExtensions(this.extensions)
() => { .then(
toastManager.hide(); () => {
toastManager.duration = 3000; toastManager.hide();
toastManager.show(this.i18n('toolbarUpdateDone')); toastManager.duration = 3000;
this.isUpdating_ = false; toastManager.show(this.i18n('toolbarUpdateDone'));
}, this.isUpdating_ = false;
() => { },
toastManager.hide(); loadError => {
this.isUpdating_ = false; this.fire('load-error', loadError);
}); toastManager.hide();
this.isUpdating_ = false;
});
}, },
}); });
...@@ -109,6 +109,11 @@ TEST_F('CrExtensionsToolbarTest', 'DevModeToggle', function() { ...@@ -109,6 +109,11 @@ TEST_F('CrExtensionsToolbarTest', 'DevModeToggle', function() {
this.runMochaTest(extension_toolbar_tests.TestNames.DevModeToggle); this.runMochaTest(extension_toolbar_tests.TestNames.DevModeToggle);
}); });
TEST_F('CrExtensionsToolbarTest', 'FailedUpdateFiresLoadError', function() {
this.runMochaTest(
extension_toolbar_tests.TestNames.FailedUpdateFiresLoadError);
});
// TODO(crbug.com/882342) Disabled on other platforms but MacOS due to timeouts. // TODO(crbug.com/882342) Disabled on other platforms but MacOS due to timeouts.
GEN('#if !defined(OS_MACOSX)'); GEN('#if !defined(OS_MACOSX)');
GEN('#define MAYBE_ClickHandlers DISABLED_ClickHandlers'); GEN('#define MAYBE_ClickHandlers DISABLED_ClickHandlers');
......
...@@ -156,9 +156,9 @@ export class TestService extends TestBrowserProxy { ...@@ -156,9 +156,9 @@ export class TestService extends TestBrowserProxy {
} }
/** @override */ /** @override */
updateAllExtensions() { updateAllExtensions(extensions) {
this.methodCalled('updateAllExtensions'); this.methodCalled('updateAllExtensions');
return Promise.resolve(); return this.forceReloadItemError_ ? Promise.reject() : Promise.resolve();
} }
/** @override */ /** @override */
......
...@@ -10,7 +10,7 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min ...@@ -10,7 +10,7 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min
import {eventToPromise} from '../test_util.m.js'; import {eventToPromise} from '../test_util.m.js';
import {TestService} from './test_service.js'; import {TestService} from './test_service.js';
import {testVisible} from './test_util.js'; import {createExtensionInfo, testVisible} from './test_util.js';
/** @fileoverview Suite of tests for extension-toolbar. */ /** @fileoverview Suite of tests for extension-toolbar. */
window.extension_toolbar_tests = {}; window.extension_toolbar_tests = {};
...@@ -20,7 +20,8 @@ extension_toolbar_tests.TestNames = { ...@@ -20,7 +20,8 @@ extension_toolbar_tests.TestNames = {
Layout: 'layout', Layout: 'layout',
ClickHandlers: 'click handlers', ClickHandlers: 'click handlers',
DevModeToggle: 'dev mode toggle', DevModeToggle: 'dev mode toggle',
KioskMode: 'kiosk mode button' KioskMode: 'kiosk mode button',
FailedUpdateFiresLoadError: 'failed local extension update files load error'
}; };
suite(extension_toolbar_tests.suiteName, function() { suite(extension_toolbar_tests.suiteName, function() {
...@@ -136,6 +137,54 @@ suite(extension_toolbar_tests.suiteName, function() { ...@@ -136,6 +137,54 @@ suite(extension_toolbar_tests.suiteName, function() {
}); });
}); });
/** Tests that the update button properly fires the load-error event. */
test(
assert(extension_toolbar_tests.TestNames.FailedUpdateFiresLoadError),
function() {
let item = document.createElement('extensions-item');
item.data = createExtensionInfo();
item.delegate = mockDelegate;
document.body.appendChild(item);
item.set('inDevMode', true);
item.set('data.location', chrome.developerPrivate.Location.UNPACKED);
toolbar.set('inDevMode', true);
flush();
const proxyDelegate = new TestService();
toolbar.delegate = proxyDelegate;
let firedLoadError = false;
toolbar.addEventListener('load-error', () => {
firedLoadError = true;
}, {once: true});
const verifyLoadErrorFired = function(expectCalled) {
return new Promise((resolve, reject) => {
setTimeout(() => {
expectEquals(expectCalled, firedLoadError);
resolve();
});
});
};
toolbar.$.devMode.click();
toolbar.$.updateNow.click();
return proxyDelegate.whenCalled('updateAllExtensions')
.then(function() {
return verifyLoadErrorFired(false);
})
.then(function() {
proxyDelegate.resetResolver('updateAllExtensions');
proxyDelegate.setForceReloadItemError(true);
toolbar.$.updateNow.click();
return proxyDelegate.whenCalled('updateAllExtensions');
})
.then(function() {
return verifyLoadErrorFired(true);
});
});
if (isChromeOS) { if (isChromeOS) {
test(assert(extension_toolbar_tests.TestNames.KioskMode), function() { test(assert(extension_toolbar_tests.TestNames.KioskMode), function() {
const button = toolbar.$.kioskExtensions; const button = toolbar.$.kioskExtensions;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment