diff options
Diffstat (limited to 'dom/localstorage/test/unit/head.js')
-rw-r--r-- | dom/localstorage/test/unit/head.js | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/dom/localstorage/test/unit/head.js b/dom/localstorage/test/unit/head.js new file mode 100644 index 0000000000..eaca1ed173 --- /dev/null +++ b/dom/localstorage/test/unit/head.js @@ -0,0 +1,332 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Tests are expected to define testSteps. +/* globals testSteps */ + +const NS_ERROR_DOM_QUOTA_EXCEEDED_ERR = 22; + +function is(a, b, msg) { + Assert.equal(a, b, msg); +} + +function ok(cond, msg) { + Assert.ok(!!cond, msg); +} + +add_setup(function() { + do_get_profile(); + + enableTesting(); + + Cu.importGlobalProperties(["crypto"]); + + registerCleanupFunction(resetTesting); +}); + +function returnToEventLoop() { + return new Promise(function(resolve) { + executeSoon(resolve); + }); +} + +function enableTesting() { + Services.prefs.setBoolPref("dom.simpleDB.enabled", true); + Services.prefs.setBoolPref("dom.storage.testing", true); + + // xpcshell globals don't have associated clients in the Clients API sense, so + // we need to disable client validation so that the unit tests are allowed to + // use LocalStorage. + Services.prefs.setBoolPref("dom.storage.client_validation", false); + + Services.prefs.setBoolPref("dom.quotaManager.testing", true); +} + +function resetTesting() { + Services.prefs.clearUserPref("dom.quotaManager.testing"); + Services.prefs.clearUserPref("dom.storage.client_validation"); + Services.prefs.clearUserPref("dom.storage.testing"); + Services.prefs.clearUserPref("dom.simpleDB.enabled"); +} + +function setGlobalLimit(globalLimit) { + Services.prefs.setIntPref( + "dom.quotaManager.temporaryStorage.fixedLimit", + globalLimit + ); +} + +function resetGlobalLimit() { + Services.prefs.clearUserPref("dom.quotaManager.temporaryStorage.fixedLimit"); +} + +function setOriginLimit(originLimit) { + Services.prefs.setIntPref("dom.storage.default_quota", originLimit); +} + +function resetOriginLimit() { + Services.prefs.clearUserPref("dom.storage.default_quota"); +} + +function setTimeout(callback, timeout) { + let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + + timer.initWithCallback( + { + notify() { + callback(); + }, + }, + timeout, + Ci.nsITimer.TYPE_ONE_SHOT + ); + + return timer; +} + +function initStorage() { + return Services.qms.init(); +} + +function initTemporaryStorage() { + return Services.qms.initTemporaryStorage(); +} + +function initPersistentOrigin(principal) { + return Services.qms.initializePersistentOrigin(principal); +} + +function initTemporaryOrigin(persistence, principal) { + return Services.qms.initializeTemporaryOrigin(persistence, principal); +} + +function getOriginUsage(principal, fromMemory = false) { + let request = Services.qms.getUsageForPrincipal( + principal, + function() {}, + fromMemory + ); + + return request; +} + +function clear() { + let request = Services.qms.clear(); + + return request; +} + +function clearOriginsByPattern(pattern) { + let request = Services.qms.clearStoragesForOriginAttributesPattern(pattern); + + return request; +} + +function clearOriginsByPrefix(principal, persistence) { + let request = Services.qms.clearStoragesForPrincipal( + principal, + persistence, + null, + true + ); + + return request; +} + +function clearOrigin(principal, persistence) { + let request = Services.qms.clearStoragesForPrincipal(principal, persistence); + + return request; +} + +function reset() { + let request = Services.qms.reset(); + + return request; +} + +function resetOrigin(principal) { + let request = Services.qms.resetStoragesForPrincipal( + principal, + "default", + "ls" + ); + + return request; +} + +function installPackage(packageName) { + let currentDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + + let packageFile = currentDir.clone(); + packageFile.append(packageName + ".zip"); + + let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance( + Ci.nsIZipReader + ); + zipReader.open(packageFile); + + let entryNames = []; + let entries = zipReader.findEntries(null); + while (entries.hasMore()) { + let entry = entries.getNext(); + entryNames.push(entry); + } + entryNames.sort(); + + for (let entryName of entryNames) { + let zipentry = zipReader.getEntry(entryName); + + let file = getRelativeFile(entryName); + + if (zipentry.isDirectory) { + file.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0755", 8)); + } else { + let istream = zipReader.getInputStream(entryName); + + var ostream = Cc[ + "@mozilla.org/network/file-output-stream;1" + ].createInstance(Ci.nsIFileOutputStream); + ostream.init(file, -1, parseInt("0644", 8), 0); + + let bostream = Cc[ + "@mozilla.org/network/buffered-output-stream;1" + ].createInstance(Ci.nsIBufferedOutputStream); + bostream.init(ostream, 32768); + + bostream.writeFrom(istream, istream.available()); + + istream.close(); + bostream.close(); + } + } + + zipReader.close(); +} + +function getProfileDir() { + return Services.dirsvc.get("ProfD", Ci.nsIFile); +} + +// Given a "/"-delimited path relative to the profile directory, +// return an nsIFile representing the path. This does not test +// for the existence of the file or parent directories. +// It is safe even on Windows where the directory separator is not "/", +// but make sure you're not passing in a "\"-delimited path. +function getRelativeFile(relativePath) { + let profileDir = getProfileDir(); + + let file = profileDir.clone(); + relativePath.split("/").forEach(function(component) { + file.append(component); + }); + + return file; +} + +function repeatChar(count, ch) { + if (count == 0) { + return ""; + } + + let result = ch; + let count2 = count / 2; + + // Double the input until it is long enough. + while (result.length <= count2) { + result += result; + } + + // Use substring to hit the precise length target without using extra memory. + return result + result.substring(0, count - result.length); +} + +function getPrincipal(url, attrs) { + let uri = Services.io.newURI(url); + if (!attrs) { + attrs = {}; + } + return Services.scriptSecurityManager.createContentPrincipal(uri, attrs); +} + +function getCurrentPrincipal() { + return Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal); +} + +function getDefaultPrincipal() { + return getPrincipal("http://example.com"); +} + +function getSimpleDatabase(principal, persistence) { + let connection = Cc["@mozilla.org/dom/sdb-connection;1"].createInstance( + Ci.nsISDBConnection + ); + + if (!principal) { + principal = getDefaultPrincipal(); + } + + connection.init(principal, persistence); + + return connection; +} + +function getLocalStorage(principal) { + if (!principal) { + principal = getDefaultPrincipal(); + } + + return Services.domStorageManager.createStorage( + null, + principal, + principal, + "" + ); +} + +class RequestError extends Error { + constructor(resultCode, resultName) { + super(`Request failed (code: ${resultCode}, name: ${resultName})`); + this.name = "RequestError"; + this.resultCode = resultCode; + this.resultName = resultName; + } +} + +async function requestFinished(request) { + await new Promise(function(resolve) { + request.callback = function() { + resolve(); + }; + }); + + if (request.resultCode !== Cr.NS_OK) { + throw new RequestError(request.resultCode, request.resultName); + } + + return request.result; +} + +function loadSubscript(path) { + let file = do_get_file(path, false); + let uri = Services.io.newFileURI(file); + Services.scriptloader.loadSubScript(uri.spec); +} + +async function readUsageFromUsageFile(usageFile) { + let file = await File.createFromNsIFile(usageFile); + + let buffer = await new Promise(resolve => { + let reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.readAsArrayBuffer(file); + }); + + // Manually getting the lower 32-bits because of the lack of support for + // 64-bit values currently from DataView/JS (other than the BigInt support + // that's currently behind a flag). + let view = new DataView(buffer, 8, 4); + return view.getUint32(); +} |