summaryrefslogtreecommitdiffstats
path: root/dom/tests/mochitest/fetch/test_formdataparsing.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/tests/mochitest/fetch/test_formdataparsing.js')
-rw-r--r--dom/tests/mochitest/fetch/test_formdataparsing.js283
1 files changed, 283 insertions, 0 deletions
diff --git a/dom/tests/mochitest/fetch/test_formdataparsing.js b/dom/tests/mochitest/fetch/test_formdataparsing.js
new file mode 100644
index 000000000..bc7eb21a6
--- /dev/null
+++ b/dom/tests/mochitest/fetch/test_formdataparsing.js
@@ -0,0 +1,283 @@
+var boundary = "1234567891011121314151617";
+
+// fn(body) should create a Body subclass with content body treated as
+// FormData and return it.
+function testFormDataParsing(fn) {
+
+ function makeTest(shouldPass, input, testFn) {
+ var obj = fn(input);
+ return obj.formData().then(function(fd) {
+ ok(shouldPass, "Expected test to be valid FormData for " + input);
+ if (testFn) {
+ return testFn(fd);
+ }
+ }, function(e) {
+ if (shouldPass) {
+ ok(false, "Expected test to pass for " + input);
+ } else {
+ ok(e.name == "TypeError", "Error should be a TypeError.");
+ }
+ });
+ }
+
+ // [shouldPass?, input, testFn]
+ var tests =
+ [
+ [ true,
+
+ boundary +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ is(fd.get("greeting"), '"hello"');
+ }
+ ],
+ [ false,
+
+ // Invalid disposition.
+ boundary +
+ '\r\nContent-Disposition: form-datafoobar; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ true,
+
+ '--' +
+ boundary +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ is(fd.get("greeting"), '"hello"');
+ }
+ ],
+ [ false,
+ boundary + "\r\n\r\n" + boundary + '-',
+ ],
+ [ false,
+ // No valid ending.
+ boundary + "\r\n\r\n" + boundary,
+ ],
+ [ false,
+
+ // One '-' prefix is not allowed. 2 or none.
+ '-' +
+ boundary +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ 'invalid' +
+ boundary +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary + 'suffix' +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary + 'suffix' +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ // Partial boundary
+ boundary.substr(3) +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary +
+ // Missing '\n' at beginning.
+ '\rContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary +
+ // No form-data.
+ '\r\nContent-Disposition: mixed; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary +
+ // No headers.
+ '\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary +
+ // No content-disposition.
+ '\r\nContent-Dispositypo: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary +
+ // No name.
+ '\r\nContent-Disposition: form-data;\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary +
+ // Missing empty line between headers and body.
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ // Empty entry followed by valid entry.
+ boundary + "\r\n\r\n" + boundary +
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n"hello"\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+
+ boundary +
+ // Header followed by empty line, but empty body not followed by
+ // newline.
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n' +
+ boundary + '-',
+ ],
+ [ true,
+
+ boundary +
+ // Empty body followed by newline.
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ is(fd.get("greeting"), "", "Empty value is allowed.");
+ }
+ ],
+ [ false,
+ boundary +
+ // Value is boundary itself.
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n' +
+ boundary + '\r\n' +
+ boundary + '-',
+ ],
+ [ false,
+ boundary +
+ // Variant of above with no valid ending boundary.
+ '\r\nContent-Disposition: form-data; name="greeting"\r\n\r\n' +
+ boundary
+ ],
+ [ true,
+ boundary +
+ // Unquoted filename with empty body.
+ '\r\nContent-Disposition: form-data; name="file"; filename=file1.txt\r\n\r\n\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ var f = fd.get("file");
+ ok(f instanceof File, "Entry with filename attribute should be read as File.");
+ is(f.name, "file1.txt", "Filename should match.");
+ is(f.type, "text/plain", "Default content-type should be text/plain.");
+ return readAsText(f).then(function(text) {
+ is(text, "", "File should be empty.");
+ });
+ }
+ ],
+ [ true,
+ boundary +
+ // Quoted filename with empty body.
+ '\r\nContent-Disposition: form-data; name="file"; filename="file1.txt"\r\n\r\n\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ var f = fd.get("file");
+ ok(f instanceof File, "Entry with filename attribute should be read as File.");
+ is(f.name, "file1.txt", "Filename should match.");
+ is(f.type, "text/plain", "Default content-type should be text/plain.");
+ return readAsText(f).then(function(text) {
+ is(text, "", "File should be empty.");
+ });
+ }
+ ],
+ [ false,
+ boundary +
+ // Invalid filename
+ '\r\nContent-Disposition: form-data; name="file"; filename="[\n@;xt"\r\n\r\n\r\n' +
+ boundary + '-',
+ ],
+ [ true,
+ boundary +
+ '\r\nContent-Disposition: form-data; name="file"; filename="[@;xt"\r\n\r\n\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ var f = fd.get("file");
+ ok(f instanceof File, "Entry with filename attribute should be read as File.");
+ is(f.name, "[@", "Filename should match.");
+ }
+ ],
+ [ true,
+ boundary +
+ '\r\nContent-Disposition: form-data; name="file"; filename="file with spaces"\r\n\r\n\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ var f = fd.get("file");
+ ok(f instanceof File, "Entry with filename attribute should be read as File.");
+ is(f.name, "file with spaces", "Filename should match.");
+ }
+ ],
+ [ true,
+ boundary + '\r\n' +
+ 'Content-Disposition: form-data; name="file"; filename="xml.txt"\r\n' +
+ 'content-type : application/xml\r\n' +
+ '\r\n' +
+ '<body>foobar\r\n\r\n</body>\r\n' +
+ boundary + '-',
+
+ function(fd) {
+ var f = fd.get("file");
+ ok(f instanceof File, "Entry with filename attribute should be read as File.");
+ is(f.name, "xml.txt", "Filename should match.");
+ is(f.type, "application/xml", "content-type should be application/xml.");
+ return readAsText(f).then(function(text) {
+ is(text, "<body>foobar\r\n\r\n</body>", "File should have correct text.");
+ });
+ }
+ ],
+ ];
+
+ var promises = [];
+ for (var i = 0; i < tests.length; ++i) {
+ var test = tests[i];
+ promises.push(makeTest(test[0], test[1], test[2]));
+ }
+
+ return Promise.all(promises);
+}
+
+function makeRequest(body) {
+ var req = new Request("", { method: 'post', body: body,
+ headers: {
+ 'Content-Type': 'multipart/form-data; boundary=' + boundary
+ }});
+ return req;
+}
+
+function makeResponse(body) {
+ var res = new Response(body, { headers: {
+ 'Content-Type': 'multipart/form-data; boundary=' + boundary
+ }});
+ return res;
+}
+
+function runTest() {
+ return Promise.all([testFormDataParsing(makeRequest),
+ testFormDataParsing(makeResponse)]);
+}