Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
AddonTestUtils.init(this);
AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"1",
"42"
);
add_task(async function setup() {
await AddonTestUtils.promiseStartupManager();
});
add_task(async function test_method_return_runtime_port() {
await runExtensionAPITest("API method returns an ExtensionPort instance", {
backgroundScript({ testAsserts }) {
try {
browser.mockExtensionAPI.methodReturnsPort("port-create-error");
throw new Error("methodReturnsPort should have raised an exception");
} catch (err) {
testAsserts.equal(
err?.message,
"An unexpected error occurred",
"Got the expected error"
);
}
const port = browser.mockExtensionAPI.methodReturnsPort(
"port-create-success"
);
testAsserts.equal(!!port, true, "Got a port");
testAsserts.equal(
typeof port.name,
"string",
"port.name should be a string"
);
testAsserts.equal(
typeof port.sender,
"object",
"port.sender should be an object"
);
testAsserts.equal(
typeof port.disconnect,
"function",
"port.disconnect method"
);
testAsserts.equal(
typeof port.postMessage,
"function",
"port.postMessage method"
);
testAsserts.equal(
typeof port.onDisconnect?.addListener,
"function",
"port.onDisconnect.addListener method"
);
testAsserts.equal(
typeof port.onMessage?.addListener,
"function",
"port.onDisconnect.addListener method"
);
return new Promise(resolve => {
let messages = [];
port.onDisconnect.addListener(() => resolve(messages));
port.onMessage.addListener((...args) => {
messages.push(args);
});
});
},
assertResults({ testError, testResult }) {
Assert.deepEqual(testError, null, "Got no error as expected");
Assert.deepEqual(
testResult,
[
[1, 2],
[3, 4],
[5, 6],
],
"Got the expected results"
);
},
mockAPIRequestHandler(policy, request) {
if (request.apiName == "methodReturnsPort") {
if (request.args[0] == "port-create-error") {
return {
type: Ci.mozIExtensionAPIRequestResult.RETURN_VALUE,
value: "not-a-valid-port",
};
}
return {
type: Ci.mozIExtensionAPIRequestResult.RETURN_VALUE,
value: {
portId: "port-id-1",
name: "a-port-name",
},
};
} else if (request.requestType == "addListener") {
if (request.apiObjectType !== "Port") {
throw new Error(`Unexpected objectType ${request}`);
}
switch (request.apiName) {
case "onDisconnect":
this._onDisconnectCb = request.eventListener;
return;
case "onMessage":
Promise.resolve().then(async () => {
await request.eventListener.callListener([1, 2]);
await request.eventListener.callListener([3, 4]);
await request.eventListener.callListener([5, 6]);
this._onDisconnectCb.callListener([]);
});
return;
}
} else if (
request.requestType == "getProperty" &&
request.apiObjectType == "Port" &&
request.apiName == "sender"
) {
return {
type: Ci.mozIExtensionAPIRequestResult.RETURN_VALUE,
value: { id: "fake-sender-id-prop" },
};
}
throw new Error(`Unexpected request: ${request}`);
},
});
});
add_task(async function test_port_as_event_listener_eventListener_param() {
await runExtensionAPITest(
"API event eventListener received an ExtensionPort parameter",
{
backgroundScript({ testAsserts, testLog }) {
const api = browser.mockExtensionAPI;
let listener;
return new Promise((resolve, reject) => {
testLog("addListener and wait for event to be fired");
listener = port => {
try {
testAsserts.equal(!!port, true, "Got a port parameter");
testAsserts.equal(
port.name,
"a-port-name-2",
"Got expected port.name value"
);
testAsserts.equal(
typeof port.disconnect,
"function",
"port.disconnect method"
);
testAsserts.equal(
typeof port.postMessage,
"function",
"port.disconnect method"
);
port.onMessage.addListener((msg, portArg) => {
if (msg === "test-done") {
testLog("Got a port.onMessage event");
testAsserts.equal(
portArg?.name,
"a-port-name-2",
"Got port as last argument"
);
testAsserts.equal(
portArg === port,
true,
"Got the same port instance as expected"
);
resolve();
} else {
reject(
new Error(
`port.onMessage got an unexpected message: ${msg}`
)
);
}
});
} catch (err) {
reject(err);
}
};
api.onTestEvent.addListener(listener);
});
},
assertResults({ testError }) {
Assert.deepEqual(testError, null, "Got no error as expected");
},
mockAPIRequestHandler(policy, request) {
if (
request.requestType == "addListener" &&
request.apiName == "onTestEvent"
) {
request.eventListener.callListener(["arg0", "arg1"], {
apiObjectType: Ci.mozIExtensionListenerCallOptions.RUNTIME_PORT,
apiObjectDescriptor: { portId: "port-id-2", name: "a-port-name-2" },
apiObjectPrepended: true,
});
return;
} else if (
request.requestType == "addListener" &&
request.apiObjectType == "Port" &&
request.apiObjectId == "port-id-2"
) {
request.eventListener.callListener(["test-done"], {
apiObjectType: Ci.mozIExtensionListenerCallOptions.RUNTIME_PORT,
apiObjectDescriptor: { portId: "port-id-2", name: "a-port-name-2" },
});
return;
}
throw new Error(`Unexpected request: ${request}`);
},
}
);
});