Bug 950399 - Tests for domain cookies r=yoric
authorTim Taubert <ttaubert@mozilla.com>
Thu, 15 Jan 2015 13:09:02 +0100
changeset 224323 def4cd55d1f99ff281d5e4fdc732b49df6cf6df5
parent 224322 17b3a6d3ee1a126de2becd6bdc99798ef4898aa5
child 224324 0f3b187814d7df01b8155ac8ee14fdd2ab87a6bf
push id54190
push userkwierso@gmail.com
push dateSat, 17 Jan 2015 02:06:29 +0000
treeherdermozilla-inbound@369a8f14ccf8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyoric
bugs950399
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 950399 - Tests for domain cookies r=yoric
browser/components/sessionstore/test/browser.ini
browser/components/sessionstore/test/browser_cookies.js
browser/components/sessionstore/test/browser_cookies.sjs
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -7,16 +7,17 @@
 # browser_589246.js is disabled for leaking browser windows (bug 752467)
 # browser_580512.js is disabled for leaking browser windows (bug 752467)
 
 [DEFAULT]
 support-files =
   head.js
   content.js
   content-forms.js
+  browser_cookies.sjs
   browser_formdata_sample.html
   browser_formdata_xpath_sample.html
   browser_frametree_sample.html
   browser_frametree_sample_frameset.html
   browser_frame_history_index.html
   browser_frame_history_index2.html
   browser_frame_history_index_blank.html
   browser_frame_history_a.html
@@ -60,16 +61,17 @@ support-files =
 
 [browser_aboutPrivateBrowsing.js]
 [browser_aboutSessionRestore.js]
 [browser_attributes.js]
 [browser_backup_recovery.js]
 [browser_broadcast.js]
 [browser_capabilities.js]
 [browser_cleaner.js]
