tor-browser

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

test_response.js (10025B)


      1 function testDefaultCtor() {
      2  var res = new Response();
      3  is(res.type, "default", "Default Response type is default");
      4  ok(
      5    res.headers instanceof Headers,
      6    "Response should have non-null Headers object"
      7  );
      8  is(res.url, "", "URL should be empty string");
      9  is(res.status, 200, "Default status is 200");
     10  is(res.statusText, "", "Default statusText is an empty string");
     11 }
     12 
     13 function testClone() {
     14  var orig = new Response("This is a body", {
     15    status: 404,
     16    statusText: "Not Found",
     17    headers: { "Content-Length": 5 },
     18  });
     19  var clone = orig.clone();
     20  is(clone.status, 404, "Response status is 404");
     21  is(clone.statusText, "Not Found", "Response statusText is POST");
     22  ok(
     23    clone.headers instanceof Headers,
     24    "Response should have non-null Headers object"
     25  );
     26 
     27  is(
     28    clone.headers.get("content-length"),
     29    "5",
     30    "Response content-length should be 5."
     31  );
     32  orig.headers.set("content-length", 6);
     33  is(
     34    clone.headers.get("content-length"),
     35    "5",
     36    "Response content-length should be 5."
     37  );
     38 
     39  ok(!orig.bodyUsed, "Original body is not consumed.");
     40  ok(!clone.bodyUsed, "Clone body is not consumed.");
     41 
     42  var origBody = null;
     43  var clone2 = null;
     44  return orig
     45    .text()
     46    .then(function (body) {
     47      origBody = body;
     48      is(origBody, "This is a body", "Original body string matches");
     49      ok(orig.bodyUsed, "Original body is consumed.");
     50      ok(!clone.bodyUsed, "Clone body is not consumed.");
     51 
     52      try {
     53        orig.clone();
     54        ok(false, "Cannot clone Response whose body is already consumed");
     55      } catch (e) {
     56        is(
     57          e.name,
     58          "TypeError",
     59          "clone() of consumed body should throw TypeError"
     60        );
     61      }
     62 
     63      clone2 = clone.clone();
     64      return clone.text();
     65    })
     66    .then(function (body) {
     67      is(body, origBody, "Clone body matches original body.");
     68      ok(clone.bodyUsed, "Clone body is consumed.");
     69 
     70      try {
     71        clone.clone();
     72        ok(false, "Cannot clone Response whose body is already consumed");
     73      } catch (e) {
     74        is(
     75          e.name,
     76          "TypeError",
     77          "clone() of consumed body should throw TypeError"
     78        );
     79      }
     80 
     81      return clone2.text();
     82    })
     83    .then(function (body) {
     84      is(body, origBody, "Clone body matches original body.");
     85      ok(clone2.bodyUsed, "Clone body is consumed.");
     86 
     87      try {
     88        clone2.clone();
     89        ok(false, "Cannot clone Response whose body is already consumed");
     90      } catch (e) {
     91        is(
     92          e.name,
     93          "TypeError",
     94          "clone() of consumed body should throw TypeError"
     95        );
     96      }
     97    });
     98 }
     99 
    100 function testCloneUnfiltered() {
    101  var url =
    102    "http://example.com/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?status=200";
    103  return fetch(url, { mode: "no-cors" }).then(function (response) {
    104    // By default the chrome-only function should not be available.
    105    is(response.type, "opaque", "response should be opaque");
    106    is(
    107      response.cloneUnfiltered,
    108      undefined,
    109      "response.cloneUnfiltered should be undefined"
    110    );
    111 
    112    // When the test is run in a worker context we can't actually try to use
    113    // the chrome-only function.  SpecialPowers is not defined.
    114    if (typeof SpecialPowers !== "object") {
    115      return;
    116    }
    117 
    118    // With a chrome code, however, should be able to get an unfiltered response.
    119    var chromeResponse = SpecialPowers.wrap(response);
    120    is(
    121      typeof chromeResponse.cloneUnfiltered,
    122      "function",
    123      "chromeResponse.cloneFiltered should be a function"
    124    );
    125    var unfiltered = chromeResponse.cloneUnfiltered();
    126    is(unfiltered.type, "default", "unfiltered response should be default");
    127    is(unfiltered.status, 200, "unfiltered response should have 200 status");
    128  });
    129 }
    130 
    131 function testError() {
    132  var res = Response.error();
    133  is(res.status, 0, "Error response status should be 0");
    134  try {
    135    res.headers.set("someheader", "not allowed");
    136    ok(false, "Error response should have immutable headers");
    137  } catch (e) {
    138    ok(true, "Error response should have immutable headers");
    139  }
    140 }
    141 
    142 function testRedirect() {
    143  var res = Response.redirect("./redirect.response");
    144  is(res.status, 302, "Default redirect has status code 302");
    145  is(res.statusText, "", "Default redirect has status text empty");
    146  var h = res.headers.get("location");
    147  ok(
    148    h === new URL("./redirect.response", self.location.href).href,
    149    "Location header should be correct absolute URL"
    150  );
    151  try {
    152    res.headers.set("someheader", "not allowed");
    153    ok(false, "Redirects should have immutable headers");
    154  } catch (e) {
    155    ok(true, "Redirects should have immutable headers");
    156  }
    157 
    158  var successStatus = [301, 302, 303, 307, 308];
    159  for (var i = 0; i < successStatus.length; ++i) {
    160    var res = Response.redirect("./redirect.response", successStatus[i]);
    161    is(res.status, successStatus[i], "Status code should match");
    162  }
    163 
    164  var failStatus = [300, 0, 304, 305, 306, 309, 500];
    165  for (var i = 0; i < failStatus.length; ++i) {
    166    try {
    167      var res = Response.redirect(".", failStatus[i]);
    168      ok(false, "Invalid status code should fail " + failStatus[i]);
    169    } catch (e) {
    170      is(
    171        e.name,
    172        "RangeError",
    173        "Invalid status code should fail " + failStatus[i]
    174      );
    175    }
    176  }
    177 }
    178 
    179 function testOk() {
    180  var r1 = new Response("", { status: 200 });
    181  ok(r1.ok, "Response with status 200 should have ok true");
    182 
    183  var r2 = new Response(undefined, { status: 204 });
    184  ok(r2.ok, "Response with status 204 should have ok true");
    185 
    186  var r3 = new Response("", { status: 299 });
    187  ok(r3.ok, "Response with status 299 should have ok true");
    188 
    189  var r4 = new Response("", { status: 302 });
    190  ok(!r4.ok, "Response with status 302 should have ok false");
    191 }
    192 
    193 function testBodyUsed() {
    194  var res = new Response("Sample body");
    195  ok(!res.bodyUsed, "bodyUsed is initially false.");
    196  return res
    197    .text()
    198    .then(v => {
    199      is(v, "Sample body", "Body should match");
    200      ok(res.bodyUsed, "After reading body, bodyUsed should be true.");
    201    })
    202    .then(() => {
    203      return res.blob().then(
    204        v => {
    205          ok(false, "Attempting to read body again should fail.");
    206        },
    207        e => {
    208          ok(true, "Attempting to read body again should fail.");
    209        }
    210      );
    211    });
    212 }
    213 
    214 function testBodyCreation() {
    215  var text = "κόσμε";
    216  var res1 = new Response(text);
    217  var p1 = res1.text().then(function (v) {
    218    ok(typeof v === "string", "Should resolve to string");
    219    is(text, v, "Extracted string should match");
    220  });
    221 
    222  var res2 = new Response(new Uint8Array([72, 101, 108, 108, 111]));
    223  var p2 = res2.text().then(function (v) {
    224    is("Hello", v, "Extracted string should match");
    225  });
    226 
    227  var res2b = new Response(new Uint8Array([72, 101, 108, 108, 111]).buffer);
    228  var p2b = res2b.text().then(function (v) {
    229    is("Hello", v, "Extracted string should match");
    230  });
    231 
    232  var resblob = new Response(new Blob([text]));
    233  var pblob = resblob.text().then(function (v) {
    234    is(v, text, "Extracted string should match");
    235  });
    236 
    237  var params = new URLSearchParams();
    238  params.append("item", "Geckos");
    239  params.append("feature", "stickyfeet");
    240  params.append("quantity", "700");
    241  var res3 = new Response(params);
    242  var p3 = res3.text().then(function (v) {
    243    var extracted = new URLSearchParams(v);
    244    is(extracted.get("item"), "Geckos", "Param should match");
    245    is(extracted.get("feature"), "stickyfeet", "Param should match");
    246    is(extracted.get("quantity"), "700", "Param should match");
    247  });
    248 
    249  return Promise.all([p1, p2, p2b, pblob, p3]);
    250 }
    251 
    252 function testBodyExtraction() {
    253  var text = "κόσμε";
    254  var newRes = function () {
    255    return new Response(text);
    256  };
    257  return newRes()
    258    .text()
    259    .then(function (v) {
    260      ok(typeof v === "string", "Should resolve to string");
    261      is(text, v, "Extracted string should match");
    262    })
    263    .then(function () {
    264      return newRes()
    265        .blob()
    266        .then(function (v) {
    267          ok(v instanceof Blob, "Should resolve to Blob");
    268          return readAsText(v).then(function (result) {
    269            is(result, text, "Decoded Blob should match original");
    270          });
    271        });
    272    })
    273    .then(function () {
    274      return newRes()
    275        .json()
    276        .then(
    277          function (v) {
    278            ok(false, "Invalid json should reject");
    279          },
    280          function (e) {
    281            ok(true, "Invalid json should reject");
    282          }
    283        );
    284    })
    285    .then(function () {
    286      return newRes()
    287        .arrayBuffer()
    288        .then(function (v) {
    289          ok(v instanceof ArrayBuffer, "Should resolve to ArrayBuffer");
    290          var dec = new TextDecoder();
    291          is(
    292            dec.decode(new Uint8Array(v)),
    293            text,
    294            "UTF-8 decoded ArrayBuffer should match original"
    295          );
    296        });
    297    });
    298 }
    299 
    300 function testNullBodyStatus() {
    301  [204, 205, 304].forEach(function (status) {
    302    try {
    303      var res = new Response(new Blob(), { status });
    304      ok(
    305        false,
    306        "Response body provided but status code does not permit a body"
    307      );
    308    } catch (e) {
    309      ok(true, "Response body provided but status code does not permit a body");
    310    }
    311  });
    312 
    313  [204, 205, 304].forEach(function (status) {
    314    try {
    315      var res = new Response(undefined, { status });
    316      ok(true, "Response body provided but status code does not permit a body");
    317    } catch (e) {
    318      ok(
    319        false,
    320        "Response body provided but status code does not permit a body"
    321      );
    322    }
    323  });
    324 }
    325 
    326 function runTest() {
    327  testDefaultCtor();
    328  testError();
    329  testRedirect();
    330  testOk();
    331  testNullBodyStatus();
    332 
    333  return (
    334    Promise.resolve()
    335      .then(testBodyCreation)
    336      .then(testBodyUsed)
    337      .then(testBodyExtraction)
    338      .then(testClone)
    339      .then(testCloneUnfiltered)
    340      // Put more promise based tests here.
    341      .catch(function (e) {
    342        dump("### ### " + e + "\n");
    343        ok(false, "got unexpected error!");
    344      })
    345  );
    346 }