Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
const { UserContextManagerClass } = ChromeUtils.importESModule(
"chrome://remote/content/shared/UserContextManager.sys.mjs"
);
add_task(async function test_invalid() {
const userContextManager = new UserContextManagerClass();
// Check invalid types for hasUserContextId/getInternalIdById which expects
// a string.
for (const value of [null, undefined, 1, [], {}]) {
is(userContextManager.hasUserContextId(value), false);
is(userContextManager.getInternalIdById(value), null);
}
// Check an invalid value for hasUserContextId/getInternalIdById which expects
// either "default" or a UUID from Services.uuid.generateUUID.
is(userContextManager.hasUserContextId("foo"), false);
is(userContextManager.getInternalIdById("foo"), null);
// Check invalid types for getIdByInternalId which expects a number.
for (const value of [null, undefined, "foo", [], {}]) {
is(userContextManager.getIdByInternalId(value), null);
}
userContextManager.destroy();
});
add_task(async function test_default_context() {
const userContextManager = new UserContextManagerClass();
ok(
userContextManager.hasUserContextId("default"),
`Context id default is known by the manager`
);
ok(
userContextManager.getUserContextIds().includes("default"),
`Context id default is listed by the manager`
);
is(
userContextManager.getInternalIdById("default"),
0,
"Default user context has the expected internal id"
);
userContextManager.destroy();
});
add_task(async function test_new_internal_contexts() {
info("Create a new user context with ContextualIdentityService");
const beforeInternalId =
ContextualIdentityService.create("before").userContextId;
info("Create the UserContextManager");
const userContextManager = new UserContextManagerClass();
const beforeContextId =
userContextManager.getIdByInternalId(beforeInternalId);
assertContextAvailable(userContextManager, beforeContextId, beforeInternalId);
info("Create another user context with ContextualIdentityService");
const afterInternalId =
ContextualIdentityService.create("after").userContextId;
const afterContextId = userContextManager.getIdByInternalId(afterInternalId);
assertContextAvailable(userContextManager, afterContextId, afterInternalId);
info("Delete both user contexts");
ContextualIdentityService.remove(beforeInternalId);
ContextualIdentityService.remove(afterInternalId);
assertContextRemoved(userContextManager, afterContextId, afterInternalId);
assertContextRemoved(userContextManager, beforeContextId, beforeInternalId);
userContextManager.destroy();
});
add_task(async function test_create_remove_context() {
const userContextManager = new UserContextManagerClass();
for (const closeContextTabs of [true, false]) {
info("Create two contexts via createContext");
const userContextId1 = userContextManager.createContext();
const internalId1 = userContextManager.getInternalIdById(userContextId1);
assertContextAvailable(userContextManager, userContextId1);
const userContextId2 = userContextManager.createContext();
const internalId2 = userContextManager.getInternalIdById(userContextId2);
assertContextAvailable(userContextManager, userContextId2);
info("Create tabs in various user contexts");
const tabDefault = await addTab(gBrowser, url);
const tabContext1 = await addTab(gBrowser, url, {
userContextId: internalId1,
});
const tabContext2 = await addTab(gBrowser, url, {
userContextId: internalId2,
});
info("Remove the user context 1 via removeUserContext");
userContextManager.removeUserContext(userContextId1, { closeContextTabs });
assertContextRemoved(userContextManager, userContextId1, internalId1);
if (closeContextTabs) {
ok(!gBrowser.tabs.includes(tabContext1), "Tab context 1 is closed");
} else {
ok(gBrowser.tabs.includes(tabContext1), "Tab context 1 is not closed");
}
ok(gBrowser.tabs.includes(tabDefault), "Tab default is not closed");
ok(gBrowser.tabs.includes(tabContext2), "Tab context 2 is not closed");
info("Remove the user context 2 via removeUserContext");
userContextManager.removeUserContext(userContextId2, { closeContextTabs });
assertContextRemoved(userContextManager, userContextId2, internalId2);
if (closeContextTabs) {
ok(!gBrowser.tabs.includes(tabContext2), "Tab context 2 is closed");
} else {
ok(gBrowser.tabs.includes(tabContext2), "Tab context 2 is not closed");
}
ok(gBrowser.tabs.includes(tabDefault), "Tab default is not closed");
}
userContextManager.destroy();
});
add_task(async function test_create_context_prefix() {
const userContextManager = new UserContextManagerClass();
info("Create a context with a custom prefix via createContext");
const userContextId = userContextManager.createContext("test_prefix");
const internalId = userContextManager.getInternalIdById(userContextId);
const identity =
ContextualIdentityService.getPublicIdentityFromId(internalId);
ok(
identity.name.startsWith("test_prefix"),
"The new identity used the provided prefix"
);
userContextManager.removeUserContext(userContextId);
userContextManager.destroy();
});
add_task(async function test_several_managers() {
const manager1 = new UserContextManagerClass();
const manager2 = new UserContextManagerClass();
info("Create a context via manager1");
const contextId1 = manager1.createContext();
const internalId = manager1.getInternalIdById(contextId1);
assertContextUnknown(manager2, contextId1);
info("Retrieve the corresponding user context id in manager2");
const contextId2 = manager2.getIdByInternalId(internalId);
is(
typeof contextId2,
"string",
"manager2 has a valid id for the user context created by manager 1"
);
Assert.notEqual(
contextId1,
contextId2,
"manager1 and manager2 have different ids for the same internal context id"
);
info("Remove the user context via manager2");
manager2.removeUserContext(contextId2);
info("Check that the user context is removed from both managers");
assertContextRemoved(manager1, contextId1, internalId);
assertContextRemoved(manager2, contextId2, internalId);
manager1.destroy();
manager2.destroy();
});
function assertContextAvailable(manager, contextId, expectedInternalId = null) {
ok(
manager.getUserContextIds().includes(contextId),
`Context id ${contextId} is listed by the manager`
);
ok(
manager.hasUserContextId(contextId),
`Context id ${contextId} is known by the manager`
);
const internalId = manager.getInternalIdById(contextId);
if (expectedInternalId != null) {
is(internalId, expectedInternalId, "Internal id has the expected value");
}
is(
typeof internalId,
"number",
`Context id ${contextId} corresponds to a valid internal id (${internalId})`
);
is(
manager.getIdByInternalId(internalId),
contextId,
`Context id ${contextId} is returned for internal id ${internalId}`
);
ok(
ContextualIdentityService.getPublicUserContextIds().includes(internalId),
`User context for context id ${contextId} is found by ContextualIdentityService`
);
}
function assertContextUnknown(manager, contextId) {
ok(
!manager.getUserContextIds().includes(contextId),
`Context id ${contextId} is not listed by the manager`
);
ok(
!manager.hasUserContextId(contextId),
`Context id ${contextId} is not known by the manager`
);
is(
manager.getInternalIdById(contextId),
null,
`Context id ${contextId} does not match any internal id`
);
}
function assertContextRemoved(manager, contextId, internalId) {
assertContextUnknown(manager, contextId);
is(
manager.getIdByInternalId(internalId),
null,
`Internal id ${internalId} cannot be converted to user context id`
);
ok(
!ContextualIdentityService.getPublicUserContextIds().includes(internalId),
`Internal id ${internalId} is not found in ContextualIdentityService`
);
}