+[browser_cookies.js]
 [browser_crashedTabs.js]
 skip-if = !e10s || os == "linux" # Waiting on OMTC enabled by default on Linux (Bug 994541)
 [browser_dying_cache.js]
 [browser_dynamic_frames.js]
 [browser_form_restore_events.js]
 [browser_formdata.js]
 skip-if = buildapp == 'mulet'
 [browser_formdata_format.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_cookies.js
@@ -0,0 +1,175 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const PATH = "/browser/browser/components/sessionstore/test/";
+
+/**
+ * Remove all cookies to start off a clean slate.
+ */
+add_task(function* test_setup() {
+  Services.cookies.removeAll();
+});
+
+/**
+ * Test multiple scenarios with different Set-Cookie header domain= params.
+ */
+add_task(function* test_run() {
+  // Set-Cookie: foobar=random()
+  // The domain of the cookie should be the request domain (www.example.com).
+  // We should collect data only for the request domain, no parent or subdomains.
+  yield testCookieCollection({
+    host: "http://www.example.com",
+    cookieHost: "www.example.com",
+    cookieURIs: ["http://www.example.com" + PATH],
+    noCookieURIs: ["http://example.com/" + PATH]
+  });
+
+  // Set-Cookie: foobar=random()
+  // The domain of the cookie should be the request domain (example.com).
+  // We should collect data only for the request domain, no parent or subdomains.
+  yield testCookieCollection({
+    host: "http://example.com",
+    cookieHost: "example.com",
+    cookieURIs: ["http://example.com" + PATH],
+    noCookieURIs: ["http://www.example.com/" + PATH]
+  });
+
+  // Set-Cookie: foobar=random(); Domain=example.com
+  // The domain of the cookie should be the given one (.example.com).
+  // We should collect data for the given domain and its subdomains.
+  yield testCookieCollection({
+    host: "http://example.com",
+    domain: "example.com",
+    cookieHost: ".example.com",
+    cookieURIs: ["http://example.com" + PATH, "http://www.example.com/" + PATH],
+    noCookieURIs: ["about:robots"]
+  });
+
+  // Set-Cookie: foobar=random(); Domain=.example.com
+  // The domain of the cookie should be the given one (.example.com).
+  // We should collect data for the given domain and its subdomains.
+  yield testCookieCollection({
+    host: "http://example.com",
+    domain: ".example.com",
+    cookieHost: ".example.com",
+    cookieURIs: ["http://example.com" + PATH, "http://www.example.com/" + PATH],
+    noCookieURIs: ["about:robots"]
+  });
+
+  // Set-Cookie: foobar=random(); Domain=www.example.com
+  // The domain of the cookie should be the given one (.www.example.com).
+  // We should collect data for the given domain and its subdomains.
+  yield testCookieCollection({
+    host: "http://www.example.com",
+    domain: "www.example.com",
+    cookieHost: ".www.example.com",
+    cookieURIs: ["http://www.example.com/" + PATH],
+    noCookieURIs: ["http://example.com"]
+  });
+
+  // Set-Cookie: foobar=random(); Domain=.www.example.com
+  // The domain of the cookie should be the given one (.www.example.com).
+  // We should collect data for the given domain and its subdomains.
+  yield testCookieCollection({
+    host: "http://www.example.com",
+    domain: ".www.example.com",
+    cookieHost: ".www.example.com",
+    cookieURIs: ["http://www.example.com/" + PATH],
+    noCookieURIs: ["http://example.com"]
+  });
+});
+
+/**
+ * Generic test function to check sessionstore's cookie collection module with
+ * different cookie domains given in the Set-Cookie header. See above for some
+ * usage examples.
+ */
+let testCookieCollection = Task.async(function (params) {
+  let tab = gBrowser.addTab("about:blank");
+  let browser = tab.linkedBrowser;
+
+  let urlParams = new URLSearchParams();
+  let value = Math.random();
+  urlParams.append("value", value);
+
+  if (params.domain) {
+    urlParams.append("domain", params.domain);
+  }
+
+  // Construct request URI.
+  let uri = `${params.host}${PATH}browser_cookies.sjs?${urlParams}`;
+
+  // Wait for the browser to load and the cookie to be set.
+  // These two events can probably happen in no particular order,
+  // so let's wait for them in parallel.
+  yield Promise.all([
+    waitForNewCookie(),
+    replaceCurrentURI(browser, uri)
+  ]);
+
+  // Check all URIs for which the cookie should be collected.
+  for (let uri of params.cookieURIs || []) {
+    yield replaceCurrentURI(browser, uri);
+
+    // Check the cookie.
+    let cookie = getCookie();
+    is(cookie.host, params.cookieHost, "cookie host is correct");
+    is(cookie.path, PATH, "cookie path is correct");
+    is(cookie.name, "foobar", "cookie name is correct");
+    is(cookie.value, value, "cookie value is correct");
+  }
+
+  // Check all URIs for which the cookie should NOT be collected.
+  for (let uri of params.noCookieURIs || []) {
+    yield replaceCurrentURI(browser, uri);
+
+    // Cookie should be ignored.
+    ok(!getCookie(), "no cookie collected");
+  }
+
+  // Clean up.
+  gBrowser.removeTab(tab);
+  Services.cookies.removeAll();
+});
+
+/**
+ * Replace the current URI of the given browser by loading a new URI. The
+ * browser's session history will be completely replaced. This function ensures
+ * that the parent process has the lastest shistory data before resolving.
+ */
+let replaceCurrentURI = Task.async(function* (browser, uri) {
+  // Replace the tab's current URI with the parent domain.
+  let flags = Ci.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY;
+  browser.loadURIWithFlags(uri, flags);
+  yield promiseBrowserLoaded(browser);
+
+  // Ensure the tab's session history is up-to-date.
+  TabState.flush(browser);
+});
+
+/**
+ * Waits for a new "*example.com" cookie to be added.
+ */
+function waitForNewCookie() {
+  return new Promise(resolve => {
+    Services.obs.addObserver(function observer(subj, topic, data) {
+      let cookie = subj.QueryInterface(Ci.nsICookie2);
+      if (data == "added" && cookie.host.endsWith("example.com")) {
+        Services.obs.removeObserver(observer, topic);
+        resolve();
+      }
+    }, "cookie-changed", false);
+  });
+}
+
+/**
+ * Retrieves the first cookie in the first window from the current sessionstore
+ * state.
+ */
+function getCookie() {
+  let state = JSON.parse(ss.getWindowState(window));
+  let cookies = state.windows[0].cookies || [];
+  return cookies[0] || null;
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_cookies.sjs
@@ -0,0 +1,21 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+Components.utils.importGlobalProperties(["URLSearchParams"]);
+
+function handleRequest(req, resp) {
+  resp.setStatusLine(req.httpVersion, 200);
+
+  let params = new URLSearchParams(req.queryString);
+  let value = params.get("value");
+
+  let domain = "";
+  if  (params.has("domain")) {
+    domain = `; Domain=${params.get("domain")}`;
+  }
+
+  resp.setHeader("Set-Cookie", `foobar=${value}${domain}`);
+  resp.write("<meta charset=utf-8>hi");
+}