Search code examples
javascripteventsfirefox-addon-sdk

Test http-on-modify-request observer via sdk/system/events?


Is it possible to test a http-on-modify-request-Observer?

The events module offers an emit(type, event) method to create Firefox events. To test a module listening to a http-on-modify-request, you can set the type to http-on-modify-request. The question is how to set the event parameters to mimic a web request? The documentation states

event : object
An optional object with data and subject attributes. data refers to a string that you would like to pass through this event. subject should refer to the actual actor/subject of this event (ie: the object emitting the event).

Setting event.data gets passed on as the data parameter of the observer, same for f.ex. a string as an event.subject, but when I tried to pass an object with a QueryInterface-function, it did not work:

events.emit("http-on-modify-request", {"subject": {
    QueryInterface : function() {
        return {"URI": {"spec": 'mock://URI.spec'}}
    }}});

Code to be tested is very similar to https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/system_events.


@humanoid's answer to use

obs.notifyObservers(
    { QueryInterface : function() {
        return {"URI": NetUtil.newURI("mock://URI.spec") };
    }},
    "http-on-modify-request",
    null);

failed with

JavaScript Error: "NS_NOINTERFACE: Component returned failure code: 0x80004002 (NS_NOINTERFACE) [nsISupports.QueryInterface]" {file: "resource://gre/modules/commonjs/toolkit/loader.js -> resource://addon-id/caller.js" line: xy}]


Solution

  • The emit method from sdk/system/events is not useful to create observer notifications that look like notifications from Firefox, because it adds wrappers to ensure weak references.

    Instead I would suggest to use the "vanilla" observer service, for example from Services.jsm:

    const { Services: { obs } } = require("resource://gre/modules/Services.jsm");