Commit 2f74f0e7 authored by Reka Norman's avatar Reka Norman Committed by Commit Bot

[App Management] Add metadata view tests.

This CL adds tests for the pin to shelf toggle in the app management
metadata view. It also creates a test util file, and refactors some
tests to use these util functions.

Bug: 906508
Change-Id: Ica7f7ceb5b097effbbab544a7f7cc066c7a9074d
Reviewed-on: https://chromium-review.googlesource.com/c/1420077Reviewed-by: default avatarcalamity <calamity@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Commit-Queue: calamity <calamity@chromium.org>
Cr-Commit-Position: refs/heads/master@{#626883}
parent 566d8f2b
...@@ -117,6 +117,7 @@ if (!is_android) { ...@@ -117,6 +117,7 @@ if (!is_android) {
":browser_proxy", ":browser_proxy",
":constants", ":constants",
":fake_page_handler", ":fake_page_handler",
":store_client",
":types", ":types",
] ]
} }
...@@ -125,12 +126,15 @@ if (!is_android) { ...@@ -125,12 +126,15 @@ if (!is_android) {
deps = [ deps = [
":app_item", ":app_item",
":fake_page_handler", ":fake_page_handler",
":store_client",
] ]
} }
js_library("permission_item") { js_library("permission_item") {
deps = [ deps = [
":fake_page_handler", ":fake_page_handler",
":store_client",
":util",
] ]
} }
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
padding-inline-start: 24px; padding-inline-start: 24px;
} }
</style> </style>
<app-management-permission-view-header app="[[app_]]"> <app-management-permission-view-header>
</app-management-permission-view-header> </app-management-permission-view-header>
<div class="card-container"> <div class="card-container">
<div id="app-info"> <div id="app-info">
......
...@@ -24,25 +24,10 @@ Polymer({ ...@@ -24,25 +24,10 @@ Polymer({
}, },
attached: function() { attached: function() {
this.watch('app_', (state) => { this.watch('app_', state => app_management.util.getSelectedApp(state));
const selectedAppId = state.currentPage.selectedAppId;
if (selectedAppId) {
return state.apps[selectedAppId];
}
});
this.updateFromStore(); this.updateFromStore();
}, },
/**
* @param {App} app
* @return {string}
* @private
*/
iconUrlFromId_: function(app) {
return app_management.util.getAppIcon(app);
},
/** /**
* @private * @private
*/ */
......
...@@ -9,15 +9,15 @@ cr.define('app_management', function() { ...@@ -9,15 +9,15 @@ cr.define('app_management', function() {
class FakePageHandler { class FakePageHandler {
/** /**
* @param {number} permissionId * @param {number} permissionId
* @param {Object=} config * @param {Object=} optConfig
* @return {!Permission} * @return {!Permission}
*/ */
static createPermission(permissionId, config) { static createPermission(permissionId, optConfig) {
const permission = app_management.util.createPermission( const permission = app_management.util.createPermission(
permissionId, PermissionValueType.kTriState, TriState.kBlock); permissionId, PermissionValueType.kTriState, TriState.kBlock);
if (config) { if (optConfig) {
Object.assign(permission, config); Object.assign(permission, optConfig);
} }
return permission; return permission;
...@@ -25,10 +25,10 @@ cr.define('app_management', function() { ...@@ -25,10 +25,10 @@ cr.define('app_management', function() {
/** /**
* @param {string} id * @param {string} id
* @param {Object=} config * @param {Object=} optConfig
* @return {!App} * @return {!App}
*/ */
static createApp(id, config) { static createApp(id, optConfig) {
const permissionIds = [ const permissionIds = [
PwaPermissionType.CONTENT_SETTINGS_TYPE_GEOLOCATION, PwaPermissionType.CONTENT_SETTINGS_TYPE_GEOLOCATION,
PwaPermissionType.CONTENT_SETTINGS_TYPE_NOTIFICATIONS, PwaPermissionType.CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
...@@ -46,24 +46,25 @@ cr.define('app_management', function() { ...@@ -46,24 +46,25 @@ cr.define('app_management', function() {
id: id, id: id,
type: apps.mojom.AppType.kWeb, type: apps.mojom.AppType.kWeb,
title: 'App Title', title: 'App Title',
description: '',
version: '5.1', version: '5.1',
size: '9.0MB', size: '9.0MB',
isPinned: apps.mojom.OptionalBool.kUnknown, isPinned: apps.mojom.OptionalBool.kFalse,
permissions: permissions, permissions: permissions,
}; };
if (config) { if (optConfig) {
Object.assign(app, config); Object.assign(app, optConfig);
} }
return app; return app;
} }
/** /**
* @param {appManagement.mojom.PageInterface} page * @param {appManagement.mojom.PageProxy} page
*/ */
constructor(page) { constructor(page) {
/** @type {appManagement.mojom.PageInterface} */ /** @type {appManagement.mojom.PageProxy} */
this.page = page; this.page = page;
/** @type {!Array<App>} */ /** @type {!Array<App>} */
...@@ -128,6 +129,31 @@ cr.define('app_management', function() { ...@@ -128,6 +129,31 @@ cr.define('app_management', function() {
* @param {string} appId * @param {string} appId
*/ */
openNativeSettings(appId) {} openNativeSettings(appId) {}
/**
* @param {string} id
* @param {Object=} optConfig
*/
async addApp(id, optConfig) {
this.page.onAppAdded(FakePageHandler.createApp(id, optConfig));
await this.flushForTesting();
}
/**
* Takes an app id and an object mapping app fields to the values they
* should be changed to, and dispatches an action to carry out these
* changes.
* @param {string} id
* @param {Object} changes
*/
async changeApp(id, changes) {
this.page.onAppChanged(FakePageHandler.createApp(id, changes));
await this.flushForTesting();
}
async flushForTesting() {
await this.page.flushForTesting();
}
} }
return {FakePageHandler: FakePageHandler}; return {FakePageHandler: FakePageHandler};
......
...@@ -36,19 +36,20 @@ ...@@ -36,19 +36,20 @@
justify-content: space-around; justify-content: space-around;
} }
</style> </style>
<template is="dom-if" if="[[pinToShelfToggleVisible_(app)]]"> <template is="dom-if" if="[[pinToShelfToggleVisible_(app_)]]">
<div id="shelf-switch-row"> <div id="shelf-switch-row">
<span id="shelf-switch" class="header-text"> <span id="shelf-switch" class="header-text">
$i18n{pinToShelf} $i18n{pinToShelf}
<cr-toggle checked="[[isPinned_(app)]]" on-change="togglePinned_"> <cr-toggle id="pin-to-shelf-toggle" checked="[[isPinned_(app_)]]"
on-change="togglePinned_">
</cr-toggle> </cr-toggle>
</span> </span>
</div> </div>
</template> </template>
<div id="metadata-overview" class="secondary-text"> <div id="metadata-overview" class="secondary-text">
<span>[[versionString_(app)]]</span> <span>[[versionString_(app_)]]</span>
<span>[[sizeString_(app)]]</span> <span>[[sizeString_(app_)]]</span>
<!--TODO(ceciliani): Placeholder for legal declaration--> <!--TODO(ceciliani): Placeholder for legal declaration-->
</div> </div>
</template> </template>
......
...@@ -5,20 +5,29 @@ ...@@ -5,20 +5,29 @@
Polymer({ Polymer({
is: 'app-management-metadata-view', is: 'app-management-metadata-view',
behaviors: [
app_management.StoreClient,
],
properties: { properties: {
/** @type {App} */ /** @type {App} */
app: { app_: {
type: Object, type: Object,
}, },
}, },
attached: function() {
this.watch('app_', state => app_management.util.getSelectedApp(state));
this.updateFromStore();
},
/** /**
* @param {App} app * @param {App} app
* @return bool * @return bool
* @private * @private
*/ */
pinToShelfToggleVisible_: function(app) { pinToShelfToggleVisible_: function(app) {
return !(app.isPinned === OptionalBool.kUnknown); return app.isPinned !== OptionalBool.kUnknown;
}, },
/** /**
...@@ -33,11 +42,9 @@ Polymer({ ...@@ -33,11 +42,9 @@ Polymer({
}, },
togglePinned_: function() { togglePinned_: function() {
assert(this.app);
let newPinnedValue; let newPinnedValue;
switch (this.app.isPinned) { switch (this.app_.isPinned) {
case OptionalBool.kFalse: case OptionalBool.kFalse:
newPinnedValue = OptionalBool.kTrue; newPinnedValue = OptionalBool.kTrue;
break; break;
...@@ -49,12 +56,12 @@ Polymer({ ...@@ -49,12 +56,12 @@ Polymer({
} }
app_management.BrowserProxy.getInstance().handler.setPinned( app_management.BrowserProxy.getInstance().handler.setPinned(
this.app.id, newPinnedValue); this.app_.id, newPinnedValue);
}, },
/** /**
* @param {App} app * @param {App} app
* @return {string?} * @return {?string}
* @private * @private
*/ */
versionString_: function(app) { versionString_: function(app) {
...@@ -67,7 +74,7 @@ Polymer({ ...@@ -67,7 +74,7 @@ Polymer({
/** /**
* @param {App} app * @param {App} app
* @return {string?} * @return {?string}
* @private * @private
*/ */
sizeString_: function(app) { sizeString_: function(app) {
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
Polymer({ Polymer({
is: 'app-management-permission-item', is: 'app-management-permission-item',
behaviors: [
app_management.StoreClient,
],
properties: { properties: {
/** /**
* The name of the permission, to be displayed to the user. * The name of the permission, to be displayed to the user.
...@@ -21,14 +25,14 @@ Polymer({ ...@@ -21,14 +25,14 @@ Polymer({
/** /**
* @type {App} * @type {App}
*/ */
app: Object, app_: Object,
/** /**
* @private {PermissionValueType} * @private {PermissionValueType}
*/ */
permissionValueType_: { permissionValueType_: {
type: Number, type: Number,
computed: 'getPermissionValueType_(app)', computed: 'getPermissionValueType_(app_)',
}, },
/** /**
...@@ -38,13 +42,18 @@ Polymer({ ...@@ -38,13 +42,18 @@ Polymer({
*/ */
permissionValue_: { permissionValue_: {
type: Number, type: Number,
computed: 'getPermissionValue_(app, permissionType)', computed: 'getPermissionValue_(app_, permissionType)',
}, },
/** @type {string} */ /** @type {string} */
icon: String, icon: String,
}, },
attached: function() {
this.watch('app_', state => app_management.util.getSelectedApp(state));
this.updateFromStore();
},
/** /**
* @param {App} app * @param {App} app
* @return {number} * @return {number}
...@@ -112,7 +121,7 @@ Polymer({ ...@@ -112,7 +121,7 @@ Polymer({
} }
app_management.BrowserProxy.getInstance().handler.setPermission( app_management.BrowserProxy.getInstance().handler.setPermission(
this.app.id, newPermission); this.app_.id, newPermission);
}, },
/** /**
......
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
<paper-ripple class="circle"></paper-ripple> <paper-ripple class="circle"></paper-ripple>
</button> </button>
</paper-icon-button-light> </paper-icon-button-light>
<img id="permission-view-header-icon" src="[[iconUrlFromId_(app)]]"> <img id="permission-view-header-icon" src="[[iconUrlFromId_(app_)]]">
<div class="page-title">[[app.title]]</div> <div class="page-title">[[app_.title]]</div>
<slot name="extra-right-buttons"></slot> <slot name="extra-right-buttons"></slot>
<paper-button id="uninstall-button" on-click="onClickUninstallButton_"> <paper-button id="uninstall-button" on-click="onClickUninstallButton_">
$i18n{uninstall} $i18n{uninstall}
......
...@@ -10,19 +10,13 @@ Polymer({ ...@@ -10,19 +10,13 @@ Polymer({
properties: { properties: {
/** @type {App} */ /** @type {App} */
app: { app_: {
type: Object, type: Object,
}, },
}, },
attached: function() { attached: function() {
this.watch('app', (state) => { this.watch('app_', state => app_management.util.getSelectedApp(state));
const selectedAppId = state.currentPage.selectedAppId;
if (selectedAppId) {
return state.apps[selectedAppId];
}
});
this.updateFromStore(); this.updateFromStore();
}, },
...@@ -50,6 +44,6 @@ Polymer({ ...@@ -50,6 +44,6 @@ Polymer({
* @private * @private
*/ */
onClickUninstallButton_: function() { onClickUninstallButton_: function() {
app_management.BrowserProxy.getInstance().handler.uninstall(this.app.id); app_management.BrowserProxy.getInstance().handler.uninstall(this.app_.id);
}, },
}); });
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
margin-inline-end: 16px; margin-inline-end: 16px;
} }
</style> </style>
<app-management-permission-view-header app="[[app_]]"> <app-management-permission-view-header>
<div slot="extra-right-buttons" id="extra-button"> <div slot="extra-right-buttons" id="extra-button">
<paper-button id="site-settings-button" <paper-button id="site-settings-button"
class="secondary-text" class="secondary-text"
...@@ -76,7 +76,6 @@ ...@@ -76,7 +76,6 @@
<div id="permission-list" class="card-container"> <div id="permission-list" class="card-container">
<app-management-permission-item <app-management-permission-item
class="permission-card-row separated-row header-text" class="permission-card-row separated-row header-text"
app="[[app_]]"
permission-label="$i18n{notifications}" permission-label="$i18n{notifications}"
permission-type="CONTENT_SETTINGS_TYPE_NOTIFICATIONS"> permission-type="CONTENT_SETTINGS_TYPE_NOTIFICATIONS">
</app-management-permission-item> </app-management-permission-item>
...@@ -100,21 +99,18 @@ ...@@ -100,21 +99,18 @@
<iron-collapse opened="[[listExpanded_]]"> <iron-collapse opened="[[listExpanded_]]">
<app-management-permission-item <app-management-permission-item
class="subpermission-row" class="subpermission-row"
app="[[app_]]"
icon="cr:location-on" icon="cr:location-on"
permission-label="$i18n{location}" permission-label="$i18n{location}"
permission-type="CONTENT_SETTINGS_TYPE_GEOLOCATION"> permission-type="CONTENT_SETTINGS_TYPE_GEOLOCATION">
</app-management-permission-item> </app-management-permission-item>
<app-management-permission-item <app-management-permission-item
class="subpermission-row" class="subpermission-row"
app="[[app_]]"
icon="cr:videocam" icon="cr:videocam"
permission-label="$i18n{camera}" permission-label="$i18n{camera}"
permission-type="CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA"> permission-type="CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA">
</app-management-permission-item> </app-management-permission-item>
<app-management-permission-item <app-management-permission-item
class="subpermission-row" class="subpermission-row"
app="[[app_]]"
icon="cr:mic" icon="cr:mic"
permission-label="$i18n{microphone}" permission-label="$i18n{microphone}"
permission-type="CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC"> permission-type="CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC">
......
...@@ -24,13 +24,7 @@ Polymer({ ...@@ -24,13 +24,7 @@ Polymer({
}, },
attached: function() { attached: function() {
this.watch('app_', (state) => { this.watch('app_', state => app_management.util.getSelectedApp(state));
const selectedAppId = state.currentPage.selectedAppId;
if (selectedAppId) {
return state.apps[selectedAppId];
}
});
this.updateFromStore(); this.updateFromStore();
}, },
......
...@@ -18,6 +18,8 @@ cr.define('app_management', function() { ...@@ -18,6 +18,8 @@ cr.define('app_management', function() {
* @return {AppMap} * @return {AppMap}
*/ */
AppState.addApp = function(apps, action) { AppState.addApp = function(apps, action) {
assert(!apps[action.app.id]);
const newAppEntry = {}; const newAppEntry = {};
newAppEntry[action.app.id] = action.app; newAppEntry[action.app.id] = action.app;
return Object.assign({}, apps, newAppEntry); return Object.assign({}, apps, newAppEntry);
......
...@@ -56,10 +56,24 @@ cr.define('app_management.util', function() { ...@@ -56,10 +56,24 @@ cr.define('app_management.util', function() {
return `chrome://extension-icon/${app.id}/128/1`; return `chrome://extension-icon/${app.id}/128/1`;
} }
/**
* If there is no selected app, returns undefined so that Polymer bindings
* won't be updated.
* @param {AppManagementPageState} state
* @return {App|undefined}
*/
function getSelectedApp(state) {
const selectedAppId = state.currentPage.selectedAppId;
if (selectedAppId) {
return state.apps[selectedAppId];
}
}
return { return {
createEmptyState: createEmptyState, createEmptyState: createEmptyState,
createInitialState: createInitialState, createInitialState: createInitialState,
createPermission: createPermission, createPermission: createPermission,
getAppIcon: getAppIcon, getAppIcon: getAppIcon,
getSelectedApp: getSelectedApp,
}; };
}); });
...@@ -18,7 +18,9 @@ AppManagementBrowserTest.prototype = { ...@@ -18,7 +18,9 @@ AppManagementBrowserTest.prototype = {
browsePreload: 'chrome://apps', browsePreload: 'chrome://apps',
extraLibraries: PolymerTest.getLibraries(ROOT_PATH), extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([
'test_util.js',
]),
featureList: ['features::kAppManagement', ''], featureList: ['features::kAppManagement', ''],
...@@ -26,7 +28,6 @@ AppManagementBrowserTest.prototype = { ...@@ -26,7 +28,6 @@ AppManagementBrowserTest.prototype = {
runAccessibilityChecks: true, runAccessibilityChecks: true,
}; };
function AppManagementAppTest() {} function AppManagementAppTest() {}
AppManagementAppTest.prototype = { AppManagementAppTest.prototype = {
...@@ -55,6 +56,20 @@ TEST_F('AppManagementMainViewTest', 'All', function() { ...@@ -55,6 +56,20 @@ TEST_F('AppManagementMainViewTest', 'All', function() {
mocha.run(); mocha.run();
}); });
function AppManagementMetadataViewTest() {}
AppManagementMetadataViewTest.prototype = {
__proto__: AppManagementBrowserTest.prototype,
extraLibraries: AppManagementBrowserTest.prototype.extraLibraries.concat([
'metadata_view_test.js',
]),
};
TEST_F('AppManagementMetadataViewTest', 'All', function() {
mocha.run();
});
function AppManagementReducersTest() {} function AppManagementReducersTest() {}
AppManagementReducersTest.prototype = { AppManagementReducersTest.prototype = {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
'use strict';
suite('<app-management-app>', function() { suite('<app-management-app>', function() {
test('loads', async function() { test('loads', async function() {
// Check that the browser responds to the getApps() message. // Check that the browser responds to the getApps() message.
......
...@@ -2,74 +2,57 @@ ...@@ -2,74 +2,57 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
'use strict';
suite('<app-management-main-view>', function() { suite('<app-management-main-view>', function() {
let mainView; let mainView;
let fakeHandler; let fakeHandler;
let callbackRouterProxy;
let appIdCounter; let appIdCounter;
/**
* @param {number} numApps
*/
async function addApps(numApps) {
for (let i = 0; i < numApps; i++) {
await fakeHandler.addApp((appIdCounter++).toString());
}
}
setup(function() { setup(function() {
appIdCounter = 0; appIdCounter = 0;
mainView = document.createElement('app-management-main-view'); mainView = document.createElement('app-management-main-view');
PolymerTest.clearBody(); PolymerTest.clearBody();
let browserProxy = app_management.BrowserProxy.getInstance(); fakeHandler = setupFakeHandler();
callbackRouterProxy = browserProxy.callbackRouter.createProxy(); replaceStore();
fakeHandler = new app_management.FakePageHandler(callbackRouterProxy);
browserProxy.handler = fakeHandler;
app_management.Store.instance_ = new app_management.Store();
app_management.Store.getInstance().init(
app_management.util.createEmptyState());
document.body.appendChild(mainView); document.body.appendChild(mainView);
}); });
/**
* @param {number} numApps
* @return {!Array<appManagement.mojom.App>} apps
*/
function createTestApps(numApps) {
let apps = [];
for (let i = 0; i < numApps; i++) {
apps.push(
app_management.FakePageHandler.createApp('TestApp' + appIdCounter++));
}
return apps;
}
async function addApps(apps) {
for (const app of apps) {
callbackRouterProxy.onAppAdded(app);
}
await callbackRouterProxy.flushForTesting();
}
test('simple app addition', async function() { test('simple app addition', async function() {
// Ensure there is no apps initially // Ensure there is no apps initially
expectEquals( expectEquals(
0, mainView.root.querySelectorAll('app-management-app-item').length); 0, mainView.root.querySelectorAll('app-management-app-item').length);
let apps = createTestApps(1); const appId = '1';
await addApps(apps); await fakeHandler.addApp(appId);
let appItems = mainView.root.querySelectorAll('app-management-app-item'); let appItems = mainView.root.querySelectorAll('app-management-app-item');
expectEquals(1, appItems.length); expectEquals(1, appItems.length);
expectEquals(appItems[0].app.id, apps[0].id); expectEquals(appId, appItems[0].app.id);
}); });
test('more apps bar visibility', async function() { test('more apps bar visibility', async function() {
// The more apps bar shouldn't appear when there are 4 apps. // The more apps bar shouldn't appear when there are 4 apps.
await addApps(createTestApps(4)); await addApps(4);
expectEquals( expectEquals(
4, mainView.root.querySelectorAll('app-management-app-item').length); 4, mainView.root.querySelectorAll('app-management-app-item').length);
expectTrue(mainView.$['expander-row'].hidden); expectTrue(mainView.$['expander-row'].hidden);
// The more apps bar appears when there are 5 apps. // The more apps bar appears when there are 5 apps.
await addApps(createTestApps(1)); await addApps(1);
expectEquals( expectEquals(
5, mainView.root.querySelectorAll('app-management-app-item').length); 5, mainView.root.querySelectorAll('app-management-app-item').length);
expectFalse(mainView.$['expander-row'].hidden); expectFalse(mainView.$['expander-row'].hidden);
...@@ -77,14 +60,14 @@ suite('<app-management-main-view>', function() { ...@@ -77,14 +60,14 @@ suite('<app-management-main-view>', function() {
test('notifications sublabel collapsibility', async function() { test('notifications sublabel collapsibility', async function() {
// The three spans contains collapsible attribute. // The three spans contains collapsible attribute.
await addApps(createTestApps(4)); await addApps(4);
const pieces = await mainView.getNotificationSublabelPieces_(); const pieces = await mainView.getNotificationSublabelPieces_();
expectTrue(pieces.filter(p => p.arg === '$1')[0].collapsible); expectTrue(pieces.filter(p => p.arg === '$1')[0].collapsible);
expectTrue(pieces.filter(p => p.arg === '$2')[0].collapsible); expectTrue(pieces.filter(p => p.arg === '$2')[0].collapsible);
expectTrue(pieces.filter(p => p.arg === '$3')[0].collapsible); expectTrue(pieces.filter(p => p.arg === '$3')[0].collapsible);
// Checking ",and other x apps" is non-collapsible // Checking ",and other x apps" is non-collapsible
await addApps(createTestApps(6)); await addApps(6);
const pieces2 = await mainView.getNotificationSublabelPieces_(); const pieces2 = await mainView.getNotificationSublabelPieces_();
expectFalse(pieces2.filter(p => p.arg === '$4')[0].collapsible); expectFalse(pieces2.filter(p => p.arg === '$4')[0].collapsible);
}); });
......
// 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.
'use strict';
suite('<app-management-metadata-view>', function() {
let metadataView;
let fakeHandler;
const APP_ID = '1';
setup(async function() {
metadataView = document.createElement('app-management-metadata-view');
PolymerTest.clearBody();
fakeHandler = setupFakeHandler();
replaceStore();
// Add an app, and make it the currently selected app.
await fakeHandler.addApp(APP_ID);
app_management.Store.getInstance().dispatch(
app_management.actions.changePage(PageType.DETAIL, APP_ID));
document.body.appendChild(metadataView);
});
test(
'when app.isPinned is unknown, the pin to shelf toggle is not visible',
async function() {
await fakeHandler.changeApp(APP_ID, {isPinned: OptionalBool.kUnknown});
// Check that the toggle is not visible.
const toggle = metadataView.root.getElementById('pin-to-shelf-toggle');
if (toggle) {
expectTrue(isHidden(toggle));
}
});
test(
'clicking the pin to shelf toggle changes the isPinned field of the app',
async function() {
// Set app.isPinned to false.
await fakeHandler.changeApp(APP_ID, {isPinned: OptionalBool.kFalse});
const toggle = metadataView.root.getElementById('pin-to-shelf-toggle');
// Check that the toggle is visible and is not checked.
expectTrue(!!toggle && !isHidden(toggle));
expectFalse(toggle.checked);
// Toggle from false to true.
toggle.click();
await fakeHandler.flushForTesting();
// Check that the isPinned field of the app has changed.
expectEquals(OptionalBool.kTrue, metadataView.app_.isPinned);
// Check that the toggle is now checked.
expectTrue(toggle.checked);
// Toggle from true to false.
toggle.click();
await fakeHandler.flushForTesting();
// Check that the isPinned field of the app has changed.
expectEquals(OptionalBool.kFalse, metadataView.app_.isPinned);
// Check that the toggle is no longer checked.
expectFalse(toggle.checked);
});
});
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
'use strict';
suite('app state', function() { suite('app state', function() {
let apps; let apps;
let action;
let state; let state;
function createApp(id, config) { function createApp(id, config) {
...@@ -27,8 +28,7 @@ suite('app state', function() { ...@@ -27,8 +28,7 @@ suite('app state', function() {
test('updates when an app is added', function() { test('updates when an app is added', function() {
const newApp = createApp('3', {type: 1, title: 'a'}); const newApp = createApp('3', {type: 1, title: 'a'});
const action = app_management.actions.addApp(newApp);
action = app_management.actions.addApp(newApp);
apps = app_management.AppState.updateApps(apps, action); apps = app_management.AppState.updateApps(apps, action);
// Check that apps contains a key for each app id. // Check that apps contains a key for each app id.
...@@ -45,7 +45,7 @@ suite('app state', function() { ...@@ -45,7 +45,7 @@ suite('app state', function() {
test('updates when an app is changed', function() { test('updates when an app is changed', function() {
const changedApp = createApp('2', {type: 1, title: 'a'}); const changedApp = createApp('2', {type: 1, title: 'a'});
action = app_management.actions.changeApp(changedApp); const action = app_management.actions.changeApp(changedApp);
apps = app_management.AppState.updateApps(apps, action); apps = app_management.AppState.updateApps(apps, action);
// Check that app has changed. // Check that app has changed.
...@@ -58,7 +58,7 @@ suite('app state', function() { ...@@ -58,7 +58,7 @@ suite('app state', function() {
}); });
test('updates when an app is removed', function() { test('updates when an app is removed', function() {
action = app_management.actions.removeApp('1'); const action = app_management.actions.removeApp('1');
apps = app_management.AppState.updateApps(apps, action); apps = app_management.AppState.updateApps(apps, action);
// Check that app is removed. // Check that app is removed.
...@@ -74,7 +74,7 @@ suite('app state', function() { ...@@ -74,7 +74,7 @@ suite('app state', function() {
state.currentPage.selectedAppId = '1'; state.currentPage.selectedAppId = '1';
state.currentPage.pageType = PageType.DETAIL; state.currentPage.pageType = PageType.DETAIL;
action = app_management.actions.removeApp('1'); let action = app_management.actions.removeApp('1');
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals(null, state.currentPage.selectedAppId); assertEquals(null, state.currentPage.selectedAppId);
...@@ -97,7 +97,7 @@ suite('app state', function() { ...@@ -97,7 +97,7 @@ suite('app state', function() {
state.currentPage.selectedAppId = '1'; state.currentPage.selectedAppId = '1';
state.currentPage.pageType = PageType.DETAIL; state.currentPage.pageType = PageType.DETAIL;
action = app_management.actions.changePage(PageType.MAIN); let action = app_management.actions.changePage(PageType.MAIN);
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals(null, state.currentPage.selectedAppId); assertEquals(null, state.currentPage.selectedAppId);
...@@ -113,7 +113,7 @@ suite('app state', function() { ...@@ -113,7 +113,7 @@ suite('app state', function() {
test('state updates when changing to app detail page', function() { test('state updates when changing to app detail page', function() {
// State updates when a valid app detail page is selected. // State updates when a valid app detail page is selected.
action = app_management.actions.changePage(PageType.DETAIL, '2'); let action = app_management.actions.changePage(PageType.DETAIL, '2');
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals('2', state.currentPage.selectedAppId); assertEquals('2', state.currentPage.selectedAppId);
...@@ -131,7 +131,7 @@ suite('app state', function() { ...@@ -131,7 +131,7 @@ suite('app state', function() {
}); });
test('state updates when changing to notifications page', function() { test('state updates when changing to notifications page', function() {
action = app_management.actions.changePage(PageType.NOTIFICATIONS); const action = app_management.actions.changePage(PageType.NOTIFICATIONS);
state = app_management.reduceAction(state, action); state = app_management.reduceAction(state, action);
assertEquals(PageType.NOTIFICATIONS, state.currentPage.pageType); assertEquals(PageType.NOTIFICATIONS, state.currentPage.pageType);
......
// 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.
'use strict';
/**
* @return {app_management.FakePageHandler}
*/
function setupFakeHandler() {
const browserProxy = app_management.BrowserProxy.getInstance();
const callbackRouterProxy = browserProxy.callbackRouter.createProxy();
const fakeHandler = new app_management.FakePageHandler(callbackRouterProxy);
browserProxy.handler = fakeHandler;
return fakeHandler;
}
/**
* Replace the app management store instance with a new, empty store.
*/
function replaceStore() {
app_management.Store.instance_ = new app_management.Store();
app_management.Store.getInstance().init(
app_management.util.createEmptyState());
}
/**
* @param {Element} element
* @return {bool}
*/
function isHidden(element) {
const rect = element.getBoundingClientRect();
return rect.height === 0 && rect.width === 0;
}
...@@ -54,6 +54,11 @@ goog.provide('{{module.namespace}}.{{interface.name}}CallbackRouter'); ...@@ -54,6 +54,11 @@ goog.provide('{{module.namespace}}.{{interface.name}}CallbackRouter');
* @return {!{{module.namespace}}.{{interface.name}}Request} * @return {!{{module.namespace}}.{{interface.name}}Request}
*/ */
createRequest() {} createRequest() {}
/**
* @return {Promise}
*/
flushForTesting() {}
}; };
{{module.namespace}}.{{interface.name}} = class { {{module.namespace}}.{{interface.name}} = class {
......
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