| Index: chrome/test/data/extensions/api_test/permissions/host_subsets/background.js
|
| diff --git a/chrome/test/data/extensions/api_test/permissions/host_subsets/background.js b/chrome/test/data/extensions/api_test/permissions/host_subsets/background.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3957bface9ed4840f140331ae64bf3693df19d59
|
| --- /dev/null
|
| +++ b/chrome/test/data/extensions/api_test/permissions/host_subsets/background.js
|
| @@ -0,0 +1,193 @@
|
| +// Copyright 2013 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.
|
| +
|
| +var ERROR = 'Optional permissions must be listed in extension manifest.';
|
| +var test = chrome.test;
|
| +
|
| +// The URL patterns that we've supposedly been granted access to so far. Use
|
| +// this to verify queried hosts for each test.
|
| +var grantedHosts = [];
|
| +
|
| +// Pushes a value onto an array, asserting that it's unique in the array.
|
| +function pushUniqueValue(array, value) {
|
| + test.assertEq(-1, array.indexOf(value));
|
| + array.push(value);
|
| +}
|
| +
|
| +// Removes a value from an array, asserting that it's unique in the array.
|
| +function removeUniqueValue(array, value) {
|
| + var indexOfValue = array.indexOf(value);
|
| + test.assertTrue(indexOfValue >= 0);
|
| + array.splice(indexOfValue, 1);
|
| + test.assertEq(-1, array.indexOf(value));
|
| +}
|
| +
|
| +// Asserts that two arrays are equal when treated as sets.
|
| +function assertSetEq(expected, actual) {
|
| + if (!actual)
|
| + actual = [];
|
| + test.assertEq(expected.slice().sort(), actual.slice().sort());
|
| +}
|
| +
|
| +// Validates that the origin permissions returned from getAll() and contains()
|
| +// match |grantedHosts|.
|
| +function checkGrantedHosts(callback) {
|
| + chrome.permissions.getAll(test.callbackPass(function(permissions) {
|
| + assertSetEq(grantedHosts, permissions.origins);
|
| + var countDown = grantedHosts.length;
|
| + if (countDown == 0) {
|
| + callback();
|
| + return;
|
| + }
|
| + grantedHosts.forEach(function(host) {
|
| + chrome.permissions.contains({origins: [host]},
|
| + test.callbackPass(function(contains) {
|
| + test.assertTrue(contains);
|
| + if (--countDown == 0)
|
| + callback();
|
| + }));
|
| + });
|
| + }));
|
| +}
|
| +
|
| +// Returns a function which requests access to a host, and afterwards checks
|
| +// that our expected host permissions agree with Chrome's.
|
| +function requestHost(host, expectedGranted, expectedError) {
|
| + return function(callback) {
|
| + chrome.permissions.request({origins: [host]},
|
| + test.callback(function(granted) {
|
| + if (granted)
|
| + pushUniqueValue(grantedHosts, host);
|
| + if (expectedGranted) {
|
| + test.assertTrue(
|
| + granted,
|
| + "Access to " + host + " was not granted, but should have been");
|
| + } else {
|
| + test.assertFalse(
|
| + granted,
|
| + "Access to " + host + " was granted, but should not have been");
|
| + }
|
| + checkGrantedHosts(callback);
|
| + }, expectedError));
|
| + };
|
| +}
|
| +
|
| +// Returns a function which removes access to a host, and afterwards checks
|
| +// that our expected host permissions agree with Chrome's.
|
| +function removeHost(host, expectedRemoved) {
|
| + return function(callback) {
|
| + chrome.permissions.remove({origins: [host]},
|
| + test.callbackPass(function(removed) {
|
| + if (removed) {
|
| + test.assertTrue(expectedRemoved, "Access to " + host + " removed");
|
| + removeUniqueValue(grantedHosts, host);
|
| + } else {
|
| + test.assertFalse(expectedRemoved, "Access to " + host + " not removed");
|
| + }
|
| + checkGrantedHosts(callback);
|
| + }));
|
| + }
|
| +}
|
| +
|
| +// Returns a function which checks that permissions.contains(host) returns
|
| +// |expected|.
|
| +function contains(host, expected) {
|
| + return function(callback) {
|
| + chrome.permissions.contains({origins: [host]},
|
| + test.callbackPass(function(result) {
|
| + test.assertEq(expected, result);
|
| + callback();
|
| + }));
|
| + };
|
| +}
|
| +
|
| +// Calls every function in |chain| passing each the next function to run as a
|
| +// single argument - except for the last function, which is *not* expected to
|
| +// have a callback.
|
| +//
|
| +// The test is kept alive until all callbacks in the chain have been run.
|
| +function chain(callbacks) {
|
| + var head = callbacks[0], tail = callbacks.slice(1);
|
| + if (tail.length == 0) {
|
| + head();
|
| + return;
|
| + }
|
| + var callbackCompleted = chrome.test.callbackAdded();
|
| + head(function() {
|
| + try {
|
| + chain(tail);
|
| + } finally {
|
| + callbackCompleted();
|
| + }
|
| + });
|
| +}
|
| +
|
| +function main() {
|
| + chain([
|
| + // Simple request #1.
|
| + contains('http://google.com/*', false),
|
| + requestHost('http://google.com/*', true),
|
| + contains('http://google.com/*', true),
|
| + contains('http://google.com/foo/*', true),
|
| + contains('http://google.com:1234/foo/*', true),
|
| + contains('http://www.google.com/*', false),
|
| +
|
| + // Simple request #2.
|
| + requestHost('http://*.yahoo.com/*', true),
|
| + contains('http://yahoo.com/*', true),
|
| + contains('http://yahoo.com/foo/*', true),
|
| + contains('http://www.yahoo.com/*', true),
|
| + contains('http://www.yahoo.com/foo/*', true),
|
| + contains('http://www.yahoo.com:5678/foo/*', true),
|
| +
|
| + // Can request access to a subset of a host that's allowed.
|
| + requestHost('http://yahoo.com/*', true),
|
| +
|
| + // Can remove it.
|
| + removeHost('http://yahoo.com/*', true),
|
| +
|
| + // However, since it's still granted by the *.yahoo.com/*
|
| + // permission, it's still considered to contain it.
|
| + contains('http://yahoo.com/*', true),
|
| +
|
| + // Can remove the whole host, though.
|
| + removeHost('http://*.yahoo.com/*', true),
|
| + contains('http://google.com/*', true),
|
| + contains('http://yahoo.com/*', false),
|
| + contains('http://www.yahoo.com/*', false),
|
| +
|
| + // Widening the net (and then deleting it).
|
| + requestHost('http://*.google.com/*', true),
|
| + contains('http://google.com/*', true),
|
| + contains('http://www.google.com/*', true),
|
| + removeHost('http://google.com/*', true),
|
| + contains('http://google.com/*', true),
|
| + contains('http://www.google.com/*', true),
|
| + removeHost('http://*.google.com/*', true),
|
| + contains('http://google.com/*', false),
|
| + contains('http://www.google.com/*', false),
|
| +
|
| + // https schemes should fail because they're not covered by
|
| + // this extension's optional permission pattern.
|
| + requestHost('https://google.com/*', false, ERROR),
|
| + requestHost('https://*.yahoo.com/*', false, ERROR),
|
| +
|
| + // There is a sneaky ftp://ftp.example.com/* pattern in the
|
| + // manifest. Test it.
|
| + requestHost('ftp://example.com/*', false, ERROR),
|
| + contains('ftp://example.com/*', false),
|
| + requestHost('ftp://www.example.com/*', false, ERROR),
|
| + contains('ftp://www.example.com/*', false),
|
| + requestHost('ftp://secret.ftp.example.com/*', false, ERROR),
|
| + contains('ftp://secret.ftp.example.com/*', false),
|
| + requestHost('ftp://ftp.example.com/*', true),
|
| + contains('ftp://ftp.example.com/*', true),
|
| + removeHost('ftp://ftp.example.com/*', true),
|
| + contains('ftp://ftp.example.com/*', false),
|
| +
|
| + // And finally...
|
| + test.succeed]);
|
| +}
|
| +
|
| +test.runTests([main]);
|
|
|