Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

"use strict";
const { Schemas } = ChromeUtils.importESModule(
"resource://gre/modules/Schemas.sys.mjs"
);
const global = this;
let schemaJson = [
{
namespace: "noAllowedContexts",
properties: {
prop1: { type: "object" },
prop2: { type: "object", allowedContexts: ["test_zero", "test_one"] },
prop3: { type: "number", value: 1 },
prop4: { type: "number", value: 1, allowedContexts: ["numeric_one"] },
},
},
{
namespace: "defaultContexts",
defaultContexts: ["test_two"],
properties: {
prop1: { type: "object" },
prop2: { type: "object", allowedContexts: ["test_three"] },
prop3: { type: "number", value: 1 },
prop4: { type: "number", value: 1, allowedContexts: ["numeric_two"] },
},
},
{
namespace: "withAllowedContexts",
allowedContexts: ["test_four"],
properties: {
prop1: { type: "object" },
prop2: { type: "object", allowedContexts: ["test_five"] },
prop3: { type: "number", value: 1 },
prop4: { type: "number", value: 1, allowedContexts: ["numeric_three"] },
},
},
{
namespace: "withAllowedContextsAndDefault",
allowedContexts: ["test_six"],
defaultContexts: ["test_seven"],
properties: {
prop1: { type: "object" },
prop2: { type: "object", allowedContexts: ["test_eight"] },
prop3: { type: "number", value: 1 },
prop4: { type: "number", value: 1, allowedContexts: ["numeric_four"] },
},
},
{
namespace: "with_submodule",
defaultContexts: ["test_nine"],
types: [
{
id: "subtype",
type: "object",
functions: [
{
name: "noAllowedContexts",
type: "function",
parameters: [],
},
{
name: "allowedContexts",
allowedContexts: ["test_ten"],
type: "function",
parameters: [],
},
],
},
],
properties: {
prop1: { $ref: "subtype" },
prop2: { $ref: "subtype", allowedContexts: ["test_eleven"] },
},
},
];
add_task(async function testRestrictions() {
let url = "data:," + JSON.stringify(schemaJson);
await Schemas.load(url);
let results = {};
let localWrapper = {
manifestVersion: 2,
cloneScope: global,
shouldInject(ns, name, allowedContexts) {
name = ns ? ns + "." + name : name;
results[name] = allowedContexts.join(",");
return true;
},
getImplementation() {
// The actual implementation is not significant for this test.
// Let's take this opportunity to see if schema generation is free of
// exceptions even when somehow getImplementation does not return an
// implementation.
},
};
let root = {};
Schemas.inject(root, localWrapper);
function verify(path, expected) {
let obj = root;
for (let thing of path.split(".")) {
try {
obj = obj[thing];
} catch (e) {
// Blech.
}
}
let result = results[path];
equal(result, expected, path);
}
verify("noAllowedContexts", "");
verify("noAllowedContexts.prop1", "");
verify("noAllowedContexts.prop2", "test_zero,test_one");
verify("noAllowedContexts.prop3", "");
verify("noAllowedContexts.prop4", "numeric_one");
verify("defaultContexts", "");
verify("defaultContexts.prop1", "test_two");
verify("defaultContexts.prop2", "test_three");
verify("defaultContexts.prop3", "test_two");
verify("defaultContexts.prop4", "numeric_two");
verify("withAllowedContexts", "test_four");
verify("withAllowedContexts.prop1", "");
verify("withAllowedContexts.prop2", "test_five");
verify("withAllowedContexts.prop3", "");
verify("withAllowedContexts.prop4", "numeric_three");
verify("withAllowedContextsAndDefault", "test_six");
verify("withAllowedContextsAndDefault.prop1", "test_seven");
verify("withAllowedContextsAndDefault.prop2", "test_eight");
verify("withAllowedContextsAndDefault.prop3", "test_seven");
verify("withAllowedContextsAndDefault.prop4", "numeric_four");
verify("with_submodule", "");
verify("with_submodule.prop1", "test_nine");
verify("with_submodule.prop1.noAllowedContexts", "test_nine");
verify("with_submodule.prop1.allowedContexts", "test_ten");
verify("with_submodule.prop2", "test_eleven");
// Note: test_nine inherits allowed contexts from the namespace, not from
// submodule. There is no "defaultContexts" for submodule types to not
// complicate things.
verify("with_submodule.prop1.noAllowedContexts", "test_nine");
verify("with_submodule.prop1.allowedContexts", "test_ten");
// This is a constant, so it does not matter that getImplementation does not
// return an implementation since the API injector should take care of it.
equal(root.noAllowedContexts.prop3, 1);
Assert.throws(
() => root.noAllowedContexts.prop1,
/undefined/,
"Should throw when the implementation is absent."
);
});