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]); |