toolkit/devtools/server/tests/browser/browser_storage_dynamic_windows.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 const Cu = Components.utils;
michael@0 2 Cu.import("resource://gre/modules/Services.jsm");
michael@0 3 let tempScope = {};
michael@0 4 Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope);
michael@0 5 Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope);
michael@0 6 Cu.import("resource://gre/modules/Promise.jsm", tempScope);
michael@0 7 let {DebuggerServer, DebuggerClient, Promise} = tempScope;
michael@0 8 tempScope = null;
michael@0 9
michael@0 10 const {StorageFront} = require("devtools/server/actors/storage");
michael@0 11 let gFront, gWindow;
michael@0 12
michael@0 13 const beforeReload = {
michael@0 14 cookies: {
michael@0 15 "test1.example.org": ["c1", "cs2", "c3", "uc1"],
michael@0 16 "sectest1.example.org": ["uc1", "cs2"]
michael@0 17 },
michael@0 18 localStorage: {
michael@0 19 "http://test1.example.org": ["ls1", "ls2"],
michael@0 20 "http://sectest1.example.org": ["iframe-u-ls1"]
michael@0 21 },
michael@0 22 sessionStorage: {
michael@0 23 "http://test1.example.org": ["ss1"],
michael@0 24 "http://sectest1.example.org": ["iframe-u-ss1", "iframe-u-ss2"]
michael@0 25 },
michael@0 26 indexedDB: {
michael@0 27 "http://test1.example.org": [
michael@0 28 JSON.stringify(["idb1", "obj1"]),
michael@0 29 JSON.stringify(["idb1", "obj2"]),
michael@0 30 JSON.stringify(["idb2", "obj3"]),
michael@0 31 ],
michael@0 32 "http://sectest1.example.org": []
michael@0 33 }
michael@0 34 };
michael@0 35
michael@0 36 function finishTests(client) {
michael@0 37 // Cleanup so that indexed db created from this test do not interfere next ones
michael@0 38
michael@0 39 /**
michael@0 40 * This method iterates over iframes in a window and clears the indexed db
michael@0 41 * created by this test.
michael@0 42 */
michael@0 43 let clearIDB = (w, i, c) => {
michael@0 44 if (w[i] && w[i].clear) {
michael@0 45 w[i].clearIterator = w[i].clear(() => clearIDB(w, i + 1, c));
michael@0 46 w[i].clearIterator.next();
michael@0 47 }
michael@0 48 else if (w[i] && w[i + 1]) {
michael@0 49 clearIDB(w, i + 1, c);
michael@0 50 }
michael@0 51 else {
michael@0 52 c();
michael@0 53 }
michael@0 54 };
michael@0 55
michael@0 56 let closeConnection = () => {
michael@0 57 // Forcing GC/CC to get rid of docshells and windows created by this test.
michael@0 58 forceCollections();
michael@0 59 client.close(() => {
michael@0 60 forceCollections();
michael@0 61 DebuggerServer.destroy();
michael@0 62 forceCollections();
michael@0 63 gFront = gWindow = DebuggerClient = DebuggerServer = null;
michael@0 64 finish();
michael@0 65 });
michael@0 66 }
michael@0 67 gWindow.clearIterator = gWindow.clear(() => {
michael@0 68 clearIDB(gWindow, 0, closeConnection);
michael@0 69 });
michael@0 70 gWindow.clearIterator.next();
michael@0 71 }
michael@0 72
michael@0 73 function testStores(data, client) {
michael@0 74 testWindowsBeforeReload(data);
michael@0 75 testReload().then(() =>
michael@0 76 testAddIframe()).then(() =>
michael@0 77 testRemoveIframe()).then(() =>
michael@0 78 finishTests(client));
michael@0 79 }
michael@0 80
michael@0 81 function testWindowsBeforeReload(data) {
michael@0 82 for (let storageType in beforeReload) {
michael@0 83 ok(data[storageType], storageType + " storage actor is present");
michael@0 84 is(Object.keys(data[storageType].hosts).length,
michael@0 85 Object.keys(beforeReload[storageType]).length,
michael@0 86 "Number of hosts for " + storageType + "match");
michael@0 87 for (let host in beforeReload[storageType]) {
michael@0 88 ok(data[storageType].hosts[host], "Host " + host + " is present");
michael@0 89 }
michael@0 90 }
michael@0 91 }
michael@0 92
michael@0 93 function markOutMatched(toBeEmptied, data, deleted) {
michael@0 94 if (!Object.keys(toBeEmptied).length) {
michael@0 95 info("Object empty")
michael@0 96 return;
michael@0 97 }
michael@0 98 ok(Object.keys(data).length,
michael@0 99 "Atleast some storage types should be present in deleted");
michael@0 100 for (let storageType in toBeEmptied) {
michael@0 101 if (!data[storageType]) {
michael@0 102 continue;
michael@0 103 }
michael@0 104 info("Testing for " + storageType);
michael@0 105 for (let host in data[storageType]) {
michael@0 106 ok(toBeEmptied[storageType][host], "Host " + host + " found");
michael@0 107 if (!deleted) {
michael@0 108 for (let item of data[storageType][host]) {
michael@0 109 let index = toBeEmptied[storageType][host].indexOf(item);
michael@0 110 ok(index > -1, "Item found - " + item);
michael@0 111 if (index > -1) {
michael@0 112 toBeEmptied[storageType][host].splice(index, 1);
michael@0 113 }
michael@0 114 }
michael@0 115 if (!toBeEmptied[storageType][host].length) {
michael@0 116 delete toBeEmptied[storageType][host];
michael@0 117 }
michael@0 118 }
michael@0 119 else {
michael@0 120 delete toBeEmptied[storageType][host];
michael@0 121 }
michael@0 122 }
michael@0 123 if (!Object.keys(toBeEmptied[storageType]).length) {
michael@0 124 delete toBeEmptied[storageType];
michael@0 125 }
michael@0 126 }
michael@0 127 }
michael@0 128
michael@0 129 function testReload() {
michael@0 130 info("Testing if reload works properly");
michael@0 131
michael@0 132 let shouldBeEmptyFirst = Cu.cloneInto(beforeReload, {});
michael@0 133 let shouldBeEmptyLast = Cu.cloneInto(beforeReload, {});
michael@0 134 let reloaded = Promise.defer();
michael@0 135
michael@0 136 let onStoresUpdate = data => {
michael@0 137 info("in stores update of testReload");
michael@0 138 // This might be second time stores update is happening, in which case,
michael@0 139 // data.deleted will be null.
michael@0 140 // OR.. This might be the first time on a super slow machine where both
michael@0 141 // data.deleted and data.added is missing in the first update.
michael@0 142 if (data.deleted) {
michael@0 143 markOutMatched(shouldBeEmptyFirst, data.deleted, true);
michael@0 144 }
michael@0 145
michael@0 146 if (!Object.keys(shouldBeEmptyFirst).length) {
michael@0 147 info("shouldBeEmptyFirst is empty now");
michael@0 148 }
michael@0 149
michael@0 150 // stores-update call might not have data.added for the first time on slow
michael@0 151 // machines, in which case, data.added will be null
michael@0 152 if (data.added) {
michael@0 153 markOutMatched(shouldBeEmptyLast, data.added);
michael@0 154 }
michael@0 155
michael@0 156 if (!Object.keys(shouldBeEmptyLast).length) {
michael@0 157 info("Everything to be received is received.");
michael@0 158 endTestReloaded();
michael@0 159 }
michael@0 160 };
michael@0 161
michael@0 162 let endTestReloaded = () => {
michael@0 163 gFront.off("stores-update", onStoresUpdate);
michael@0 164 reloaded.resolve();
michael@0 165 };
michael@0 166
michael@0 167 gFront.on("stores-update", onStoresUpdate);
michael@0 168
michael@0 169 content.location.reload();
michael@0 170 return reloaded.promise;
michael@0 171 }
michael@0 172
michael@0 173 function testAddIframe() {
michael@0 174 info("Testing if new iframe addition works properly");
michael@0 175 let reloaded = Promise.defer();
michael@0 176
michael@0 177 let shouldBeEmpty = {
michael@0 178 localStorage: {
michael@0 179 "https://sectest1.example.org": ["iframe-s-ls1"]
michael@0 180 },
michael@0 181 sessionStorage: {
michael@0 182 "https://sectest1.example.org": ["iframe-s-ss1"]
michael@0 183 },
michael@0 184 cookies: {
michael@0 185 "sectest1.example.org": ["sc1"]
michael@0 186 },
michael@0 187 indexedDB: {
michael@0 188 // empty because indexed db creation happens after the page load, so at
michael@0 189 // the time of window-ready, there was no indexed db present.
michael@0 190 "https://sectest1.example.org": []
michael@0 191 }
michael@0 192 };
michael@0 193
michael@0 194 let onStoresUpdate = data => {
michael@0 195 info("checking if the hosts list is correct for this iframe addition");
michael@0 196
michael@0 197 markOutMatched(shouldBeEmpty, data.added);
michael@0 198
michael@0 199 ok(!data.changed || !data.changed.cookies ||
michael@0 200 !data.changed.cookies["https://sectest1.example.org"],
michael@0 201 "Nothing got changed for cookies");
michael@0 202 ok(!data.changed || !data.changed.localStorage ||
michael@0 203 !data.changed.localStorage["https://sectest1.example.org"],
michael@0 204 "Nothing got changed for local storage");
michael@0 205 ok(!data.changed || !data.changed.sessionStorage ||
michael@0 206 !data.changed.sessionStorage["https://sectest1.example.org"],
michael@0 207 "Nothing got changed for session storage");
michael@0 208 ok(!data.changed || !data.changed.indexedDB ||
michael@0 209 !data.changed.indexedDB["https://sectest1.example.org"],
michael@0 210 "Nothing got changed for indexed db");
michael@0 211
michael@0 212 ok(!data.deleted || !data.deleted.cookies ||
michael@0 213 !data.deleted.cookies["https://sectest1.example.org"],
michael@0 214 "Nothing got deleted for cookies");
michael@0 215 ok(!data.deleted || !data.deleted.localStorage ||
michael@0 216 !data.deleted.localStorage["https://sectest1.example.org"],
michael@0 217 "Nothing got deleted for local storage");
michael@0 218 ok(!data.deleted || !data.deleted.sessionStorage ||
michael@0 219 !data.deleted.sessionStorage["https://sectest1.example.org"],
michael@0 220 "Nothing got deleted for session storage");
michael@0 221 ok(!data.deleted || !data.deleted.indexedDB ||
michael@0 222 !data.deleted.indexedDB["https://sectest1.example.org"],
michael@0 223 "Nothing got deleted for indexed db");
michael@0 224
michael@0 225 if (!Object.keys(shouldBeEmpty).length) {
michael@0 226 info("Everything to be received is received.");
michael@0 227 endTestReloaded();
michael@0 228 }
michael@0 229 };
michael@0 230
michael@0 231 let endTestReloaded = () => {
michael@0 232 gFront.off("stores-update", onStoresUpdate);
michael@0 233 reloaded.resolve();
michael@0 234 };
michael@0 235
michael@0 236 gFront.on("stores-update", onStoresUpdate);
michael@0 237
michael@0 238 let iframe = content.document.createElement("iframe");
michael@0 239 iframe.src = ALT_DOMAIN_SECURED + "storage-secured-iframe.html";
michael@0 240 content.document.querySelector("body").appendChild(iframe);
michael@0 241 return reloaded.promise;
michael@0 242 }
michael@0 243
michael@0 244 function testRemoveIframe() {
michael@0 245 info("Testing if iframe removal works properly");
michael@0 246 let reloaded = Promise.defer();
michael@0 247
michael@0 248 let shouldBeEmpty = {
michael@0 249 localStorage: {
michael@0 250 "http://sectest1.example.org": []
michael@0 251 },
michael@0 252 sessionStorage: {
michael@0 253 "http://sectest1.example.org": []
michael@0 254 }
michael@0 255 };
michael@0 256
michael@0 257 let onStoresUpdate = data => {
michael@0 258 info("checking if the hosts list is correct for this iframe deletion");
michael@0 259
michael@0 260 markOutMatched(shouldBeEmpty, data.deleted, true);
michael@0 261
michael@0 262 ok(!data.deleted.cookies || !data.deleted.cookies["sectest1.example.org"],
michael@0 263 "Nothing got deleted for Cookies as the same hostname is still present");
michael@0 264
michael@0 265 ok(!data.changed || !data.changed.cookies ||
michael@0 266 !data.changed.cookies["http://sectest1.example.org"],
michael@0 267 "Nothing got changed for cookies");
michael@0 268 ok(!data.changed || !data.changed.localStorage ||
michael@0 269 !data.changed.localStorage["http://sectest1.example.org"],
michael@0 270 "Nothing got changed for local storage");
michael@0 271 ok(!data.changed || !data.changed.sessionStorage ||
michael@0 272 !data.changed.sessionStorage["http://sectest1.example.org"],
michael@0 273 "Nothing got changed for session storage");
michael@0 274
michael@0 275 ok(!data.added || !data.added.cookies ||
michael@0 276 !data.added.cookies["http://sectest1.example.org"],
michael@0 277 "Nothing got added for cookies");
michael@0 278 ok(!data.added || !data.added.localStorage ||
michael@0 279 !data.added.localStorage["http://sectest1.example.org"],
michael@0 280 "Nothing got added for local storage");
michael@0 281 ok(!data.added || !data.added.sessionStorage ||
michael@0 282 !data.added.sessionStorage["http://sectest1.example.org"],
michael@0 283 "Nothing got added for session storage");
michael@0 284
michael@0 285 if (!Object.keys(shouldBeEmpty).length) {
michael@0 286 info("Everything to be received is received.");
michael@0 287 endTestReloaded();
michael@0 288 }
michael@0 289 };
michael@0 290
michael@0 291 let endTestReloaded = () => {
michael@0 292 gFront.off("stores-update", onStoresUpdate);
michael@0 293 reloaded.resolve();
michael@0 294 };
michael@0 295
michael@0 296 gFront.on("stores-update", onStoresUpdate);
michael@0 297
michael@0 298 for (let iframe of content.document.querySelectorAll("iframe")) {
michael@0 299 if (iframe.src.startsWith("http:")) {
michael@0 300 iframe.remove();
michael@0 301 break;
michael@0 302 }
michael@0 303 }
michael@0 304 return reloaded.promise;
michael@0 305 }
michael@0 306
michael@0 307 function test() {
michael@0 308 waitForExplicitFinish();
michael@0 309 addTab(MAIN_DOMAIN + "storage-dynamic-windows.html", function(doc) {
michael@0 310 try {
michael@0 311 // Sometimes debugger server does not get destroyed correctly by previous
michael@0 312 // tests.
michael@0 313 DebuggerServer.destroy();
michael@0 314 } catch (ex) { }
michael@0 315 DebuggerServer.init(function () { return true; });
michael@0 316 DebuggerServer.addBrowserActors();
michael@0 317
michael@0 318 let createConnection = () => {
michael@0 319 let client = new DebuggerClient(DebuggerServer.connectPipe());
michael@0 320 client.connect(function onConnect() {
michael@0 321 client.listTabs(function onListTabs(aResponse) {
michael@0 322 let form = aResponse.tabs[aResponse.selected];
michael@0 323 gFront = StorageFront(client, form);
michael@0 324
michael@0 325 gFront.listStores().then(data => testStores(data, client));
michael@0 326 });
michael@0 327 });
michael@0 328 };
michael@0 329
michael@0 330 /**
michael@0 331 * This method iterates over iframes in a window and setups the indexed db
michael@0 332 * required for this test.
michael@0 333 */
michael@0 334 let setupIDBInFrames = (w, i, c) => {
michael@0 335 if (w[i] && w[i].idbGenerator) {
michael@0 336 w[i].setupIDB = w[i].idbGenerator(() => setupIDBInFrames(w, i + 1, c));
michael@0 337 w[i].setupIDB.next();
michael@0 338 }
michael@0 339 else if (w[i] && w[i + 1]) {
michael@0 340 setupIDBInFrames(w, i + 1, c);
michael@0 341 }
michael@0 342 else {
michael@0 343 c();
michael@0 344 }
michael@0 345 };
michael@0 346 // Setup the indexed db in main window.
michael@0 347 gWindow = doc.defaultView.wrappedJSObject;
michael@0 348 gWindow.setupIDB = gWindow.idbGenerator(() => {
michael@0 349 setupIDBInFrames(gWindow, 0, createConnection);
michael@0 350 });
michael@0 351 gWindow.setupIDB.next();
michael@0 352 });
michael@0 353 }

mercurial