blob: 92152e9842cc99b5cbe6e25869e3c328b4a3f68b [file] [log] [blame]
// Copyright 2017 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.
suite('AllSites', function() {
const TEST_COOKIE_LIST = {
id: 'example',
children: [
{domain: 'bar.com'},
{domain: 'bar.com'},
{domain: 'bar.com'},
{domain: 'bar.com'},
{domain: 'google.com'},
{domain: 'google.com'},
]
};
/**
* An example eTLD+1 Object with multiple origins grouped under it.
* @type {!SiteGroup}
*/
const TEST_MULTIPLE_SITE_GROUP = test_util.createSiteGroup('example.com', [
'http://example.com',
'https://www.example.com',
'https://login.example.com',
]);
/**
* An example pref with multiple categories and multiple allow/block
* state.
* @type {SiteSettingsPref}
*/
let prefsVarious;
/**
* A site list element created before each test.
* @type {SiteList}
*/
let testElement;
/**
* The mock proxy object to use during test.
* @type {TestSiteSettingsPrefsBrowserProxy}
*/
let browserProxy = null;
/**
* The mock local data proxy object to use during test.
* @type {TestLocalDataBrowserProxy}
*/
let localDataBrowserProxy;
suiteSetup(function() {
CrSettingsPrefs.setInitialized();
});
suiteTeardown(function() {
CrSettingsPrefs.resetForTesting();
});
// Initialize a site-list before each test.
setup(function() {
prefsVarious = test_util.createSiteSettingsPrefs([], [
test_util.createContentSettingTypeToValuePair(
settings.ContentSettingsTypes.GEOLOCATION,
[
test_util.createRawSiteException('https://foo.com'),
test_util.createRawSiteException('https://bar.com', {
setting: settings.ContentSetting.BLOCK,
})
]),
test_util.createContentSettingTypeToValuePair(
settings.ContentSettingsTypes.NOTIFICATIONS,
[
test_util.createRawSiteException('https://google.com', {
setting: settings.ContentSetting.BLOCK,
}),
test_util.createRawSiteException('https://bar.com', {
setting: settings.ContentSetting.BLOCK,
}),
test_util.createRawSiteException('https://foo.com', {
setting: settings.ContentSetting.BLOCK,
}),
])
]);
browserProxy = new TestSiteSettingsPrefsBrowserProxy();
localDataBrowserProxy = new TestLocalDataBrowserProxy();
settings.SiteSettingsPrefsBrowserProxyImpl.instance_ = browserProxy;
settings.LocalDataBrowserProxyImpl.instance_ = localDataBrowserProxy;
PolymerTest.clearBody();
testElement = document.createElement('all-sites');
assertTrue(!!testElement);
document.body.appendChild(testElement);
});
teardown(function() {
// The code being tested changes the Route. Reset so that state is not
// leaked across tests.
settings.resetRouteForTesting();
});
/**
* Configures the test element.
* @param {Array<dictionary>} prefs The prefs to use.
*/
function setUpCategory(prefs) {
browserProxy.setPrefs(prefs);
settings.navigateTo(settings.routes.SITE_SETTINGS_ALL);
}
test('All sites list populated', function() {
setUpCategory(prefsVarious);
testElement.populateList_();
return browserProxy.whenCalled('getAllSites').then(() => {
// Use resolver to ensure that the list container is populated.
const resolver = new PromiseResolver();
// In Polymer2, we need to wait until after the next render for the list
// to be populated. TODO (rbpotter): Remove conditional when migration to
// Polymer 2 is completed.
if (Polymer.DomIf) {
Polymer.RenderStatus.beforeNextRender(testElement, () => {
resolver.resolve();
});
} else {
testElement.async(resolver.resolve);
}
return resolver.promise.then(() => {
assertEquals(3, testElement.siteGroupMap.size);
// Flush to be sure list container is populated.
Polymer.dom.flush();
const siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals(3, siteEntries.length);
});
});
});
test('search query filters list', function() {
const SEARCH_QUERY = 'foo';
setUpCategory(prefsVarious);
testElement.populateList_();
return browserProxy.whenCalled('getAllSites')
.then(() => {
// Flush to be sure list container is populated.
Polymer.dom.flush();
const siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals(3, siteEntries.length);
testElement.filter = SEARCH_QUERY;
})
.then(() => {
Polymer.dom.flush();
const siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
const hiddenSiteEntries = Polymer.dom(testElement.root)
.querySelectorAll('site-entry[hidden]');
assertEquals(1, siteEntries.length - hiddenSiteEntries.length);
for (let i = 0; i < siteEntries; ++i) {
const entry = siteEntries[i];
if (!hiddenSiteEntries.includes(entry)) {
assertTrue(entry.siteGroup.origins.some((origin) => {
return origin.includes(SEARCH_QUERY);
}));
}
}
});
});
test('can be sorted by most visited', function() {
setUpCategory(prefsVarious);
testElement.populateList_();
return browserProxy.whenCalled('getAllSites').then(() => {
// Add additional origins and artificially insert fake engagement scores
// to sort.
assertEquals(3, testElement.siteGroupMap.size);
const fooSiteGroup = testElement.siteGroupMap.get('foo.com');
fooSiteGroup.origins.push(test_util.createOriginInfo(
'https://login.foo.com', {engagement: 20}));
assertEquals(2, fooSiteGroup.origins.length);
fooSiteGroup.origins[0].engagement = 50.4;
const googleSiteGroup = testElement.siteGroupMap.get('google.com');
assertEquals(1, googleSiteGroup.origins.length);
googleSiteGroup.origins[0].engagement = 55.1261;
const barSiteGroup = testElement.siteGroupMap.get('bar.com');
assertEquals(1, barSiteGroup.origins.length);
barSiteGroup.origins[0].engagement = 0.5235;
// 'Most visited' is the default sort method, so sort by a different
// method first to ensure changing to 'Most visited' works.
testElement.root.querySelector('select').value = 'name';
testElement.onSortMethodChanged_();
Polymer.dom.flush();
let siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals('bar.com', siteEntries[0].$.displayName.innerText.trim());
assertEquals('foo.com', siteEntries[1].$.displayName.innerText.trim());
assertEquals('google.com', siteEntries[2].$.displayName.innerText.trim());
testElement.root.querySelector('select').value = 'most-visited';
testElement.onSortMethodChanged_();
Polymer.dom.flush();
siteEntries = testElement.$.listContainer.querySelectorAll('site-entry');
// Each site entry is sorted by its maximum engagement, so expect
// 'foo.com' to come after 'google.com'.
assertEquals('google.com', siteEntries[0].$.displayName.innerText.trim());
assertEquals('foo.com', siteEntries[1].$.displayName.innerText.trim());
assertEquals('bar.com', siteEntries[2].$.displayName.innerText.trim());
});
});
test('can be sorted by storage', function() {
localDataBrowserProxy.setCookieDetails(TEST_COOKIE_LIST);
setUpCategory(prefsVarious);
testElement.populateList_();
return browserProxy.whenCalled('getAllSites')
.then(() => {
Polymer.dom.flush();
let siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
// Add additional origins to SiteGroups with cookies to simulate their
// being grouped entries, plus add local storage.
siteEntries[0].siteGroup.origins[0].usage = 900;
siteEntries[1].siteGroup.origins.push(
test_util.createOriginInfo('http://bar.com'));
siteEntries[1].siteGroup.origins[0].usage = 500;
siteEntries[1].siteGroup.origins[1].usage = 500;
siteEntries[2].siteGroup.origins.push(
test_util.createOriginInfo('http://google.com'));
testElement.onSortMethodChanged_();
siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
// Verify all sites is not sorted by storage.
assertEquals(3, siteEntries.length);
assertEquals(
'foo.com', siteEntries[0].$.displayName.innerText.trim());
assertEquals(
'bar.com', siteEntries[1].$.displayName.innerText.trim());
assertEquals(
'google.com', siteEntries[2].$.displayName.innerText.trim());
// Change the sort method, then verify all sites is now sorted by
// name.
testElement.root.querySelector('select').value = 'data-stored';
testElement.onSortMethodChanged_();
Polymer.dom.flush();
siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals(
'bar.com',
siteEntries[0]
.root.querySelector('#displayName .url-directionality')
.innerText.trim());
assertEquals(
'foo.com',
siteEntries[1]
.root.querySelector('#displayName .url-directionality')
.innerText.trim());
assertEquals(
'google.com',
siteEntries[2]
.root.querySelector('#displayName .url-directionality')
.innerText.trim());
});
});
test('can be sorted by name', function() {
setUpCategory(prefsVarious);
testElement.populateList_();
return browserProxy.whenCalled('getAllSites').then(() => {
Polymer.dom.flush();
let siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
// Verify all sites is not sorted by name.
assertEquals(3, siteEntries.length);
assertEquals('foo.com', siteEntries[0].$.displayName.innerText.trim());
assertEquals('bar.com', siteEntries[1].$.displayName.innerText.trim());
assertEquals('google.com', siteEntries[2].$.displayName.innerText.trim());
// Change the sort method, then verify all sites is now sorted by name.
testElement.root.querySelector('select').value = 'name';
testElement.onSortMethodChanged_();
Polymer.dom.flush();
siteEntries = testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals('bar.com', siteEntries[0].$.displayName.innerText.trim());
assertEquals('foo.com', siteEntries[1].$.displayName.innerText.trim());
assertEquals('google.com', siteEntries[2].$.displayName.innerText.trim());
});
});
test('merging additional SiteGroup lists works', function() {
setUpCategory(prefsVarious);
testElement.populateList_();
return browserProxy.whenCalled('getAllSites').then(() => {
Polymer.dom.flush();
let siteEntries =
testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals(3, siteEntries.length);
// Pretend an additional set of SiteGroups were added.
const fooEtldPlus1 = 'foo.com';
const addEtldPlus1 = 'additional-site.net';
const fooOrigin = 'https://login.foo.com';
const addOrigin = 'http://www.additional-site.net';
const STORAGE_SITE_GROUP_LIST = /** @type {!Array{!SiteGroup}}*/ ([
{
// Test merging an existing site works, with overlapping origin lists.
'etldPlus1': fooEtldPlus1,
'origins': [
test_util.createOriginInfo(fooOrigin),
test_util.createOriginInfo('https://foo.com'),
],
},
{
// Test adding a new site entry works.
'etldPlus1': addEtldPlus1,
'origins': [test_util.createOriginInfo(addOrigin)],
}
]);
testElement.onStorageListFetched(STORAGE_SITE_GROUP_LIST);
Polymer.dom.flush();
siteEntries = testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals(4, siteEntries.length);
assertEquals(fooEtldPlus1, siteEntries[0].siteGroup.etldPlus1);
assertEquals(2, siteEntries[0].siteGroup.origins.length);
assertEquals(fooOrigin, siteEntries[0].siteGroup.origins[0].origin);
assertEquals(
'https://foo.com', siteEntries[0].siteGroup.origins[1].origin);
assertEquals(addEtldPlus1, siteEntries[3].siteGroup.etldPlus1);
assertEquals(1, siteEntries[3].siteGroup.origins.length);
assertEquals(addOrigin, siteEntries[3].siteGroup.origins[0].origin);
});
});
function resetSettingsViaOverflowMenu(buttonType) {
assertTrue(buttonType == 'cancel-button' || buttonType == 'action-button');
Polymer.dom.flush();
siteEntries = testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals(1, siteEntries.length);
const overflowMenuButton = siteEntries[0].$.overflowMenuButton;
assertFalse(overflowMenuButton.closest('.row-aligned').hidden);
// Open the reset settings dialog.
const overflowMenu = testElement.$.menu.get();
const menuItems = overflowMenu.querySelectorAll('.dropdown-item');
// Test clicking on the overflow menu button opens the menu.
assertFalse(overflowMenu.open);
overflowMenuButton.click();
assertTrue(overflowMenu.open);
// Open the reset settings dialog and tap the |buttonType| button.
assertFalse(testElement.$.confirmResetSettings.get().open);
menuItems[0].click();
assertTrue(testElement.$.confirmResetSettings.get().open);
const actionButtonList =
testElement.$.confirmResetSettings.get().getElementsByClassName(
buttonType);
assertEquals(1, actionButtonList.length);
actionButtonList[0].click();
testElement.actionMenuModel_ = {
index: 0,
item: testElement.filteredList_[0],
};
// Check the dialog and overflow menu are now both closed.
assertFalse(testElement.$.confirmResetSettings.get().open);
assertFalse(overflowMenu.open);
}
test('cancelling the confirm dialog on resetting settings works', function() {
testElement.siteGroupMap.set(
TEST_MULTIPLE_SITE_GROUP.etldPlus1,
JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP)));
testElement.forceListUpdate_();
resetSettingsViaOverflowMenu('cancel-button');
});
test('reset settings via overflow menu (no data or cookies)', function() {
// Test when entire siteGroup has no data or cookies.
// Clone this object to avoid propagating changes made in this test.
testElement.siteGroupMap.set(
TEST_MULTIPLE_SITE_GROUP.etldPlus1,
JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP)));
testElement.forceListUpdate_();
resetSettingsViaOverflowMenu('action-button');
// Ensure a call was made to setOriginPermissions for each origin.
assertEquals(
TEST_MULTIPLE_SITE_GROUP.origins.length,
browserProxy.getCallCount('setOriginPermissions'));
assertEquals(testElement.filteredList_.length, 0);
});
test(
'reset settings via overflow menu (one has data and cookies)',
function() {
// Test when one origin has data and cookies.
// Clone this object to avoid propagating changes made in this test.
let siteGroup = JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP));
siteGroup.origins[0].hasPermissionSettings = true;
siteGroup.origins[0].usage = 100;
siteGroup.origins[0].numCookies = 2;
testElement.siteGroupMap.set(
siteGroup.etldPlus1, JSON.parse(JSON.stringify(siteGroup)));
testElement.forceListUpdate_();
resetSettingsViaOverflowMenu('action-button');
assertEquals(testElement.filteredList_.length, 1);
assertEquals(1, testElement.filteredList_[0].origins.length);
assertFalse(
testElement.filteredList_[0].origins[0].hasPermissionSettings);
assertEquals(testElement.filteredList_[0].origins[0].usage, 100);
assertEquals(testElement.filteredList_[0].origins[0].numCookies, 2);
});
test('reset settings via overflow menu (etld+1 has cookies)', function() {
// Test when none of origin have data or cookies, but etld+1 has
// cookies. In this case, a placeholder origin will be created with the
// Etld+1 cookies number. Clone this object to avoid propagating changes
// made in this test.
let siteGroup = JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP));
siteGroup.numCookies = 5;
testElement.siteGroupMap.set(
siteGroup.etldPlus1, JSON.parse(JSON.stringify(siteGroup)));
testElement.forceListUpdate_();
resetSettingsViaOverflowMenu('action-button');
assertEquals(testElement.filteredList_.length, 1);
assertEquals(1, testElement.filteredList_[0].origins.length);
assertFalse(testElement.filteredList_[0].origins[0].hasPermissionSettings);
assertEquals(testElement.filteredList_[0].origins[0].usage, 0);
assertEquals(testElement.filteredList_[0].origins[0].numCookies, 5);
});
function clearDataViaOverflowMenu(buttonType) {
assertTrue(buttonType == 'cancel-button' || buttonType == 'action-button');
Polymer.dom.flush();
siteEntries = testElement.$.listContainer.querySelectorAll('site-entry');
assertEquals(1, siteEntries.length);
const overflowMenuButton = siteEntries[0].$.overflowMenuButton;
assertFalse(overflowMenuButton.closest('.row-aligned').hidden);
// Open the clear data dialog.
const overflowMenu = testElement.$.menu.get();
const menuItems = overflowMenu.querySelectorAll('.dropdown-item');
// Test clicking on the overflow menu button opens the menu.
assertFalse(overflowMenu.open);
overflowMenuButton.click();
assertTrue(overflowMenu.open);
// Open the clear data dialog and tap the |buttonType| button.
assertFalse(testElement.$.confirmClearData.get().open);
menuItems[1].click();
assertTrue(testElement.$.confirmClearData.get().open);
const actionButtonList =
testElement.$.confirmClearData.get().getElementsByClassName(buttonType);
assertEquals(1, actionButtonList.length);
testElement.actionMenuModel_ = {
index: 0,
item: testElement.filteredList_[0],
};
actionButtonList[0].click();
// Check the dialog and overflow menu are now both closed.
assertFalse(testElement.$.confirmClearData.get().open);
assertFalse(overflowMenu.open);
}
test('cancelling the confirm dialog on clear data works', function() {
testElement.siteGroupMap.set(
TEST_MULTIPLE_SITE_GROUP.etldPlus1,
JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP)));
testElement.forceListUpdate_();
clearDataViaOverflowMenu('cancel-button');
});
test('clear data via overflow menu (no permission and no data)', function() {
// Test when all origins has no permission settings and no data.
// Clone this object to avoid propagating changes made in this test.
testElement.siteGroupMap.set(
TEST_MULTIPLE_SITE_GROUP.etldPlus1,
JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP)));
testElement.forceListUpdate_();
clearDataViaOverflowMenu('action-button');
// Ensure a call was made to clearEtldPlus1DataAndCookies.
assertEquals(1, browserProxy.getCallCount('clearEtldPlus1DataAndCookies'));
assertEquals(testElement.filteredList_.length, 0);
});
test('clear data via overflow menu (one origin has permission)', function() {
// Test when there is one origin has permissions settings.
// Clone this object to avoid propagating changes made in this test.
let siteGroup = JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP));
siteGroup.origins[0].hasPermissionSettings = true;
testElement.siteGroupMap.set(
siteGroup.etldPlus1, JSON.parse(JSON.stringify(siteGroup)));
testElement.forceListUpdate_();
clearDataViaOverflowMenu('action-button');
assertEquals(testElement.filteredList_.length, 1);
assertEquals(testElement.filteredList_[0].origins.length, 1);
});
test(
'clear data via overflow menu (one origin has permission and data)',
function() {
// Test when one origin has permission settings and data, clear data
// only clears the data and cookies.
siteGroup = JSON.parse(JSON.stringify(TEST_MULTIPLE_SITE_GROUP));
siteGroup.origins[0].hasPermissionSettings = true;
siteGroup.origins[0].usage = 100;
siteGroup.origins[0].numCookies = 3;
testElement.siteGroupMap.set(
siteGroup.etldPlus1, JSON.parse(JSON.stringify(siteGroup)));
testElement.forceListUpdate_();
clearDataViaOverflowMenu('action-button');
assertEquals(testElement.filteredList_.length, 1);
assertEquals(testElement.filteredList_[0].origins.length, 1);
assertTrue(
testElement.filteredList_[0].origins[0].hasPermissionSettings);
assertEquals(testElement.filteredList_[0].origins[0].usage, 0);
assertEquals(testElement.filteredList_[0].origins[0].numCookies, 0);
});
});