gecko/netwerk/test/unit/test_bug248970_cache.js
Ehsan Akhgari 5236854e21 Bug 741059 - Part 1: Add APIs to nsIChannel to allow callers to override the private bit on the channel; r=jduell
This is probably the worst patch that I have ever written!

We add a setPrivate method to nsIPrivateBrowsingChannel which will be
implemented by channels who care about private browsing.  This allows the
client to explicitly override the private bit on the channel.
NS_UsePrivateBrowsing is also taught about this override bit using the
internal nsIPrivateBrowsingChannel::IsPrivateModeOverriden API.  This patch
implements the new API for HTTP, FTP and wyciwyg channels.  This also
modifies the IPC implementations of these channels to correctly transfer that
bit to the parent process if it has been set in the child process channel.
2012-09-04 20:37:45 -04:00

212 lines
5.9 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
// names for cache devices
const kDiskDevice = "disk";
const kMemoryDevice = "memory";
const kOfflineDevice = "offline";
const kPrivate = "private";
const kCacheA = "cache-A";
const kCacheA2 = "cache-A2";
const kCacheB = "cache-B";
const kCacheC = "cache-C";
const kTestContent = "test content";
// the name for our cache session
const kPrivateBrowsing = "PrivateBrowsing";
function check_devices_available(devices) {
var cs = get_cache_service();
var found_devices = [];
var visitor = {
visitDevice: function (deviceID, deviceInfo) {
found_devices.push(deviceID);
return false;
},
visitEntry: function (deviceID, entryInfo) {
do_throw("nsICacheVisitor.visitEntry should not be called " +
"when checking the availability of devices");
}
};
// get the list of active devices
cs.visitEntries(visitor);
// see if any of the required devices was missing
if (devices.sort().toString() != found_devices.sort().toString()) {
do_throw("Expected to find these devices: \"" + devices.sort().toString() +
"\", but found these instead: \"" + found_devices.sort().toString() + "\"");
}
// see if any extra devices have been found
if (found_devices.length > devices.length) {
do_throw("Expected to find these devices: [" + devices.join(", ") +
"], but instead got: [" + found_devices.join(", ") + "]");
}
}
function make_input_stream_scriptable(input) {
var wrapper = Cc["@mozilla.org/scriptableinputstream;1"].
createInstance(Ci.nsIScriptableInputStream);
wrapper.init(input);
return wrapper;
}
const entries = [
// key content device should exist after leaving PB
[kCacheA, kTestContent, kMemoryDevice, true],
[kCacheA2, kTestContent, kPrivate, false],
[kCacheB, kTestContent, kDiskDevice, true],
[kCacheC, kTestContent, kOfflineDevice, true]
]
function get_storage_policy(device)
{
switch (device) {
case kDiskDevice:
return Ci.nsICache.STORE_ON_DISK;
case kOfflineDevice:
return Ci.nsICache.STORE_OFFLINE;
case kMemoryDevice:
case kPrivate:
return Ci.nsICache.STORE_IN_MEMORY;
}
do_throw("unknown device");
}
var store_idx;
var store_cb = null;
function store_entries(cb)
{
if (cb) {
store_cb = cb;
store_idx = 0;
}
if (store_idx == entries.length) {
do_execute_soon(store_cb);
return;
}
var cache = get_cache_service();
var session = cache.createSession(kPrivateBrowsing,
get_storage_policy(entries[store_idx][2]),
Ci.nsICache.STREAM_BASED);
if (entries[store_idx][2] == kPrivate) {
session.isPrivate = true;
}
session.asyncOpenCacheEntry(entries[store_idx][0],
Ci.nsICache.ACCESS_WRITE,
store_data);
}
var store_data = {
onCacheEntryAvailable: function oCEA(entry, access, status) {
do_check_eq(status, Cr.NS_OK);
var os = entry.openOutputStream(0);
var written = os.write(entries[store_idx][1], entries[store_idx][1].length);
if (written != entries[store_idx][1].length) {
do_throw("os.write has not written all data!\n" +
" Expected: " + entries[store_idx][1].length + "\n" +
" Actual: " + written + "\n");
}
os.close();
entry.close();
store_idx++;
do_execute_soon(store_entries);
}
};
var check_idx;
var check_cb = null;
var check_pb_exited;
function check_entries(cb, pbExited)
{
if (cb) {
check_cb = cb;
check_idx = 0;
check_pb_exited = pbExited;
}
if (check_idx == entries.length) {
do_execute_soon(check_cb);
return;
}
var cache = get_cache_service();
var session = cache.createSession(kPrivateBrowsing,
get_storage_policy(entries[check_idx][2]),
Ci.nsICache.STREAM_BASED);
if (entries[check_idx][2] == kPrivate) {
session.isPrivate = true;
}
session.asyncOpenCacheEntry(entries[check_idx][0],
Ci.nsICache.ACCESS_READ,
check_data);
}
var check_data = {
onCacheEntryAvailable: function oCEA(entry, access, status) {
if (!check_pb_exited || entries[check_idx][3]) {
do_check_eq(status, Cr.NS_OK);
var is = make_input_stream_scriptable(entry.openInputStream(0));
var read = is.read(is.available());
is.close();
entry.close();
do_check_eq(read, entries[check_idx][1]);
} else {
do_check_eq(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND);
}
check_idx++;
do_execute_soon(check_entries);
}
};
function run_test() {
// Simulate a profile dir for xpcshell
do_get_profile();
// Start off with an empty cache
evict_cache_entries();
// Store cache-A, cache-A2, cache-B and cache-C
store_entries(run_test2);
do_test_pending();
}
function run_test2() {
// Make sure all three cache devices are available initially
check_devices_available([kMemoryDevice, kDiskDevice, kOfflineDevice]);
// Check if cache-A, cache-A2, cache-B and cache-C are available
check_entries(run_test3, false);
}
function run_test3() {
// Simulate all private browsing instances being closed
var obsvc = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
obsvc.notifyObservers(null, "last-pb-context-exited", null);
// Make sure all three cache devices are still available
check_devices_available([kMemoryDevice, kDiskDevice, kOfflineDevice]);
// Make sure the memory device is not empty
do_check_eq(get_device_entry_count(kMemoryDevice), 1);
// Check if cache-A is gone, and cache-B and cache-C are still available
check_entries(do_test_finished, true);
}