tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_client_request.js (5543B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test the DevToolsClient.request API.
      7 
      8 var gClient, gActorId;
      9 
     10 const { Actor } = require("resource://devtools/shared/protocol/Actor.js");
     11 
     12 class TestActor extends Actor {
     13  constructor(conn) {
     14    super(conn, { typeName: "test", methods: [] });
     15 
     16    this.requestTypes = {
     17      hello: this.hello,
     18      error: this.error,
     19    };
     20  }
     21 
     22  hello() {
     23    return { hello: "world" };
     24  }
     25 
     26  error() {
     27    return { error: "code", message: "human message" };
     28  }
     29 }
     30 
     31 function run_test() {
     32  ActorRegistry.addGlobalActor(
     33    {
     34      constructorName: "TestActor",
     35      constructorFun: TestActor,
     36    },
     37    "test"
     38  );
     39 
     40  DevToolsServer.init();
     41  DevToolsServer.registerAllActors();
     42 
     43  add_test(init);
     44  add_test(test_client_request_promise);
     45  add_test(test_client_request_promise_error);
     46  add_test(test_client_request_event_emitter);
     47  add_test(test_close_client_while_sending_requests);
     48  add_test(test_client_request_after_close);
     49  run_next_test();
     50 }
     51 
     52 function init() {
     53  gClient = new DevToolsClient(DevToolsServer.connectPipe());
     54  gClient
     55    .connect()
     56    .then(() => gClient.mainRoot.rootForm)
     57    .then(response => {
     58      gActorId = response.test;
     59      run_next_test();
     60    });
     61 }
     62 
     63 function checkStack(expectedName) {
     64  let stack = Components.stack;
     65  while (stack) {
     66    info(stack.name);
     67    if (stack.name == expectedName) {
     68      // Reached back to outer function before request
     69      ok(true, "Complete stack");
     70      return;
     71    }
     72    stack = stack.asyncCaller || stack.caller;
     73  }
     74  ok(false, "Incomplete stack");
     75 }
     76 
     77 function test_client_request_promise() {
     78  // Test that DevToolsClient.request returns a promise that resolves on response
     79  const request = gClient.request({
     80    to: gActorId,
     81    type: "hello",
     82  });
     83 
     84  request.then(response => {
     85    Assert.equal(response.from, gActorId);
     86    Assert.equal(response.hello, "world");
     87    checkStack("test_client_request_promise/<");
     88    run_next_test();
     89  });
     90 }
     91 
     92 function test_client_request_promise_error() {
     93  // Test that DevToolsClient.request returns a promise that reject when server
     94  // returns an explicit error message
     95  const request = gClient.request({
     96    to: gActorId,
     97    type: "error",
     98  });
     99 
    100  request.then(
    101    () => {
    102      do_throw("Promise shouldn't be resolved on error");
    103    },
    104    response => {
    105      Assert.equal(response.from, gActorId);
    106      Assert.equal(response.error, "code");
    107      Assert.equal(response.message, "human message");
    108      checkStack("test_client_request_promise_error/<");
    109      run_next_test();
    110    }
    111  );
    112 }
    113 
    114 function test_client_request_event_emitter() {
    115  // Test that DevToolsClient.request returns also an EventEmitter object
    116  const request = gClient.request({
    117    to: gActorId,
    118    type: "hello",
    119  });
    120  request.on("json-reply", reply => {
    121    Assert.equal(reply.from, gActorId);
    122    Assert.equal(reply.hello, "world");
    123    checkStack("test_client_request_event_emitter");
    124    run_next_test();
    125  });
    126 }
    127 
    128 function test_close_client_while_sending_requests() {
    129  // First send a first request that will be "active"
    130  // while the connection is closed.
    131  // i.e. will be sent but no response received yet.
    132  const activeRequest = gClient.request({
    133    to: gActorId,
    134    type: "hello",
    135  });
    136 
    137  // Pile up a second one that will be "pending".
    138  // i.e. won't event be sent.
    139  const pendingRequest = gClient.request({
    140    to: gActorId,
    141    type: "hello",
    142  });
    143 
    144  const expectReply = new Promise(resolve => {
    145    gClient.expectReply("root", function (response) {
    146      Assert.equal(response.error, "connectionClosed");
    147      Assert.equal(
    148        response.message,
    149        "server side packet can't be received as the connection just closed."
    150      );
    151      resolve();
    152    });
    153  });
    154 
    155  gClient.close().then(() => {
    156    activeRequest
    157      .then(
    158        () => {
    159          ok(
    160            false,
    161            "First request unexpectedly succeed while closing the connection"
    162          );
    163        },
    164        response => {
    165          Assert.equal(response.error, "connectionClosed");
    166          Assert.equal(
    167            response.message,
    168            "'hello' active request packet to '" +
    169              gActorId +
    170              "' can't be sent as the connection just closed."
    171          );
    172        }
    173      )
    174      .then(() => pendingRequest)
    175      .then(
    176        () => {
    177          ok(
    178            false,
    179            "Second request unexpectedly succeed while closing the connection"
    180          );
    181        },
    182        response => {
    183          Assert.equal(response.error, "connectionClosed");
    184          Assert.equal(
    185            response.message,
    186            "'hello' pending request packet to '" +
    187              gActorId +
    188              "' can't be sent as the connection just closed."
    189          );
    190        }
    191      )
    192      .then(() => expectReply)
    193      .then(run_next_test);
    194  });
    195 }
    196 
    197 function test_client_request_after_close() {
    198  // Test that DevToolsClient.request fails after we called client.close()
    199  // (with promise API)
    200  const request = gClient.request({
    201    to: gActorId,
    202    type: "hello",
    203  });
    204 
    205  request.then(
    206    () => {
    207      ok(false, "Request succeed even after client.close");
    208    },
    209    response => {
    210      ok(true, "Request failed after client.close");
    211      Assert.equal(response.error, "connectionClosed");
    212      ok(
    213        response.message.match(
    214          /'hello' request packet to '.*' can't be sent as the connection is closed./
    215        )
    216      );
    217      run_next_test();
    218    }
    219  );
    220 }