<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Request consume empty bodies</title>
    <meta name="help" href="https://fetch.spec.whatwg.org/#request">
    <meta name="help" href="https://fetch.spec.whatwg.org/#body-mixin">
    <meta name="author" title="Canon Research France" href="https://www.crf.canon.fr">
    <script src="/resources/testharness.js"></script>
    <script src="/resources/testharnessreport.js"></script>
  </head>
  <body>
    <script>
    function checkBodyText(request) {
      return request.text().then(function(bodyAsText) {
        assert_equals(bodyAsText, "", "Resolved value should be empty");
        assert_false(request.bodyUsed);
      });
    }

    function checkBodyBlob(request) {
      return request.blob().then(function(bodyAsBlob) {
        var promise = new Promise(function(resolve, reject) {
          var reader = new FileReader();
          reader.onload = function(evt) {
            resolve(reader.result)
          };
          reader.onerror = function() {
            reject("Blob's reader failed");
          };
          reader.readAsText(bodyAsBlob);
        });
        return promise.then(function(body) {
          assert_equals(body, "", "Resolved value should be empty");
          assert_false(request.bodyUsed);
        });
      });
    }

    function checkBodyArrayBuffer(request) {
      return request.arrayBuffer().then(function(bodyAsArrayBuffer) {
        assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
        assert_false(request.bodyUsed);
      });
    }

    function checkBodyJSON(request) {
      return request.json().then(
        function(bodyAsJSON) {
          assert_unreached("JSON parsing should fail");
        },
        function() {
          assert_false(request.bodyUsed);
        });
    }

    function checkBodyFormData(request) {
      return request.formData().then(function(bodyAsFormData) {
        assert_true(bodyAsFormData instanceof FormData, "Should receive a FormData");
        assert_false(request.bodyUsed);
     });
    }

    function checkRequestWithNoBody(bodyType, checkFunction) {
      promise_test(function(test) {
        var request = new Request("", {"method": "POST"});
        assert_false(request.bodyUsed);
        return checkFunction(request);
      }, "Consume request's body as " + bodyType);
    }

    var formData = new FormData();
    checkRequestWithNoBody("text", checkBodyText);
    checkRequestWithNoBody("blob", checkBodyBlob);
    checkRequestWithNoBody("arrayBuffer", checkBodyArrayBuffer);
    checkRequestWithNoBody("json", checkBodyJSON);
    checkRequestWithNoBody("formData", checkBodyFormData);

    function checkRequestWithEmptyBody(bodyType, body, asText) {
      promise_test(function(test) {
        var request = new Request("", {"method": "POST", "body": body});
        assert_false(request.bodyUsed, "bodyUsed is false at init");
        if (asText) {
          return request.text().then(function(bodyAsString) {
            assert_equals(bodyAsString.length, 0, "Resolved value should be empty");
            assert_true(request.bodyUsed, "bodyUsed is true after being consumed");
          });
        }
        return request.arrayBuffer().then(function(bodyAsArrayBuffer) {
          assert_equals(bodyAsArrayBuffer.byteLength, 0, "Resolved value should be empty");
          assert_true(request.bodyUsed, "bodyUsed is true after being consumed");
        });
      }, "Consume empty " + bodyType + " request body as " + (asText ? "text" : "arrayBuffer"));
    }

    // FIXME: Add BufferSource, FormData and URLSearchParams.
    checkRequestWithEmptyBody("blob", new Blob([], { "type" : "text/plain" }), false);
    checkRequestWithEmptyBody("text", "", false);
    checkRequestWithEmptyBody("blob", new Blob([], { "type" : "text/plain" }), true);
    checkRequestWithEmptyBody("text", "", true);
    checkRequestWithEmptyBody("URLSearchParams", new URLSearchParams(""), true);
    // FIXME: This test assumes that the empty string be returned but it is not clear whether that is right. See https://github.com/w3c/web-platform-tests/pull/3950.
    checkRequestWithEmptyBody("FormData", new FormData(), true);
    checkRequestWithEmptyBody("ArrayBuffer", new ArrayBuffer(), true);
    </script>
  </body>
</html>
