Update web-platform-tests to revision b'468d01bbd84da2babf265c6af46947be68713440'

This commit is contained in:
WPT Sync Bot 2021-09-07 11:16:33 +00:00 committed by cybai
parent 35e95f55a1
commit 58e8ee674b
9438 changed files with 266112 additions and 106976 deletions

View file

@ -211,6 +211,17 @@ for (const bodyMethod of BODY_METHODS) {
}, `response.${bodyMethod}() rejects if already aborted`);
}
promise_test(async (t) => {
const controller = new AbortController();
const signal = controller.signal;
const res = await fetch('../resources/data.json', { signal });
controller.abort();
await promise_rejects_dom(t, 'AbortError', res.text());
await promise_rejects_dom(t, 'AbortError', res.text());
}, 'Call text() twice on aborted response');
promise_test(async t => {
await abortRequests();

View file

@ -0,0 +1,14 @@
// META: global=window,worker
// META: script=../resources/utils.js
// META: script=/common/utils.js
// META: script=/common/get-host-info.sub.js
promise_test(async (test) => {
const resp = await fetch(
"/fetch/connection-pool/resources/network-partition-key.py?"
+ `status=425&uuid=${token()}&partition_id=${get_host_info().ORIGIN}`
+ `&dispatch=check_partition&addcounter=true`);
assert_equals(resp.status, 425);
const text = await resp.text();
assert_equals(text, "ok. Request was sent 1 times. 1 connections were created.");
}, "Fetch on 425 response should not be retried for non TLS early data.");

View file

@ -4,7 +4,7 @@
// META: script=/common/get-host-info.sub.js
function testUpload(desc, url, method, createBody, expectedBody) {
const requestInit = {"method": method}
const requestInit = {method};
promise_test(function(test){
const body = createBody();
if (body) {
@ -19,7 +19,7 @@ function testUpload(desc, url, method, createBody, expectedBody) {
}
function testUploadFailure(desc, url, method, createBody) {
const requestInit = {"method": method};
const requestInit = {method};
promise_test(t => {
const body = createBody();
if (body) {
@ -75,16 +75,7 @@ testUpload("Fetch with POST with Blob body with mime type", url,
"POST",
() => new Blob(["Test"], { type: "text/maybe" }),
"Test");
testUpload("Fetch with POST with ReadableStream", url,
"POST",
() => {
return new ReadableStream({start: controller => {
const encoder = new TextEncoder();
controller.enqueue(encoder.encode("Test"));
controller.close();
}})
},
"Test");
testUploadFailure("Fetch with POST with ReadableStream containing String", url,
"POST",
() => {
@ -152,3 +143,30 @@ promise_test(async (test) => {
const text = await resp.text();
assert_equals(text, "ok. Request was sent 1 times. 1 connections were created.");
}, "Fetch with POST with ReadableStream on 421 response should return the response and not retry.");
promise_test(async (test) => {
const request = new Request('', {
body: new ReadableStream(),
method: 'POST',
});
assert_equals(request.headers.get('Content-Type'), null, `Request should not have a content-type set`);
const response = await fetch('data:a/a;charset=utf-8,test', {
method: 'POST',
body: new ReadableStream(),
});
assert_equals(await response.text(), 'test', `Response has correct body`);
}, "Feature detect for POST with ReadableStream");
promise_test(async (test) => {
const request = new Request('data:a/a;charset=utf-8,test', {
body: new ReadableStream(),
method: 'POST',
});
assert_equals(request.headers.get('Content-Type'), null, `Request should not have a content-type set`);
const response = await fetch(request);
assert_equals(await response.text(), 'test', `Response has correct body`);
}, "Feature detect for POST with ReadableStream, using request object");

View file

@ -0,0 +1,39 @@
// META: global=window,worker
// META: script=../resources/utils.js
// META: script=/common/utils.js
// META: script=/common/get-host-info.sub.js
function testUpload(desc, url, method, createBody, expectedBody) {
const requestInit = {method};
promise_test(async function(){
const body = createBody();
if (body) {
requestInit["body"] = body;
}
const resp = await fetch(url, requestInit);
const text = await resp.text();
assert_equals(text, expectedBody);
}, desc);
}
const url = RESOURCES_DIR + "echo-content.h2.py"
testUpload("Fetch with POST with empty ReadableStream", url,
"POST",
() => {
return new ReadableStream({start: controller => {
controller.close();
}})
},
"");
testUpload("Fetch with POST with ReadableStream", url,
"POST",
() => {
return new ReadableStream({start: controller => {
const encoder = new TextEncoder();
controller.enqueue(encoder.encode("Test"));
controller.close();
}})
},
"Test");

View file

@ -3,7 +3,7 @@
function checkFetchResponse(url, data, mime, fetchMode, method) {
var cut = (url.length >= 40) ? "[...]" : "";
desc = "Fetching " + (method ? "[" + method + "] " : "") + url.substring(0, 40) + cut + " is OK";
var desc = "Fetching " + (method ? "[" + method + "] " : "") + url.substring(0, 40) + cut + " is OK";
var init = {"method": method || "GET"};
if (fetchMode) {
init.mode = fetchMode;

View file

@ -1,7 +1,7 @@
// META: global=window,worker
// META: script=../resources/utils.js
function streamBody(reader, test, count) {
function streamBody(reader, test, count = 0) {
return reader.read().then(function(data) {
if (!data.done && count < 2) {
count += 1;
@ -18,12 +18,23 @@ function streamBody(reader, test, count) {
//count is large enough to let the UA deliver the body before it is completely retrieved
promise_test(function(test) {
return fetch(RESOURCES_DIR + "trickle.py?ms=30&count=100").then(function(resp) {
var count = 0;
if (resp.body)
return streamBody(resp.body.getReader(), test, count);
return streamBody(resp.body.getReader(), test);
else
test.step(function() {
assert_unreached( "Body does not exist in response");
});
});
}, "Stream response's body");
}, "Stream response's body when content-type is present");
// This test makes sure that the response body is not buffered if no content type is provided.
promise_test(function(test) {
return fetch(RESOURCES_DIR + "trickle.py?ms=300&count=10&notype=true").then(function(resp) {
if (resp.body)
return streamBody(resp.body.getReader(), test);
else
test.step(function() {
assert_unreached( "Body does not exist in response");
});
});
}, "Stream response's body when content-type is not present");

View file

@ -14,8 +14,8 @@ const creationCases = {
{method: 'POST', body: 'yes'}).arrayBuffer(),
};
for (creationCase of Object.keys(creationCases)) {
for (accessorName of ['start', 'type', 'size', 'highWaterMark']) {
for (const creationCase of Object.keys(creationCases)) {
for (const accessorName of ['start', 'type', 'size', 'highWaterMark']) {
promise_test(async t => {
Object.defineProperty(Object.prototype, accessorName, {
get() { throw Error(`Object.prototype.${accessorName} was accessed`); },

View file

@ -0,0 +1,14 @@
promise_test(async t => {
const res = new Response(new FormData());
const fd = await res.formData();
assert_true(fd instanceof FormData);
}, 'Consume empty response.formData() as FormData');
promise_test(async t => {
const req = new Request('about:blank', {
method: 'POST',
body: new FormData()
});
const fd = await req.formData();
assert_true(fd instanceof FormData);
}, 'Consume empty request.formData() as FormData');

View file

@ -2,6 +2,8 @@
// META: global=window,worker
// META: timeout=long
"use strict";
for(let i = 0; i < 0x21; i++) {
let fail = false,
strip = false

View file

@ -2,6 +2,8 @@
// META: global=window,worker
// META: timeout=long
"use strict";
// Invalid values
[0, 0x0A, 0x0D].forEach(val => {
val = "x" + String.fromCharCode(val) + "x"

View file

@ -1,6 +1,8 @@
// META: title=Headers structure
// META: global=window,worker
"use strict";
test(function() {
new Headers();
}, "Create headers from no parameter");
@ -144,14 +146,14 @@ test(function() {
checkIteratorProperties(actual);
sortedHeaderKeys.forEach(function(key) {
entry = actual.next();
const entry = actual.next();
assert_false(entry.done);
assert_equals(entry.value, key);
});
assert_true(actual.next().done);
assert_true(actual.next().done);
for (key of headers.keys())
for (const key of headers.keys())
assert_true(sortedHeaderKeys.indexOf(key) != -1);
}, "Check keys method");
@ -161,14 +163,14 @@ test(function() {
checkIteratorProperties(actual);
sortedHeaderKeys.forEach(function(key) {
entry = actual.next();
const entry = actual.next();
assert_false(entry.done);
assert_equals(entry.value, sortedHeaderDict[key]);
});
assert_true(actual.next().done);
assert_true(actual.next().done);
for (value of headers.values())
for (const value of headers.values())
assert_true(headerValues.indexOf(value) != -1);
}, "Check values method");
@ -178,7 +180,7 @@ test(function() {
checkIteratorProperties(actual);
sortedHeaderKeys.forEach(function(key) {
entry = actual.next();
const entry = actual.next();
assert_false(entry.done);
assert_equals(entry.value[0], key);
assert_equals(entry.value[1], sortedHeaderDict[key]);
@ -186,7 +188,7 @@ test(function() {
assert_true(actual.next().done);
assert_true(actual.next().done);
for (entry of headers.entries())
for (const entry of headers.entries())
assert_equals(entry[1], sortedHeaderDict[entry[0]]);
}, "Check entries method");
@ -195,7 +197,7 @@ test(function() {
var actual = headers[Symbol.iterator]();
sortedHeaderKeys.forEach(function(key) {
entry = actual.next();
const entry = actual.next();
assert_false(entry.done);
assert_equals(entry.value[0], key);
assert_equals(entry.value[1], sortedHeaderDict[key]);
@ -209,7 +211,7 @@ test(function() {
var reference = sortedHeaderKeys[Symbol.iterator]();
headers.forEach(function(value, key, container) {
assert_equals(headers, container);
entry = reference.next();
const entry = reference.next();
assert_false(entry.done);
assert_equals(key, entry.value);
assert_equals(value, sortedHeaderDict[entry.value]);

View file

@ -1,6 +1,8 @@
// META: title=Headers case management
// META: global=window,worker
"use strict";
var headerDictCase = {"UPPERCASE": "value1",
"lowercase": "value2",
"mixedCase": "value3",
@ -21,13 +23,13 @@ function checkHeadersCase(originalName, headersToCheck, expectedDict) {
test(function() {
var headers = new Headers(headerDictCase);
for (name in headerDictCase)
for (const name in headerDictCase)
checkHeadersCase(name, headers, headerDictCase)
}, "Create headers, names use characters with different case");
test(function() {
var headers = new Headers();
for (name in headerDictCase) {
for (const name in headerDictCase) {
headers.append(name, headerDictCase[name]);
checkHeadersCase(name, headers, headerDictCase);
}
@ -35,7 +37,7 @@ test(function() {
test(function() {
var headers = new Headers();
for (name in headerDictCase) {
for (const name in headerDictCase) {
headers.set(name, headerDictCase[name]);
checkHeadersCase(name, headers, headerDictCase);
}
@ -43,10 +45,10 @@ test(function() {
test(function() {
var headers = new Headers();
for (name in headerDictCase)
for (const name in headerDictCase)
headers.set(name, headerDictCase[name]);
for (name in headerDictCase)
for (const name in headerDictCase)
headers.delete(name.toLowerCase());
for (name in headerDictCase)
for (const name in headerDictCase)
assert_false(headers.has(name), "header " + name + " should have been deleted");
}, "Check delete method, names use characters with different case");

View file

@ -1,6 +1,8 @@
// META: title=Headers have combined (and sorted) values
// META: global=window,worker
"use strict";
var headerSeqCombine = [["single", "singleValue"],
["double", "doubleValue1"],
["double", "doubleValue2"],
@ -15,13 +17,13 @@ var expectedDict = {"single": "singleValue",
test(function() {
var headers = new Headers(headerSeqCombine);
for (name in expectedDict)
for (const name in expectedDict)
assert_equals(headers.get(name), expectedDict[name]);
}, "Create headers using same name for different values");
test(function() {
var headers = new Headers(headerSeqCombine);
for (name in expectedDict) {
for (const name in expectedDict) {
assert_true(headers.has(name), "name: " + name + " has value(s)");
headers.delete(name);
assert_false(headers.has(name), "name: " + name + " has no value(s) anymore");
@ -30,7 +32,7 @@ test(function() {
test(function() {
var headers = new Headers(headerSeqCombine);
for (name in expectedDict) {
for (const name in expectedDict) {
headers.set(name,"newSingleValue");
assert_equals(headers.get(name), "newSingleValue", "name: " + name + " has value: newSingleValue");
}
@ -38,7 +40,7 @@ test(function() {
test(function() {
var headers = new Headers(headerSeqCombine);
for (name in expectedDict) {
for (const name in expectedDict) {
var value = headers.get(name);
headers.append(name,"newSingleValue");
assert_equals(headers.get(name), (value + ", " + "newSingleValue"));

View file

@ -1,6 +1,8 @@
// META: title=Headers errors
// META: global=window,worker
"use strict";
test(function() {
assert_throws_js(TypeError, function() { new Headers([["name"]]); });
}, "Create headers giving an array having one string as init argument");

View file

@ -1,5 +1,7 @@
// META: global=window,worker
"use strict";
promise_test(() => fetch("../cors/resources/not-cors-safelisted.json").then(res => res.json().then(runTests)), "Loading data…");
const longValue = "s".repeat(127);

View file

@ -1,6 +1,8 @@
// META: title=Headers normalize values
// META: global=window,worker
"use strict";
var headerDictWS = {"name1": " space ",
"name2": "\ttab\t",
"name3": " spaceAndTab\t",
@ -11,14 +13,14 @@ var headerDictWS = {"name1": " space ",
test(function() {
var headers = new Headers(headerDictWS);
for (name in headerDictWS)
for (const name in headerDictWS)
assert_equals(headers.get(name), headerDictWS[name].trim(),
"name: " + name + " has normalized value: " + headerDictWS[name].trim());
}, "Create headers with not normalized values");
test(function() {
var headers = new Headers();
for (name in headerDictWS) {
for (const name in headerDictWS) {
headers.append(name, headerDictWS[name]);
assert_equals(headers.get(name), headerDictWS[name].trim(),
"name: " + name + " has value: " + headerDictWS[name].trim());
@ -27,7 +29,7 @@ test(function() {
test(function() {
var headers = new Headers();
for (name in headerDictWS) {
for (const name in headerDictWS) {
headers.set(name, headerDictWS[name]);
assert_equals(headers.get(name), headerDictWS[name].trim(),
"name: " + name + " has value: " + headerDictWS[name].trim());

View file

@ -1,5 +1,7 @@
// META: global=window,worker
"use strict";
var log = [];
function clearLog() {
log = [];

View file

@ -1,6 +1,8 @@
// META: title=Headers basic
// META: global=window,worker
"use strict";
var headers = new Headers();
var methods = ["append",
"delete",

View file

@ -0,0 +1,32 @@
// META: global=window,worker
// META: script=../resources/utils.js
// META: script=/common/utils.js
// META: script=/common/get-host-info.sub.js
const redirectUrl = RESOURCES_DIR + "redirect.h2.py";
const redirectLocation = "top.txt";
async function fetchStreamRedirect(statusCode) {
const url = RESOURCES_DIR + "redirect.h2.py" +
`?redirect_status=${statusCode}&location=${redirectLocation}`;
const requestInit = {method: "POST"};
requestInit["body"] = new ReadableStream({start: controller => {
const encoder = new TextEncoder();
controller.enqueue(encoder.encode("Test"));
controller.close();
}});
return fetch(url, requestInit);
}
promise_test(async () => {
const resp = await fetchStreamRedirect(303);
assert_equals(resp.status, 200);
assert_true(new URL(resp.url).pathname.endsWith(redirectLocation),
"Response's url should be the redirected one");
}, "Fetch upload streaming should be accepted on 303");
for (const statusCode of [301, 302, 307, 308]) {
promise_test(t => {
return promise_rejects_js(t, TypeError, fetchStreamRedirect(statusCode));
}, `Fetch upload streaming should fail on ${statusCode}`);
}

View file

@ -20,6 +20,7 @@ var BLOCKED_PORTS_LIST = [
42, // name
43, // nicname
53, // domain
69, // tftp
77, // priv-rjs
79, // finger
87, // ttylink
@ -37,8 +38,10 @@ var BLOCKED_PORTS_LIST = [
119, // nntp
123, // ntp
135, // loc-srv / epmap
139, // netbios
137, // netbios-ns
139, // netbios-ssn
143, // imap2
161, // snmp
179, // bgp
389, // ldap
427, // afp (alternate)
@ -53,13 +56,17 @@ var BLOCKED_PORTS_LIST = [
532, // netnews
540, // uucp
548, // afp
554, // rtsp
556, // remotefs
563, // nntp+ssl
587, // smtp (outgoing)
601, // syslog-conn
636, // ldap+ssl
989, // ftps-data
990, // ftps
993, // ldap+ssl
995, // pop3+ssl
1719, // h323gatestat
1720, // h323hostcall
1723, // pptp
2049, // nfs
@ -68,12 +75,14 @@ var BLOCKED_PORTS_LIST = [
5060, // sip
5061, // sips
6000, // x11
6566, // sane-port
6665, // irc (alternate)
6666, // irc (alternate)
6667, // irc (default)
6668, // irc (alternate)
6669, // irc (alternate)
6697, // irc+tls
10080, // amanda
];
BLOCKED_PORTS_LIST.map(function(a){

View file

@ -0,0 +1,139 @@
function requestFromBody(body) {
return new Request(
"https://example.com",
{
method: "POST",
body,
},
);
}
test(() => {
const request = requestFromBody(undefined);
assert_equals(request.headers.get("Content-Type"), null);
}, "Default Content-Type for Request with empty body");
test(() => {
const blob = new Blob([]);
const request = requestFromBody(blob);
assert_equals(request.headers.get("Content-Type"), null);
}, "Default Content-Type for Request with Blob body (no type set)");
test(() => {
const blob = new Blob([], { type: "" });
const request = requestFromBody(blob);
assert_equals(request.headers.get("Content-Type"), null);
}, "Default Content-Type for Request with Blob body (empty type)");
test(() => {
const blob = new Blob([], { type: "a/b; c=d" });
const request = requestFromBody(blob);
assert_equals(request.headers.get("Content-Type"), "a/b; c=d");
}, "Default Content-Type for Request with Blob body (set type)");
test(() => {
const buffer = new Uint8Array();
const request = requestFromBody(buffer);
assert_equals(request.headers.get("Content-Type"), null);
}, "Default Content-Type for Request with buffer source body");
promise_test(async () => {
const formData = new FormData();
formData.append("a", "b");
const request = requestFromBody(formData);
const boundary = (await request.text()).split("\r\n")[0].slice(2);
assert_equals(
request.headers.get("Content-Type"),
`multipart/form-data; boundary=${boundary}`,
);
}, "Default Content-Type for Request with FormData body");
test(() => {
const usp = new URLSearchParams();
const request = requestFromBody(usp);
assert_equals(
request.headers.get("Content-Type"),
"application/x-www-form-urlencoded;charset=UTF-8",
);
}, "Default Content-Type for Request with URLSearchParams body");
test(() => {
const request = requestFromBody("");
assert_equals(
request.headers.get("Content-Type"),
"text/plain;charset=UTF-8",
);
}, "Default Content-Type for Request with string body");
test(() => {
const stream = new ReadableStream();
const request = requestFromBody(stream);
assert_equals(request.headers.get("Content-Type"), null);
}, "Default Content-Type for Request with ReadableStream body");
// -----------------------------------------------------------------------------
const OVERRIDE_MIME = "test/only; mime=type";
function requestFromBodyWithOverrideMime(body) {
return new Request(
"https://example.com",
{
method: "POST",
body,
headers: { "Content-Type": OVERRIDE_MIME },
},
);
}
test(() => {
const request = requestFromBodyWithOverrideMime(undefined);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with empty body");
test(() => {
const blob = new Blob([]);
const request = requestFromBodyWithOverrideMime(blob);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with Blob body (no type set)");
test(() => {
const blob = new Blob([], { type: "" });
const request = requestFromBodyWithOverrideMime(blob);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with Blob body (empty type)");
test(() => {
const blob = new Blob([], { type: "a/b; c=d" });
const request = requestFromBodyWithOverrideMime(blob);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with Blob body (set type)");
test(() => {
const buffer = new Uint8Array();
const request = requestFromBodyWithOverrideMime(buffer);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with buffer source body");
test(() => {
const formData = new FormData();
const request = requestFromBodyWithOverrideMime(formData);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with FormData body");
test(() => {
const usp = new URLSearchParams();
const request = requestFromBodyWithOverrideMime(usp);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with URLSearchParams body");
test(() => {
const request = requestFromBodyWithOverrideMime("");
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with string body");
test(() => {
const stream = new ReadableStream();
const request = requestFromBodyWithOverrideMime(stream);
assert_equals(request.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Request with ReadableStream body");

View file

@ -0,0 +1,9 @@
from wptserve.utils import isomorphic_encode
def handle_headers(frame, request, response):
response.status = 200
response.headers.update([('Content-Type', 'text/plain')])
response.write_status_headers()
def handle_data(frame, request, response):
response.writer.write_data(frame.data)

View file

@ -0,0 +1,14 @@
from wptserve.utils import isomorphic_decode, isomorphic_encode
def handle_headers(frame, request, response):
status = 302
if b'redirect_status' in request.GET:
status = int(request.GET[b'redirect_status'])
response.status = status
if b'location' in request.GET:
url = isomorphic_decode(request.GET[b'location'])
response.headers[b'Location'] = isomorphic_encode(url)
response.headers.update([('Content-Type', 'text/plain')])
response.write_status_headers()

View file

@ -1,6 +1,6 @@
import time
from six.moves.urllib.parse import urlencode, urlparse
from urllib.parse import urlencode, urlparse
from wptserve.utils import isomorphic_decode, isomorphic_encode

View file

@ -1,16 +1,15 @@
import time
from six.moves import xrange
def main(request, response):
delay = float(request.GET.first(b"ms", 500)) / 1E3
count = int(request.GET.first(b"count", 50))
# Read request body
request.body
time.sleep(delay)
response.headers.set(b"Content-type", b"text/plain")
if not b"notype" in request.GET:
response.headers.set(b"Content-type", b"text/plain")
response.write_status_headers()
time.sleep(delay)
for i in xrange(count):
for i in range(count):
response.writer.write_content(b"TEST_TRICKLE\n")
time.sleep(delay)

View file

@ -62,7 +62,7 @@ function validateStreamFromString(reader, expectedValue, retrievedArrayBuffer) {
assert_true(data.value instanceof Uint8Array, "Fetch ReadableStream chunks should be Uint8Array");
var newBuffer;
if (retrievedArrayBuffer) {
newBuffer = new ArrayBuffer(data.value.length + retrievedArrayBuffer.length);
newBuffer = new Uint8Array(data.value.length + retrievedArrayBuffer.length);
newBuffer.set(retrievedArrayBuffer, 0);
newBuffer.set(data.value, retrievedArrayBuffer.length);
} else {
@ -80,7 +80,7 @@ function validateStreamFromPartialString(reader, expectedValue, retrievedArrayBu
assert_true(data.value instanceof Uint8Array, "Fetch ReadableStream chunks should be Uint8Array");
var newBuffer;
if (retrievedArrayBuffer) {
newBuffer = new ArrayBuffer(data.value.length + retrievedArrayBuffer.length);
newBuffer = new Uint8Array(data.value.length + retrievedArrayBuffer.length);
newBuffer.set(retrievedArrayBuffer, 0);
newBuffer.set(data.value, retrievedArrayBuffer.length);
} else {

View file

@ -0,0 +1,14 @@
// See also /xhr/json.any.js
promise_test(async t => {
const response = await fetch(`data:,\uFEFF{ "b": 1, "a": 2, "b": 3 }`);
const json = await response.json();
assert_array_equals(Object.keys(json), ["b", "a"]);
assert_equals(json.a, 2);
assert_equals(json.b, 3);
}, "Ensure the correct JSON parser is used");
promise_test(async t => {
const response = await fetch("/xhr/resources/utf16-bom.json");
return promise_rejects_js(t, SyntaxError, response.json());
}, "Ensure UTF-16 results in an error");

View file

@ -119,6 +119,8 @@ testReadableStreamClone(new Uint8Array(arrayBuffer), "Uint8Array");
testReadableStreamClone(new Uint8ClampedArray(arrayBuffer), "Uint8ClampedArray");
testReadableStreamClone(new Uint16Array(arrayBuffer, 2), "Uint16Array");
testReadableStreamClone(new Uint32Array(arrayBuffer), "Uint32Array");
testReadableStreamClone(typeof BigInt64Array === "function" ? new BigInt64Array(arrayBuffer) : undefined, "BigInt64Array");
testReadableStreamClone(typeof BigUint64Array === "function" ? new BigUint64Array(arrayBuffer) : undefined, "BigUint64Array");
testReadableStreamClone(new Float32Array(arrayBuffer), "Float32Array");
testReadableStreamClone(new Float64Array(arrayBuffer), "Float64Array");
testReadableStreamClone(new DataView(arrayBuffer, 2, 8), "DataView");

View file

@ -0,0 +1,125 @@
test(() => {
const response = new Response();
assert_equals(response.headers.get("Content-Type"), null);
}, "Default Content-Type for Response with empty body");
test(() => {
const blob = new Blob([]);
const response = new Response(blob);
assert_equals(response.headers.get("Content-Type"), null);
}, "Default Content-Type for Response with Blob body (no type set)");
test(() => {
const blob = new Blob([], { type: "" });
const response = new Response(blob);
assert_equals(response.headers.get("Content-Type"), null);
}, "Default Content-Type for Response with Blob body (empty type)");
test(() => {
const blob = new Blob([], { type: "a/b; c=d" });
const response = new Response(blob);
assert_equals(response.headers.get("Content-Type"), "a/b; c=d");
}, "Default Content-Type for Response with Blob body (set type)");
test(() => {
const buffer = new Uint8Array();
const response = new Response(buffer);
assert_equals(response.headers.get("Content-Type"), null);
}, "Default Content-Type for Response with buffer source body");
promise_test(async () => {
const formData = new FormData();
formData.append("a", "b");
const response = new Response(formData);
const boundary = (await response.text()).split("\r\n")[0].slice(2);
assert_equals(
response.headers.get("Content-Type"),
`multipart/form-data; boundary=${boundary}`,
);
}, "Default Content-Type for Response with FormData body");
test(() => {
const usp = new URLSearchParams();
const response = new Response(usp);
assert_equals(
response.headers.get("Content-Type"),
"application/x-www-form-urlencoded;charset=UTF-8",
);
}, "Default Content-Type for Response with URLSearchParams body");
test(() => {
const response = new Response("");
assert_equals(
response.headers.get("Content-Type"),
"text/plain;charset=UTF-8",
);
}, "Default Content-Type for Response with string body");
test(() => {
const stream = new ReadableStream();
const response = new Response(stream);
assert_equals(response.headers.get("Content-Type"), null);
}, "Default Content-Type for Response with ReadableStream body");
// -----------------------------------------------------------------------------
const OVERRIDE_MIME = "test/only; mime=type";
function responseWithOverrideMime(body) {
return new Response(
body,
{ headers: { "Content-Type": OVERRIDE_MIME } },
);
}
test(() => {
const response = responseWithOverrideMime(undefined);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with empty body");
test(() => {
const blob = new Blob([]);
const response = responseWithOverrideMime(blob);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with Blob body (no type set)");
test(() => {
const blob = new Blob([], { type: "" });
const response = responseWithOverrideMime(blob);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with Blob body (empty type)");
test(() => {
const blob = new Blob([], { type: "a/b; c=d" });
const response = responseWithOverrideMime(blob);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with Blob body (set type)");
test(() => {
const buffer = new Uint8Array();
const response = responseWithOverrideMime(buffer);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with buffer source body");
test(() => {
const formData = new FormData();
const response = responseWithOverrideMime(formData);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with FormData body");
test(() => {
const usp = new URLSearchParams();
const response = responseWithOverrideMime(usp);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with URLSearchParams body");
test(() => {
const response = responseWithOverrideMime("");
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with string body");
test(() => {
const stream = new ReadableStream();
const response = responseWithOverrideMime(stream);
assert_equals(response.headers.get("Content-Type"), OVERRIDE_MIME);
}, "Can override Content-Type for Response with ReadableStream body");

View file

@ -3,7 +3,7 @@
var url = "http://test.url:1234/";
test(function() {
redirectResponse = Response.redirect(url);
const redirectResponse = Response.redirect(url);
assert_equals(redirectResponse.type, "default");
assert_false(redirectResponse.redirected);
assert_false(redirectResponse.ok);
@ -15,7 +15,7 @@ test(function() {
[301, 302, 303, 307, 308].forEach(function(status) {
test(function() {
redirectResponse = Response.redirect(url, status);
const redirectResponse = Response.redirect(url, status);
assert_equals(redirectResponse.type, "default");
assert_false(redirectResponse.redirected);
assert_false(redirectResponse.ok);

View file

@ -1,42 +1,44 @@
// META: global=window,worker
// META: title=Consuming Response body after getting a ReadableStream
// META: script=./response-stream-disturbed-util.js
function createResponseWithReadableStream(callback) {
return fetch("../resources/data.json").then(function(response) {
var reader = response.body.getReader();
reader.releaseLock();
return callback(response);
});
async function createResponseWithReadableStream(bodySource, callback) {
const response = await responseFromBodySource(bodySource);
const reader = response.body.getReader();
reader.releaseLock();
return callback(response);
}
promise_test(function() {
return createResponseWithReadableStream(function(response) {
return response.blob().then(function(blob) {
assert_true(blob instanceof Blob);
for (const bodySource of ["fetch", "stream", "string"]) {
promise_test(function() {
return createResponseWithReadableStream(bodySource, function(response) {
return response.blob().then(function(blob) {
assert_true(blob instanceof Blob);
});
});
});
}, "Getting blob after getting the Response body - not disturbed, not locked");
}, `Getting blob after getting the Response body - not disturbed, not locked (body source: ${bodySource})`);
promise_test(function() {
return createResponseWithReadableStream(function(response) {
return response.text().then(function(text) {
assert_true(text.length > 0);
promise_test(function() {
return createResponseWithReadableStream(bodySource, function(response) {
return response.text().then(function(text) {
assert_true(text.length > 0);
});
});
});
}, "Getting text after getting the Response body - not disturbed, not locked");
}, `Getting text after getting the Response body - not disturbed, not locked (body source: ${bodySource})`);
promise_test(function() {
return createResponseWithReadableStream(function(response) {
return response.json().then(function(json) {
assert_equals(typeof json, "object");
promise_test(function() {
return createResponseWithReadableStream(bodySource, function(response) {
return response.json().then(function(json) {
assert_equals(typeof json, "object");
});
});
});
}, "Getting json after getting the Response body - not disturbed, not locked");
}, `Getting json after getting the Response body - not disturbed, not locked (body source: ${bodySource})`);
promise_test(function() {
return createResponseWithReadableStream(function(response) {
return response.arrayBuffer().then(function(arrayBuffer) {
assert_true(arrayBuffer.byteLength > 0);
promise_test(function() {
return createResponseWithReadableStream(bodySource, function(response) {
return response.arrayBuffer().then(function(arrayBuffer) {
assert_true(arrayBuffer.byteLength > 0);
});
});
});
}, "Getting arrayBuffer after getting the Response body - not disturbed, not locked");
}, `Getting arrayBuffer after getting the Response body - not disturbed, not locked (body source: ${bodySource})`);
}

View file

@ -1,33 +1,35 @@
// META: global=window,worker
// META: title=Consuming Response body after getting a ReadableStream
// META: script=./response-stream-disturbed-util.js
function createResponseWithLockedReadableStream(callback) {
return fetch("../resources/data.json").then(function(response) {
var reader = response.body.getReader();
return callback(response);
});
async function createResponseWithLockedReadableStream(bodySource, callback) {
const response = await responseFromBodySource(bodySource);
response.body.getReader();
return callback(response);
}
promise_test(function(test) {
return createResponseWithLockedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.blob());
});
}, "Getting blob after getting a locked Response body");
for (const bodySource of ["fetch", "stream", "string"]) {
promise_test(function(test) {
return createResponseWithLockedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.blob());
});
}, `Getting blob after getting a locked Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithLockedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.text());
});
}, "Getting text after getting a locked Response body");
promise_test(function(test) {
return createResponseWithLockedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.text());
});
}, `Getting text after getting a locked Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithLockedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.json());
});
}, "Getting json after getting a locked Response body");
promise_test(function(test) {
return createResponseWithLockedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.json());
});
}, `Getting json after getting a locked Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithLockedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.arrayBuffer());
});
}, "Getting arrayBuffer after getting a locked Response body");
promise_test(function(test) {
return createResponseWithLockedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.arrayBuffer());
});
}, `Getting arrayBuffer after getting a locked Response body (body source: ${bodySource})`);
}

View file

@ -1,34 +1,36 @@
// META: global=window,worker
// META: title=Consuming Response body after getting a ReadableStream
// META: script=./response-stream-disturbed-util.js
function createResponseWithDisturbedReadableStream(callback) {
return fetch("../resources/data.json").then(function(response) {
var reader = response.body.getReader();
reader.read();
return callback(response);
});
async function createResponseWithDisturbedReadableStream(bodySource, callback) {
const response = await responseFromBodySource(bodySource);
const reader = response.body.getReader();
reader.read();
return callback(response);
}
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.blob());
});
}, "Getting blob after reading the Response body");
for (const bodySource of ["fetch", "stream", "string"]) {
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.blob());
});
}, `Getting blob after reading the Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.text());
});
}, "Getting text after reading the Response body");
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.text());
});
}, `Getting text after reading the Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.json());
});
}, "Getting json after reading the Response body");
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.json());
});
}, `Getting json after reading the Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.arrayBuffer());
});
}, "Getting arrayBuffer after reading the Response body");
promise_test(function(test) {
return createResponseWithDisturbedReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.arrayBuffer());
});
}, `Getting arrayBuffer after reading the Response body (body source: ${bodySource})`);
}

View file

@ -1,33 +1,35 @@
// META: global=window,worker
// META: title=Consuming Response body after getting a ReadableStream
// META: script=./response-stream-disturbed-util.js
function createResponseWithCancelledReadableStream(callback) {
return fetch("../resources/data.json").then(function(response) {
response.body.cancel();
return callback(response);
});
async function createResponseWithCancelledReadableStream(bodySource, callback) {
const response = await responseFromBodySource(bodySource);
response.body.cancel();
return callback(response);
}
promise_test(function(test) {
return createResponseWithCancelledReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.blob());
});
}, "Getting blob after cancelling the Response body");
for (const bodySource of ["fetch", "stream", "string"]) {
promise_test(function(test) {
return createResponseWithCancelledReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.blob());
});
}, `Getting blob after cancelling the Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithCancelledReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.text());
});
}, "Getting text after cancelling the Response body");
promise_test(function(test) {
return createResponseWithCancelledReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.text());
});
}, `Getting text after cancelling the Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithCancelledReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.json());
});
}, "Getting json after cancelling the Response body");
promise_test(function(test) {
return createResponseWithCancelledReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.json());
});
}, `Getting json after cancelling the Response body (body source: ${bodySource})`);
promise_test(function(test) {
return createResponseWithCancelledReadableStream(function(response) {
return promise_rejects_js(test, TypeError, response.arrayBuffer());
});
}, "Getting arrayBuffer after cancelling the Response body");
promise_test(function(test) {
return createResponseWithCancelledReadableStream(bodySource, function(response) {
return promise_rejects_js(test, TypeError, response.arrayBuffer());
});
}, `Getting arrayBuffer after cancelling the Response body (body source: ${bodySource})`);
}

View file

@ -1,34 +1,19 @@
// META: global=window,worker
// META: title=Consuming Response body after getting a ReadableStream
// META: script=./response-stream-disturbed-util.js
promise_test(function() {
return fetch("../resources/data.json").then(function(response) {
response.blob();
for (const bodySource of ["fetch", "stream", "string"]) {
for (const consumeAs of ["blob", "text", "json", "arrayBuffer"]) {
promise_test(
async () => {
const response = await responseFromBodySource(bodySource);
response[consumeAs]();
assert_not_equals(response.body, null);
assert_throws_js(TypeError, function() { response.body.getReader(); });
});
}, "Getting a body reader after consuming as blob");
promise_test(function() {
return fetch("../resources/data.json").then(function(response) {
response.text();
assert_not_equals(response.body, null);
assert_throws_js(TypeError, function() { response.body.getReader(); });
});
}, "Getting a body reader after consuming as text");
promise_test(function() {
return fetch("../resources/data.json").then(function(response) {
response.json();
assert_not_equals(response.body, null);
assert_throws_js(TypeError, function() { response.body.getReader(); });
});
}, "Getting a body reader after consuming as json");
promise_test(function() {
return fetch("../resources/data.json").then(function(response) {
response.arrayBuffer();
assert_not_equals(response.body, null);
assert_throws_js(TypeError, function() { response.body.getReader(); });
});
}, "Getting a body reader after consuming as arrayBuffer");
assert_throws_js(TypeError, function () {
response.body.getReader();
});
},
`Getting a body reader after consuming as ${consumeAs} (body source: ${bodySource})`,
);
}
}

View file

@ -0,0 +1,17 @@
const BODY = '{"key": "value"}';
function responseFromBodySource(bodySource) {
if (bodySource === "fetch") {
return fetch("../resources/data.json");
} else if (bodySource === "stream") {
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new TextEncoder().encode(BODY));
controller.close();
},
});
return new Response(stream);
} else {
return new Response(BODY);
}
}