diff options
Diffstat (limited to 'dom/tests/unit/test_Fetch.js')
-rw-r--r-- | dom/tests/unit/test_Fetch.js | 318 |
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() { }); + }); +} |