Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
"use strict";
const { CombinedProvider } = ChromeUtils.importESModule(
"resource://gre/modules/EnterprisePoliciesParent.sys.mjs"
);
// A minimal stand-in for a real policies provider. CombinedProvider only
// reads the `policies` and `failed` members of the providers it is given.
function fakeProvider(policies, failed = false) {
return { policies, failed };
}
function combine(...providers) {
let combined = new CombinedProvider();
for (let provider of providers) {
combined.push(provider);
}
combined.mergePolicies();
return combined;
}
add_task(async function test_single_provider() {
let combined = combine(fakeProvider({ PolicyA: 1 }));
deepEqual(
combined.policies,
{ PolicyA: 1 },
"A single provider's policies pass through unchanged"
);
ok(combined.hasPolicies, "Combined provider has policies");
});
add_task(async function test_disjoint_providers_are_unioned() {
let combined = combine(
fakeProvider({ PolicyA: 1 }),
fakeProvider({ PolicyB: 2 })
);
deepEqual(
combined.policies,
{ PolicyA: 1, PolicyB: 2 },
"Non-overlapping policies from every provider are merged together"
);
});
add_task(async function test_later_provider_wins_on_conflict() {
// Providers are pushed in increasing order of precedence, so the one added
// last (the platform provider) wins on conflicting keys.
let combined = combine(
fakeProvider({ Shared: "json", OnlyJson: true }),
fakeProvider({ Shared: "platform", OnlyPlatform: true })
);
deepEqual(
combined.policies,
{ Shared: "platform", OnlyJson: true, OnlyPlatform: true },
"The higher-precedence provider overrides conflicting top-level policies"
);
});
add_task(async function test_precedence_chain_across_three_providers() {
let combined = combine(
fakeProvider({ Shared: "lowest" }),
fakeProvider({ Shared: "middle" }),
fakeProvider({ Shared: "highest" })
);
equal(
combined.policies.Shared,
"highest",
"The last-pushed provider wins across a chain of providers"
);
});
add_task(async function test_merge_is_top_level_only() {
// A conflicting top-level policy is replaced wholesale; the objects are not
// deep-merged, so sub-keys from the lower-precedence provider do not survive.
let combined = combine(
fakeProvider({ Nested: { fromJson: true, shared: "json" } }),
fakeProvider({ Nested: { shared: "platform" } })
);
deepEqual(
combined.policies.Nested,
{ shared: "platform" },
"Merging happens only at the top level; nested keys are not combined"
);
});
add_task(async function test_no_failure_when_no_provider_failed() {
ok(
!combine(fakeProvider({}), fakeProvider({})).failed,
"Combined provider does not fail when no provider failed"
);
});
add_task(async function test_failed_provider_with_no_policies_fails() {
// A provider failed and the merge produced no policies, so there is nothing
// to fall back on: the engine must surface the failure (e.g. a broken
// policies.json with no platform policies).
let combined = combine(fakeProvider(null, true), fakeProvider({}));
ok(!combined.hasPolicies, "No policies survived the merge");
ok(
combined.failed,
"A failed provider fails the engine when left policyless"
);
});
add_task(async function test_failed_provider_masked_by_policies() {
// One provider failed, but a higher-precedence provider supplied policies.
// The failure is ignored so the surviving policies still apply (e.g. a
// broken policies.json alongside valid platform/GPO policies).
let combined = combine(
fakeProvider(null, true),
fakeProvider({ PlatformPolicy: true })
);
ok(combined.hasPolicies, "The non-failed provider's policies survive");
ok(
!combined.failed,
"A failed provider does not fail the engine when policies are present"
);
});
add_task(async function test_empty_providers_have_no_policies() {
let combined = combine(fakeProvider({}), fakeProvider({}));
ok(
!combined.hasPolicies,
"Combining only empty providers yields no effective policies"
);
});