Bug 1242522 - [webext] Add MatchURLFilters xpcshell-test. r=kmag draft
authorLuca Greco <lgreco@mozilla.com>
Tue, 07 Jun 2016 18:09:25 +0200
changeset 377471 9ada9a00b552fe4b3be11d03eb0bcbae8051a00b
parent 377470 242b58c3a706aeca2bdea1e5732be2e93045108b
child 523360 7a26e47aa89d156184b439b81d2e7c8cfba6d542
push id20803
push userluca.greco@alcacoop.it
push dateFri, 10 Jun 2016 13:33:19 +0000
reviewerskmag
bugs1242522
milestone50.0a1
Bug 1242522 - [webext] Add MatchURLFilters xpcshell-test. r=kmag MozReview-Commit-ID: ETR51KDCSRm
toolkit/modules/tests/xpcshell/test_MatchURLFilters.js
toolkit/modules/tests/xpcshell/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js
@@ -0,0 +1,396 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+Components.utils.import("resource://gre/modules/MatchPattern.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+function createTestFilter({url, filters}) {
+  let m = new MatchURLFilters(filters);
+  return m.matches(url);
+}
+
+function expectPass({url, filters}) {
+  ok(createTestFilter({url, filters}),
+     `Expected match: ${JSON.stringify(filters)}, ${url}`);
+}
+
+function expectFail({url, filters}) {
+  ok(!createTestFilter({url, filters}),
+     `Expected no match: ${JSON.stringify(filters)}, ${url}`);
+}
+
+function expectThrow({url, filters, exceptionMessageContains}) {
+  let logData = {filters, url};
+
+  Assert.throws(
+    () => {
+      createTestFilter({url, filters});
+    },
+    exceptionMessageContains,
+    `Check received exception for expected message: ${JSON.stringify(logData)}`
+  );
+}
+
+add_task(function* test_match_url_filters() {
+  const shouldPass = true;
+  const shouldFail = true;
+  const shouldThrow = true;
+
+  var testCases = [
+    // Empty, undefined and null filters.
+    {shouldThrow, exceptionMessageContains: "filters array should not be empty",
+     filters: [], url: "http://mozilla.org",},
+    {shouldThrow, exceptionMessageContains: "filters should be an array",
+     filters: undefined, url: "http://mozilla.org"},
+    {shouldThrow, exceptionMessageContains: "filters should be an array",
+     filters: null, url: "http://mozilla.org"},
+
+    // Wrong formats (in a real webextension this will be blocked by the schema validation).
+    {shouldThrow, exceptionMessageContains: "filters should be an array", filters: {},
+     url: "http://mozilla.org"},
+    {shouldThrow, exceptionMessageContains: "filters should be an array",
+     filters: {nonExistentCriteria: true}, url: "http://mozilla.org", },
+    {shouldPass, filters: [{nonExistentCriteria: true}], url: "http://mozilla.org"},
+
+    // Schemes filter over various url schemes.
+    {shouldPass, filters: [{schemes: ["http"]}], url: "http://mozilla.org"},
+    {shouldPass, filters: [{schemes: ["https"]}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{schemes: ["ftp"]}], url: "ftp://fake/ftp/url"},
+    {shouldPass, filters: [{schemes: ["about"]}], url: "about:blank"},
+    {shouldPass, filters: [{schemes: ["data"]}], url: "data:,testDataURL"},
+    {shouldFail, filters: [{schemes: ["http"]}], url: "ftp://fake/ftp/url"},
+
+    // Multiple schemes: pass when at least one scheme matches.
+    {shouldPass, filters: [{schemes: ["https", "about"]}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{schemes: ["about", "https"]}], url: "https://mozilla.org"},
+    {shouldFail, filters: [{schemes: ["about", "http"]}], url: "https://mozilla.org"},
+
+    // Port filter: standard (implicit) ports.
+    {shouldPass, filters: [{ports: [443]}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{ports: [80]}], url: "http://mozilla.org"},
+    {shouldPass, filters: [{ports: [21]}], url: "ftp://ftp.mozilla.org"},
+
+    // Port filter: schemes without a default port.
+    {shouldFail, filters: [{ports: [-1]}], url: "about:blank"},
+    {shouldFail, filters: [{ports: [-1]}], url: "data:,testDataURL"},
+
+    {shouldFail, filters: [{ports: [[1, 65535]]}], url: "about:blank"},
+    {shouldFail, filters: [{ports: [[1, 65535]]}], url: "data:,testDataURL"},
+
+    // Host filters (hostEquals, hostContains, hostPrefix, hostSuffix): schemes with an host.
+    {shouldFail, filters: [{hostEquals: ""}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostEquals: null}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostEquals: "mozilla.org"}], url: "https://mozilla.org"},
+    {shouldFail, filters: [{hostEquals: "mozilla.com"}], url: "https://mozilla.org"},
+    // NOTE: trying at least once another valid protocol.
+    {shouldPass, filters: [{hostEquals: "mozilla.org"}], url: "ftp://mozilla.org"},
+    {shouldFail, filters: [{hostEquals: "mozilla.com"}], url: "ftp://mozilla.org"},
+    {shouldPass, filters: [{hostEquals: "mozilla.org"}], url: "https://mozilla.org:8888"},
+
+    {shouldPass, filters: [{hostContains: "moz"}], url: "https://mozilla.org"},
+    // NOTE: an implicit '.' char is inserted into the host.
+    {shouldPass, filters: [{hostContains: ".moz"}], url: "https://mozilla.org"},
+    {shouldFail, filters: [{hostContains: "com"}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostContains: ""}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostContains: null}], url: "https://mozilla.org"},
+
+    {shouldPass, filters: [{hostPrefix: "moz"}], url: "https://mozilla.org"},
+    {shouldFail, filters: [{hostPrefix: "org"}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostPrefix: ""}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostPrefix: null}], url: "https://mozilla.org"},
+
+    {shouldPass, filters: [{hostSuffix: ".org"}], url: "https://mozilla.org"},
+    {shouldFail, filters: [{hostSuffix: "moz"}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostSuffix: ""}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostSuffix: null}], url: "https://mozilla.org"},
+    {shouldPass, filters: [{hostSuffix: "lla.org"}], url: "https://mozilla.org:8888"},
+
+    // hostEquals: urls without an host.
+    // TODO: should we explicitly cover hostContains, hostPrefix, hostSuffix for
+    // these sub-cases?
+    {shouldFail, filters: [{hostEquals: "blank"}], url: "about:blank"},
+    {shouldFail, filters: [{hostEquals: "blank"}], url: "about://blank"},
+    {shouldFail, filters: [{hostEquals: "testDataURL"}], url: "data:,testDataURL"},
+    {shouldPass, filters: [{hostEquals: ""}], url: "about:blank"},
+    {shouldPass, filters: [{hostEquals: ""}], url: "about://blank"},
+    {shouldPass, filters: [{hostEquals: ""}], url: "data:,testDataURL"},
+
+    // Path filters (pathEquals, pathContains, pathPrefix, pathSuffix).
+    {shouldFail, filters: [{pathEquals: ""}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathEquals: null}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathEquals: "/test/path"}], url: "https://mozilla.org/test/path"},
+    {shouldFail, filters: [{pathEquals: "/wrong/path"}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathEquals: "/test/path"}], url: "https://mozilla.org:8888/test/path"},
+    // NOTE: trying at least once another valid protocol
+    {shouldPass, filters: [{pathEquals: "/test/path"}], url: "ftp://mozilla.org/test/path"},
+    {shouldFail, filters: [{pathEquals: "/wrong/path"}], url: "ftp://mozilla.org/test/path"},
+
+    {shouldPass, filters: [{pathContains: "st/"}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathContains: "/test"}], url: "https://mozilla.org/test/path"},
+    {shouldFail, filters: [{pathContains: "org"}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathContains: ""}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathContains: null}], url: "https://mozilla.org/test/path"},
+    {shouldFail, filters: [{pathContains: "param"}], url: "https://mozilla.org:8888/test/path?param=1"},
+    {shouldFail, filters: [{pathContains: "ref"}], url: "https://mozilla.org:8888/test/path#ref"},
+    {shouldPass, filters: [{pathContains: "st/pa"}], url: "https://mozilla.org:8888/test/path"},
+
+    {shouldPass, filters: [{pathPrefix: "/te"}], url: "https://mozilla.org/test/path"},
+    {shouldFail, filters: [{pathPrefix: "org/"}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathPrefix: ""}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathPrefix: null}], url: "https://mozilla.org/test/path"},
+
+    {shouldPass, filters: [{pathSuffix: "/path"}], url: "https://mozilla.org/test/path"},
+    {shouldFail, filters: [{pathSuffix: "th/"}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathSuffix: ""}], url: "https://mozilla.org/test/path"},
+    {shouldPass, filters: [{pathSuffix: null}], url: "https://mozilla.org/test/path"},
+    {shouldFail, filters: [{pathSuffix: "p=1"}], url: "https://mozilla.org:8888/test/path?p=1"},
+    {shouldFail, filters: [{pathSuffix: "ref"}], url: "https://mozilla.org:8888/test/path#ref"},
+
+    // Query filters (queryEquals, queryContains, queryPrefix, querySuffix).
+    {shouldFail, filters: [{queryEquals: ""}], url: "https://mozilla.org/?param=val"},
+    {shouldPass, filters: [{queryEquals: null}], url: "https://mozilla.org/?param=val"},
+    {shouldPass, filters: [{queryEquals: "param=val"}], url: "https://mozilla.org/?param=val"},
+    {shouldFail, filters: [{queryEquals: "?param=val"}], url: "https://mozilla.org/?param=val"},
+    {shouldFail, filters: [{queryEquals: "/path?param=val"}], url: "https://mozilla.org/path?param=val"},
+
+    // NOTE: about scheme urls cannot be matched by query.
+    {shouldFail, filters: [{queryEquals: "param=val"}], url: "about:blank?param=val"},
+    {shouldFail, filters: [{queryEquals: "param"}], url: "ftp://mozilla.org?param=val"},
+
+    {shouldPass, filters: [{queryContains: "ram"}], url: "https://mozilla.org/?param=val"},
+    {shouldPass, filters: [{queryContains: "=val"}], url: "https://mozilla.org/?param=val"},
+    {shouldFail, filters: [{queryContains: "?param"}], url: "https://mozilla.org/?param=val"},
+    {shouldFail, filters: [{queryContains: "path"}], url: "https://mozilla.org/path/?p=v#ref"},
+    {shouldPass, filters: [{queryContains: ""}], url: "https://mozilla.org/?param=val"},
+    {shouldPass, filters: [{queryContains: null}], url: "https://mozilla.org/?param=val"},
+
+    {shouldPass, filters: [{queryPrefix: "param"}], url: "https://mozilla.org/?param=val"},
+    {shouldFail, filters: [{queryPrefix: "p="}], url: "https://mozilla.org/?param=val"},
+    {shouldFail, filters: [{queryPrefix: "path"}], url: "https://mozilla.org/path?param=val"},
+    {shouldPass, filters: [{queryPrefix: ""}], url: "https://mozilla.org/?param=val"},
+    {shouldPass, filters: [{queryPrefix: null}], url: "https://mozilla.org/?param=val"},
+
+    {shouldPass, filters: [{querySuffix: "=val"}], url: "https://mozilla.org/?param=val"},
+    {shouldFail, filters: [{querySuffix: "=wrong"}], url: "https://mozilla.org/?param=val"},
+    {shouldPass, filters: [{querySuffix: ""}], url: "https://mozilla.org/?param=val"},
+    {shouldPass, filters: [{querySuffix: null}], url: "https://mozilla.org/?param=val"},
+
+    // URL filters (urlEquals, urlContains, urlPrefix, urlSuffix).
+    {shouldFail, filters: [{urlEquals: ""}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlEquals: null}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlEquals: "https://mozilla.org/?p=v#ref"}],
+     url: "https://mozilla.org/?p=v#ref"},
+    {shouldFail, filters: [{urlEquals: "https://mozilla.org/?p=v#ref2"}],
+     url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlEquals: "about:blank?p=v#ref"}], url: "about:blank?p=v#ref"},
+    {shouldPass, filters: [{urlEquals: "ftp://mozilla.org?p=v#ref"}],
+     url: "ftp://mozilla.org?p=v#ref"},
+
+    {shouldPass, filters: [{urlContains: "org/?p"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlContains: "=v#ref"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldFail, filters: [{urlContains: "ftp"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlContains: ""}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlContains: null}], url: "https://mozilla.org/?p=v#ref"},
+
+    {shouldPass, filters: [{urlPrefix: "http"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldFail, filters: [{urlPrefix: "moz"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlPrefix: ""}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlPrefix: null}], url: "https://mozilla.org/?p=v#ref"},
+
+    {shouldPass, filters: [{urlSuffix: "#ref"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldFail, filters: [{urlSuffix: "=wrong"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlSuffix: ""}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlSuffix: null}], url: "https://mozilla.org/?p=v#ref"},
+
+    // More url filters: urlMatches.
+    {shouldPass, filters: [{urlMatches: ".*://mozilla"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlMatches: ".*://mozilla"}], url: "ftp://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlMatches: ".*://.*/\?p"}], url: "ftp://mozilla.org/?p=v#ref"},
+    // NOTE: urlMatches should not match the url without the ref.
+    {shouldFail, filters: [{urlMatches: "v#ref$"}], url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{urlMatches: "^ftp"}], url: "ftp://mozilla.org/?p=v#ref"},
+
+    // More url filters: originAndPathMatches.
+    {shouldPass, filters: [{originAndPathMatches: ".*://mozilla"}],
+     url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{originAndPathMatches: ".*://mozilla"}],
+     url: "ftp://mozilla.org/?p=v#ref"},
+    // NOTE: urlMatches should not match the url without the query and the ref.
+    {shouldFail, filters: [{originAndPathMatches: ".*://.*/\?p"}],
+     url: "ftp://mozilla.org/?p=v#ref"},
+    {shouldFail, filters: [{originAndPathMatches: "v#ref$"}],
+     url: "https://mozilla.org/?p=v#ref"},
+    {shouldPass, filters: [{originAndPathMatches: "^ftp"}],
+     url: "ftp://mozilla.org/?p=v#ref"},
+
+    // Filter with all criteria: all matches, none matches, some matches.
+
+    // All matches.
+    {shouldPass, filters: [
+      {
+        schemes: ["https", "http"],
+        ports: [443, 80],
+        hostEquals: "www.mozilla.org",
+        hostContains: ".moz",
+        hostPrefix: "www",
+        hostSuffix: "org",
+        pathEquals: "/sub/path",
+        pathContains: "b/p",
+        pathPrefix: "/sub",
+        pathSuffix: "/path",
+        queryEquals: "p=v",
+        queryContains: "1=",
+        queryPrefix: "p1",
+        querySuffix: "=v",
+        urlEquals: "https://www.mozilla.org/sub/path?p1=v#ref",
+        urlContains: "org/sub",
+        urlPrefix: "https://moz",
+        urlSuffix: "#ref",
+        urlMatches: "v#ref$",
+        originAndPathMatches: ".*://moz.*/"
+      },
+    ], url: "https://www.mozilla.org/sub/path?p1=v#ref"},
+    // None matches.
+    {shouldFail, filters: [
+      {
+        schemes: ["http"],
+        ports: [80],
+        hostEquals: "mozilla.com",
+        hostContains: "www.moz",
+        hostPrefix: "www",
+        hostSuffix: "com",
+        pathEquals: "/wrong/path",
+        pathContains: "g/p",
+        pathPrefix: "/wrong",
+        pathSuffix: "/wrong",
+        queryEquals: "p2=v",
+        queryContains: "2=",
+        queryPrefix: "p2",
+        querySuffix: "=value",
+        urlEquals: "http://mozilla.com/sub/path?p1=v#ref",
+        urlContains: "com/sub",
+        urlPrefix: "http://moz",
+        urlSuffix: "#ref2",
+        urlMatches: "value#ref2$",
+        originAndPathMatches: ".*://moz.*com/"
+      },
+    ], url: "https://mozilla.org/sub/path?p1=v#ref"},
+    // Some matches
+    {shouldFail, filters: [
+      {
+        schemes: ["https"],
+        ports: [80],
+        hostEquals: "mozilla.com",
+        hostContains: "www.moz",
+        hostPrefix: "www",
+        hostSuffix: "com",
+        pathEquals: "/wrong/path",
+        pathContains: "g/p",
+        pathPrefix: "/wrong",
+        pathSuffix: "/wrong",
+        queryEquals: "p2=v",
+        queryContains: "2=",
+        queryPrefix: "p2",
+        querySuffix: "=value",
+        urlEquals: "http://mozilla.com/sub/path?p1=v#ref",
+        urlContains: "com/sub",
+        urlPrefix: "http://moz",
+        urlSuffix: "#ref2",
+        urlMatches: "value#ref2$",
+        originAndPathMatches: ".*://moz.*com/"
+      },
+    ], url: "https://mozilla.org/sub/path?p1=v#ref"},
+
+    // Filter with multiple filters: all matches, some matches, none matches.
+
+    // All matches.
+    {shouldPass, filters: [
+      {schemes: ["https", "http"]},
+      {ports: [443, 80]},
+      {hostEquals: "www.mozilla.org"},
+      {hostContains: ".moz"},
+      {hostPrefix: "www"},
+      {hostSuffix: "org"},
+      {pathEquals: "/sub/path"},
+      {pathContains: "b/p"},
+      {pathPrefix: "/sub"},
+      {pathSuffix: "/path"},
+      {queryEquals: "p=v"},
+      {queryContains: "1="},
+      {queryPrefix: "p1"},
+      {querySuffix: "=v"},
+      {urlEquals: "https://www.mozilla.org/sub/path?p1=v#ref"},
+      {urlContains: "org/sub"},
+      {urlPrefix: "https://moz"},
+      {urlSuffix: "#ref"},
+      {urlMatches: "v#ref$"},
+      {originAndPathMatches: ".*://moz.*/"},
+    ], url: "https://www.mozilla.org/sub/path?p1=v#ref"},
+
+    // None matches.
+    {shouldFail, filters: [
+      {schemes: ["http"]},
+      {ports: [80]},
+      {hostEquals: "mozilla.com"},
+      {hostContains: "www.moz"},
+      {hostPrefix: "www"},
+      {hostSuffix: "com"},
+      {pathEquals: "/wrong/path"},
+      {pathContains: "g/p"},
+      {pathPrefix: "/wrong"},
+      {pathSuffix: "/wrong"},
+      {queryEquals: "p2=v"},
+      {queryContains: "2="},
+      {queryPrefix: "p2"},
+      {querySuffix: "=value"},
+      {urlEquals: "http://mozilla.com/sub/path?p1=v#ref"},
+      {urlContains: "com/sub"},
+      {urlPrefix: "http://moz"},
+      {urlSuffix: "#ref2"},
+      {urlMatches: "value#ref2$"},
+      {originAndPathMatches: ".*://moz.*com/"},
+    ], url: "https://mozilla.org/sub/path?p1=v#ref"},
+
+    // Some matches.
+    {shouldPass, filters: [
+      {schemes: ["https"]},
+      {ports: [80]},
+      {hostEquals: "mozilla.com"},
+      {hostContains: "www.moz"},
+      {hostPrefix: "www"},
+      {hostSuffix: "com"},
+      {pathEquals: "/wrong/path"},
+      {pathContains: "g/p"},
+      {pathPrefix: "/wrong"},
+      {pathSuffix: "/wrong"},
+      {queryEquals: "p2=v"},
+      {queryContains: "2="},
+      {queryPrefix: "p2"},
+      {querySuffix: "=value"},
+      {urlEquals: "http://mozilla.com/sub/path?p1=v#ref"},
+      {urlContains: "com/sub"},
+      {urlPrefix: "http://moz"},
+      {urlSuffix: "#ref2"},
+      {urlMatches: "value#ref2$"},
+      {originAndPathMatches: ".*://moz.*com/"},
+    ], url: "https://mozilla.org/sub/path?p1=v#ref"},
+  ];
+
+  // Run all the the testCases defined above.
+  for (let currentTest of testCases) {
+    let {
+      shouldThrow, exceptionMessageContains,
+      shouldFail, url, filters,
+    } = currentTest;
+
+    if (shouldThrow) {
+      expectThrow({url, filters, exceptionMessageContains})
+    } else if (shouldFail) {
+      expectFail({url, filters});
+    } else {
+      expectPass({url, filters});
+    }
+  }
+});
--- a/toolkit/modules/tests/xpcshell/xpcshell.ini
+++ b/toolkit/modules/tests/xpcshell/xpcshell.ini
@@ -26,16 +26,18 @@ skip-if = toolkit == 'android'
 [test_jsesc.js]
 skip-if = toolkit == 'android'
 [test_Log.js]
 skip-if = toolkit == 'android'
 [test_MatchPattern.js]
 skip-if = toolkit == 'android'
 [test_MatchGlobs.js]
 skip-if = toolkit == 'android'
+[test_MatchURLFilters.js]
+skip-if = toolkit == 'android'
 [test_NewTabUtils.js]
 skip-if = toolkit == 'android'
 [test_ObjectUtils.js]
 skip-if = toolkit == 'android'
 [test_ObjectUtils_strict.js]
 skip-if = toolkit == 'android'
 [test_PermissionsUtils.js]
 skip-if = toolkit == 'android'