Files
palemoon27/toolkit/devtools/server/tests/browser/browser_storage_updates.js
T

244 lines
6.2 KiB
JavaScript

/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const {StorageFront} = require("devtools/server/actors/storage");
let gTests;
let gExpected;
let index = 0;
const beforeReload = {
cookies: ["test1.example.org", "sectest1.example.org"],
localStorage: ["http://test1.example.org", "http://sectest1.example.org"],
sessionStorage: ["http://test1.example.org", "http://sectest1.example.org"],
};
function finishTests(client) {
// Forcing GC/CC to get rid of docshells and windows created by this test.
forceCollections();
client.close(() => {
forceCollections();
DebuggerServer.destroy();
forceCollections();
gTests = null;
finish();
});
}
function markOutMatched(toBeEmptied, data, deleted) {
if (!Object.keys(toBeEmptied).length) {
info("Object empty")
return;
}
ok(Object.keys(data).length,
"Atleast some storage types should be present in deleted");
for (let storageType in toBeEmptied) {
if (!data[storageType]) {
continue;
}
info("Testing for " + storageType);
for (let host in data[storageType]) {
ok(toBeEmptied[storageType][host], "Host " + host + " found");
for (let item of data[storageType][host]) {
let index = toBeEmptied[storageType][host].indexOf(item);
ok(index > -1, "Item found - " + item);
if (index > -1) {
toBeEmptied[storageType][host].splice(index, 1);
}
}
if (!toBeEmptied[storageType][host].length) {
delete toBeEmptied[storageType][host];
}
}
if (!Object.keys(toBeEmptied[storageType]).length) {
delete toBeEmptied[storageType];
}
}
}
function onStoresCleared(data) {
if (data.sessionStorage || data.localStorage) {
let hosts = data.sessionStorage || data.localStorage;
info("Stores cleared required for session storage");
is(hosts.length, 1, "number of hosts is 1");
is(hosts[0], "http://test1.example.org",
"host matches for " + Object.keys(data)[0]);
gTests.next();
}
else {
ok(false, "Stores cleared should only be for local and sesion storage");
}
}
function onStoresUpdate({added, changed, deleted}) {
info("inside stores update for index " + index);
// Here, added, changed and deleted might be null even if they are required as
// per gExpected. This is fine as they might come in the next stores-update
// call or have already come in the previous one.
if (added) {
info("matching added object for index " + index);
markOutMatched(gExpected.added, added);
}
if (changed) {
info("matching changed object for index " + index);
markOutMatched(gExpected.changed, changed);
}
if (deleted) {
info("matching deleted object for index " + index);
markOutMatched(gExpected.deleted, deleted);
}
if ((!gExpected.added || !Object.keys(gExpected.added).length) &&
(!gExpected.changed || !Object.keys(gExpected.changed).length) &&
(!gExpected.deleted || !Object.keys(gExpected.deleted).length)) {
info("Everything expected has been received for index " + index);
index++;
gTests.next();
}
else {
info("Still some updates pending for index " + index);
}
}
function* UpdateTests(front, win, client) {
front.on("stores-update", onStoresUpdate);
// index 0
gExpected = {
added: {
cookies: {
"test1.example.org": ["c1", "c2"]
},
localStorage: {
"http://test1.example.org": ["l1"]
}
}
};
win.addCookie("c1", "foobar1");
win.addCookie("c2", "foobar2");
win.localStorage.setItem("l1", "foobar1");
yield undefined;
// index 1
gExpected = {
changed: {
cookies: {
"test1.example.org": ["c1"]
}
},
added: {
localStorage: {
"http://test1.example.org": ["l2"]
}
}
};
win.addCookie("c1", "new_foobar1");
win.localStorage.setItem("l2", "foobar2");
yield undefined;
// index 2
gExpected = {
deleted: {
cookies: {
"test1.example.org": ["c2"]
},
localStorage: {
"http://test1.example.org": ["l1"]
}
},
added: {
localStorage: {
"http://test1.example.org": ["l3"]
}
}
};
win.removeCookie("c2");
win.localStorage.removeItem("l1");
win.localStorage.setItem("l3", "foobar3");
yield undefined;
// index 3
gExpected = {
added: {
cookies: {
"test1.example.org": ["c3"]
},
sessionStorage: {
"http://test1.example.org": ["s1", "s2"]
}
},
changed: {
localStorage: {
"http://test1.example.org": ["l3"]
}
},
deleted: {
cookies: {
"test1.example.org": ["c1"]
},
localStorage: {
"http://test1.example.org": ["l2"]
}
}
};
win.removeCookie("c1");
win.addCookie("c3", "foobar3");
win.localStorage.removeItem("l2");
win.sessionStorage.setItem("s1", "foobar1");
win.sessionStorage.setItem("s2", "foobar2");
win.localStorage.setItem("l3", "new_foobar3");
yield undefined;
// index 4
gExpected = {
deleted: {
sessionStorage: {
"http://test1.example.org": ["s1"]
}
}
};
win.sessionStorage.removeItem("s1");
yield undefined;
// index 5
gExpected = {
deleted: {
cookies: {
"test1.example.org": ["c3"]
}
}
};
front.on("stores-cleared", onStoresCleared);
win.clear();
yield undefined;
// Another 2 more yield undefined s so as to wait for the "stores-cleared" to
// fire. One for Local Storage and other for Session Storage
yield undefined;
yield undefined;
front.off("stores-cleared", onStoresCleared);
front.off("stores-update", onStoresUpdate);
finishTests(client);
}
function test() {
addTab(MAIN_DOMAIN + "storage-updates.html").then(function(doc) {
initDebuggerServer();
let client = new DebuggerClient(DebuggerServer.connectPipe());
connectDebuggerClient(client).then(form => {
let front = StorageFront(client, form);
gTests = UpdateTests(front, doc.defaultView.wrappedJSObject,
client);
// Make an initial call to initialize the actor
front.listStores().then(() => gTests.next());
});
})
}