summaryrefslogtreecommitdiffstats
path: root/dom/tests/unit/test_Fetch.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/tests/unit/test_Fetch.js')
-rw-r--r--dom/tests/unit/test_Fetch.js318
1 files changed, 318 insertions, 0 deletions
diff --git a/dom/tests/unit/test_Fetch.js b/dom/tests/unit/test_Fetch.js
new file mode 100644
index 000000000..e87eb7180
--- /dev/null
+++ b/dom/tests/unit/test_Fetch.js
@@ -0,0 +1,318 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const {utils: Cu} = Components;
+
+Cu.importGlobalProperties(['fetch']);
+Cu.import("resource://testing-common/httpd.js");
+
+const BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
+ "nsIBinaryInputStream", "setInputStream");
+
+var server;
+
+function getBaseUrl () {
+ return "http://localhost:" + server.identity.primaryPort;
+}
+
+// a way to create some test defaults
+function createTestData(testPath) {
+ return {
+ testPath: testPath,
+ request: {
+ headers: {},
+ contentType: "application/json",
+ },
+ response: {
+ headers: {},
+ contentType: "application/json",
+ body: "{\"Look\": \"Success!\"}",
+ status: 200,
+ statusText: "OK"
+ },
+ };
+}
+
+// read body and content type information from a request
+function readDataFromRequest(aRequest) {
+ let requestData = {};
+ if (aRequest.method == "POST" || aRequest.method == "PUT") {
+ if (aRequest.bodyInputStream) {
+ let inputStream = new BinaryInputStream(aRequest.bodyInputStream);
+ let bytes = [];
+ let available;
+
+ while ((available = inputStream.available()) > 0) {
+ Array.prototype.push.apply(bytes, inputStream.readByteArray(available));
+ }
+
+ requestData.body = String.fromCharCode.apply(null, bytes);
+ requestData.contentType = aRequest.getHeader("Content-Type");
+ }
+ }
+ return requestData;
+}
+
+// write status information, content type information and body to a response
+function writeDataToResponse(aData, aResponse) {
+ aResponse.setStatusLine(null, aData.status, aData.statusText);
+ aResponse.setHeader("Content-Type", aData.contentType);
+ for (let header in aData.headers) {
+ aResponse.setHeader(header, aData.headers[header]);
+ }
+ aResponse.write(aData.body);
+}
+
+// test some GET functionality
+add_test(function test_GetData() {
+ do_test_pending();
+
+ let testData = createTestData("/getData");
+
+ // set up some headers to test
+ let headerNames = ["x-test-header", "x-other-test-header"];
+ for (let headerName of headerNames) {
+ testData.request.headers[headerName] = "test-value-for-" + headerName;
+ }
+
+ server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
+ try {
+ // check our request headers made it OK
+ for (let headerName of headerNames) {
+ do_check_eq(testData.request.headers[headerName],
+ aRequest.getHeader(headerName));
+ }
+
+ // send a response
+ writeDataToResponse(testData.response, aResponse);
+ } catch (e) {
+ do_report_unexpected_exception(e);
+ }
+ });
+
+ // fetch, via GET, with some request headers set
+ fetch(getBaseUrl() + testData.testPath, {headers: testData.request.headers})
+ .then(function(response){
+ // check response looks as expected
+ do_check_true(response.ok);
+ do_check_eq(response.status, testData.response.status);
+ do_check_eq(response.statusText, testData.response.statusText);
+
+ // check a response header looks OK:
+ do_check_eq(response.headers.get("Content-Type"),
+ testData.response.contentType);
+
+ // ... and again to check header names are case insensitive
+ do_check_eq(response.headers.get("content-type"),
+ testData.response.contentType);
+
+ // ensure response.text() returns a promise that resolves appropriately
+ response.text().then(function(text) {
+ do_check_eq(text, testData.response.body);
+ do_test_finished();
+ run_next_test();
+ });
+ }).catch(function(e){
+ do_report_unexpected_exception(e);
+ do_test_finished();
+ run_next_test();
+ });
+});
+
+// test a GET with no init
+add_test(function test_GetDataNoInit() {
+ do_test_pending();
+
+ let testData = createTestData("/getData");
+
+ server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
+ try {
+ // send a response
+ writeDataToResponse(testData.response, aResponse);
+ } catch (e) {
+ do_report_unexpected_exception(e);
+ }
+ });
+
+ fetch(getBaseUrl() + testData.testPath, {headers: testData.request.headers})
+ .then(function(response){
+ // check response looks as expected
+ do_check_true(response.ok);
+ do_check_eq(response.status, testData.response.status);
+
+ // ensure response.text() returns a promise that resolves appropriately
+ response.text().then(function(text) {
+ do_check_eq(text, testData.response.body);
+ do_test_finished();
+ run_next_test();
+ });
+ }).catch(function(e){
+ do_report_unexpected_exception(e);
+ do_test_finished();
+ run_next_test();
+ });
+});
+
+// test some error responses
+add_test(function test_get40x() {
+ do_test_pending();
+
+ // prepare a response with some 40x error - a 404 will do
+ let notFoundData = createTestData("/getNotFound");
+ notFoundData.response.status = 404;
+ notFoundData.response.statusText = "Not found";
+ notFoundData.response.body = null;
+
+ // No need to register a path handler - httpd will return 404 anyway.
+ // Fetch, via GET, the resource that doesn't exist
+ fetch(getBaseUrl() + notFoundData.testPath).then(function(response){
+ do_check_eq(response.status, 404);
+ do_test_finished();
+ run_next_test();
+ });
+});
+
+add_test(function test_get50x() {
+ do_test_pending();
+
+ // prepare a response with some server error - a 500 will do
+ let serverErrorData = createTestData("/serverError");
+ serverErrorData.response.status = 500;
+ serverErrorData.response.statusText = "The server broke";
+ serverErrorData.response.body = null;
+
+ server.registerPathHandler(serverErrorData.testPath,
+ function(aRequest, aResponse) {
+ try {
+ // send the error response
+ writeDataToResponse(serverErrorData.response, aResponse);
+ } catch (e) {
+ do_report_unexpected_exception(e);
+ }
+ });
+
+ // fetch, via GET, the resource that creates a server error
+ fetch(getBaseUrl() + serverErrorData.testPath).then(function(response){
+ do_check_eq(response.status, 500);
+ do_test_finished();
+ run_next_test();
+ });
+});
+
+// test a failure to connect
+add_test(function test_getTestFailedConnect() {
+ do_test_pending();
+ // try a server that's not there
+ fetch("http://localhost:4/should/fail").then(response => {
+ do_throw("Request should not succeed");
+ }).catch(err => {
+ do_check_eq(true, err instanceof TypeError);
+ do_test_finished();
+ run_next_test();
+ });
+});
+
+// test POSTing some JSON data
+add_test(function test_PostJSONData() {
+ do_test_pending();
+
+ let testData = createTestData("/postJSONData");
+ testData.request.body = "{\"foo\": \"bar\"}";
+
+ server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
+ try {
+ let requestData = readDataFromRequest(aRequest);
+
+ // Check the request body is OK
+ do_check_eq(requestData.body, testData.request.body);
+
+ // Check the content type is as expected
+ do_check_eq(requestData.contentType, testData.request.contentType);
+
+ writeDataToResponse(testData.response, aResponse);
+ } catch (e) {
+ do_check_true(false);
+ }
+ });
+
+ fetch(getBaseUrl() + testData.testPath, {
+ method: "POST",
+ body: testData.request.body,
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ }).then(function(aResponse) {
+ do_check_true(aResponse.ok);
+ do_check_eq(aResponse.status, testData.response.status);
+ do_check_eq(aResponse.statusText, testData.response.statusText);
+
+ do_test_finished();
+ run_next_test();
+ }).catch(function(e) {
+ do_report_unexpected_exception(e);
+ do_test_finished();
+ run_next_test();
+ });
+});
+
+// test POSTing some text
+add_test(function test_PostTextData() {
+ do_test_pending();
+
+ let testData = createTestData("/postTextData");
+ testData.request.body = "A plain text body";
+ testData.request.contentType = "text/plain";
+ let responseHeaderName = "some-response-header";
+ testData.response.headers[responseHeaderName] = "some header value";
+
+ server.registerPathHandler(testData.testPath, function(aRequest, aResponse) {
+ try {
+ let requestData = readDataFromRequest(aRequest);
+
+ // Check the request body is OK
+ do_check_eq(requestData.body, testData.request.body);
+
+ // Check the content type is as expected
+ do_check_eq(requestData.contentType, testData.request.contentType);
+
+ writeDataToResponse(testData.response, aResponse);
+ } catch (e) {
+ do_check_true(false);
+ }
+ });
+
+ fetch(getBaseUrl() + testData.testPath, {
+ method: "POST",
+ body: testData.request.body,
+ headers: {
+ 'Content-Type': testData.request.contentType
+ }
+ }).then(function(aResponse) {
+ do_check_true(aResponse.ok);
+ do_check_eq(aResponse.status, testData.response.status);
+ do_check_eq(aResponse.statusText, testData.response.statusText);
+
+ // check the response header is set OK
+ do_check_eq(aResponse.headers.get(responseHeaderName),
+ testData.response.headers[responseHeaderName]);
+
+ do_test_finished();
+ run_next_test();
+ }).catch(function(e) {
+ do_report_unexpected_exception(e);
+ do_test_finished();
+ run_next_test();
+ });
+});
+
+function run_test() {
+ // Set up an HTTP Server
+ server = new HttpServer();
+ server.start(-1);
+
+ run_next_test();
+
+ do_register_cleanup(function() {
+ server.stop(function() { });
+ });
+}