Bug 1963188 - part4 : add test for WindowsMediaFoundationCDMOriginsListService. r=media-playback-reviewers,padenot,dom-storage-reviewers,janv
Also fixed the test failure for test_open_and_databases.js. Differential Revision: https://phabricator.services.mozilla.com/D247368
This commit is contained in:
@@ -5,6 +5,29 @@
|
||||
|
||||
/* exported testSteps */
|
||||
async function testSteps() {
|
||||
const factory = (function () {
|
||||
if (typeof Cc === "undefined") {
|
||||
return indexedDB;
|
||||
}
|
||||
|
||||
// In xpcshell tests (where `Cc` is defined), we avoid using the system
|
||||
// principal because background services may create indexedDB databases
|
||||
// concurrently under that principal. To prevent interference and ensure
|
||||
// test isolation, we use a sandbox with a content principal instead.
|
||||
|
||||
const { PrincipalUtils } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/dom/quota/test/modules/PrincipalUtils.sys.mjs"
|
||||
);
|
||||
|
||||
const principal = PrincipalUtils.createPrincipal("https://example.com");
|
||||
|
||||
const sandbox = new Cu.Sandbox(principal, {
|
||||
wantGlobalProperties: ["indexedDB"],
|
||||
});
|
||||
|
||||
return Cu.evalInSandbox("indexedDB", sandbox);
|
||||
})();
|
||||
|
||||
const openInfos = [
|
||||
{ name: "foo-a", version: 1 },
|
||||
{ name: "foo-b", version: 1 },
|
||||
@@ -15,7 +38,7 @@ async function testSteps() {
|
||||
for (let index = 0; index < openInfos.length; index++) {
|
||||
const openInfo = openInfos[index];
|
||||
|
||||
const request = indexedDB.open(openInfo.name, openInfo.version);
|
||||
const request = factory.open(openInfo.name, openInfo.version);
|
||||
|
||||
await expectingUpgrade(request);
|
||||
|
||||
@@ -28,7 +51,7 @@ async function testSteps() {
|
||||
|
||||
info("Getting databases");
|
||||
|
||||
const databasesPromise = indexedDB.databases();
|
||||
const databasesPromise = factory.databases();
|
||||
|
||||
info("Opening databases");
|
||||
|
||||
@@ -37,7 +60,7 @@ async function testSteps() {
|
||||
for (let index = 0; index < openInfos.length; index++) {
|
||||
const openInfo = openInfos[index];
|
||||
|
||||
const request = indexedDB.open(openInfo.name, openInfo.version);
|
||||
const request = factory.open(openInfo.name, openInfo.version);
|
||||
|
||||
const promise = expectingSuccess(request);
|
||||
|
||||
|
||||
6
toolkit/components/media/tests/browser.toml
Normal file
6
toolkit/components/media/tests/browser.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[DEFAULT]
|
||||
subsuite = "media-bc"
|
||||
tags = "media-engine-compatible"
|
||||
skip-if = ["!wmfme"]
|
||||
|
||||
["browser_windowsMediaFoundationCDMOriginsListService.js"]
|
||||
@@ -0,0 +1,190 @@
|
||||
/* 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/. */
|
||||
|
||||
/* global add_task */
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* This test verifies that nsIWindowsMediaFoundationCDMOriginsListService
|
||||
* correctly triggers its callback and that the origin entries are propagated
|
||||
* as expected. It also checks that the result of calling
|
||||
* requestMediaKeySystemAccess for PlayReady is influenced by these entries.
|
||||
*/
|
||||
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
|
||||
BrowserTestUtils: "resource://testing-common/BrowserTestUtils.sys.mjs",
|
||||
TestUtils: "resource://testing-common/TestUtils.sys.mjs",
|
||||
});
|
||||
|
||||
const COLLECTION_NAME = "mfcdm-origins-list";
|
||||
const gRemoteSettings = RemoteSettings(COLLECTION_NAME);
|
||||
const gOriginsListService = Cc[
|
||||
"@mozilla.org/media/wmfcdm-origins-list;1"
|
||||
].getService(Ci.nsIWindowsMediaFoundationCDMOriginsListService);
|
||||
const gEntries = [
|
||||
{
|
||||
origin: "example.com",
|
||||
allowed: false,
|
||||
},
|
||||
{
|
||||
origin: "example.org",
|
||||
allowed: true,
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function testOriginsListServiceCallback() {
|
||||
info(`Simulate sending initial entries update to RemoteSettings`);
|
||||
await updateRemoteSettings(gEntries);
|
||||
|
||||
info(`Waiting for the callback to be triggered`);
|
||||
let waitUpdate = TestUtils.topicObserved("updated-entries");
|
||||
let callback = {
|
||||
onOriginsListLoaded(entries) {
|
||||
Assert.equal(entries.length, gEntries.length, "Entry count matches");
|
||||
for (let expected of gEntries) {
|
||||
let found = false;
|
||||
for (let i = 0; i < entries.length; i++) {
|
||||
let e = entries.queryElementAt(i, Ci.nsIOriginStatusEntry);
|
||||
if (
|
||||
e.origin === expected.origin &&
|
||||
e.status === (expected.allowed ? 1 : 0)
|
||||
) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assert.ok(
|
||||
found,
|
||||
`Expected origin (${expected.origin}/${expected.allowed}) found`
|
||||
);
|
||||
}
|
||||
Services.obs.notifyObservers(null, "updated-entries");
|
||||
},
|
||||
};
|
||||
gOriginsListService.setCallback(callback);
|
||||
await waitUpdate;
|
||||
|
||||
info(
|
||||
`Simulate adding another new record which should trigger callback again`
|
||||
);
|
||||
waitUpdate = TestUtils.topicObserved("updated-entries");
|
||||
gEntries.push({
|
||||
origin: "example.net",
|
||||
allowed: false,
|
||||
});
|
||||
await Promise.all([
|
||||
TestUtils.topicObserved("updated-entries"),
|
||||
updateRemoteSettings(gEntries),
|
||||
]);
|
||||
|
||||
info(
|
||||
`Remove old callback, and set a new callback, which should be triggered as well`
|
||||
);
|
||||
waitUpdate = TestUtils.topicObserved("updated-entries");
|
||||
gOriginsListService.removeCallback(callback);
|
||||
gOriginsListService.setCallback(callback);
|
||||
await waitUpdate;
|
||||
});
|
||||
|
||||
// This task follows the entries set in the previous task.
|
||||
add_task(async function testCheckCreateKeySystemAccess() {
|
||||
info(`Set pre-requirement prefs`);
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["media.wmf.media-engine.enabled", 2],
|
||||
// Our mock CDM doesn't implement 'IsTypeSupportedEx()', only 'IsTypeSupported()'
|
||||
["media.eme.playready.istypesupportedex", false],
|
||||
["media.eme.wmf.use-mock-cdm-for-external-cdms", true],
|
||||
],
|
||||
});
|
||||
|
||||
info(`Open a new tab and navigate`);
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(window.gBrowser);
|
||||
|
||||
// Test both preference values to control the default behavior when an origin
|
||||
// is not explicitly listed in the entries.
|
||||
// 3 : enabled allowed by default via Remote Settings
|
||||
// 4 : enabled blocked by default via Remote Settings
|
||||
const originFilterPrefs = [3, 4];
|
||||
for (let prefValue of originFilterPrefs) {
|
||||
const isDefaultAllowed = prefValue == 3;
|
||||
info(`Testing default behavior: ${isDefaultAllowed ? "allow" : "block"}`);
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["media.eme.mfcdm.origin-filter.enabled", prefValue]],
|
||||
});
|
||||
|
||||
const notSpecifiedDomains = [
|
||||
// Sub-domain, should follow the main domain result
|
||||
{
|
||||
origin: "test1.example.com",
|
||||
allowed: false,
|
||||
},
|
||||
{
|
||||
origin: "test1.example.org",
|
||||
allowed: true,
|
||||
},
|
||||
// Not specified and not a subdomain, follow the default result
|
||||
{
|
||||
origin: "example.onion",
|
||||
allowed: isDefaultAllowed,
|
||||
},
|
||||
];
|
||||
|
||||
for (let entry of gEntries.concat(notSpecifiedDomains)) {
|
||||
info(`Navigate to ${entry.origin}`);
|
||||
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, entry.origin);
|
||||
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
|
||||
info(`Creating a key system access, which should be ${entry.allowed}`);
|
||||
await checkCreateKeySystemAccess({
|
||||
tab,
|
||||
isAllowed: entry.allowed,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
info(`Remove tab`);
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
// Below are helper functions
|
||||
function updateRemoteSettings(entries) {
|
||||
return gRemoteSettings.emit("sync", {
|
||||
data: {
|
||||
current: entries,
|
||||
created: [],
|
||||
updated: [],
|
||||
deleted: [],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function checkCreateKeySystemAccess({ tab, isAllowed } = {}) {
|
||||
return SpecialPowers.spawn(
|
||||
tab.linkedBrowser,
|
||||
[isAllowed],
|
||||
async isAllowed_ => {
|
||||
const keySystem = "com.microsoft.playready.recommendation";
|
||||
const config = [
|
||||
{
|
||||
videoCapabilities: [
|
||||
{
|
||||
contentType: 'video/mp4; codecs="avc1.42E01E"',
|
||||
},
|
||||
],
|
||||
initDataTypes: ["cenc"],
|
||||
sessionTypes: ["temporary"],
|
||||
},
|
||||
];
|
||||
try {
|
||||
info("Attemping to create a key system access");
|
||||
await content.navigator.requestMediaKeySystemAccess(keySystem, config);
|
||||
ok(isAllowed_, "Created a key system access");
|
||||
} catch (e) {
|
||||
ok(!isAllowed_, "Not allowed to create a key system access");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user