/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ Components.utils.import("resource://gre/modules/Http.jsm"); Components.utils.import("resource://testing-common/httpd.js"); const BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream", "setInputStream"); var server; const kDefaultServerPort = 9000; const kSuccessPath = "/success"; const kBaseUrl = "http://localhost:" + kDefaultServerPort; const kSuccessUrl = kBaseUrl + kSuccessPath; const kPostPath = "/post"; const kPostUrl = kBaseUrl + kPostPath; const kPostDataSent = [["foo", "bar"], ["complex", "!*()@"]]; const kPostDataReceived = "foo=bar&complex=%21%2A%28%29%40"; const kPostMimeTypeReceived = "application/x-www-form-urlencoded; charset=utf-8"; const kJsonPostPath = "/json_post"; const kJsonPostUrl = kBaseUrl + kJsonPostPath; const kJsonPostData = JSON.stringify(kPostDataSent); const kJsonPostMimeType = "application/json"; const kPutPath = "/put"; const kPutUrl = kBaseUrl + kPutPath; const kPutDataSent = [["P", "NP"]]; const kPutDataReceived = "P=NP"; const kGetPath = "/get"; const kGetUrl = kBaseUrl + kGetPath; function successResult(aRequest, aResponse) { aResponse.setStatusLine(null, 200, "OK"); aResponse.setHeader("Content-Type", "application/json"); aResponse.write("Success!"); } function getDataChecker(aExpectedMethod, aExpectedData, aExpectedMimeType = null) { return function(aRequest, aResponse) { let body = new BinaryInputStream(aRequest.bodyInputStream); let bytes = []; let avail; while ((avail = body.available()) > 0) Array.prototype.push.apply(bytes, body.readByteArray(avail)); do_check_eq(aRequest.method, aExpectedMethod); // Checking if the Content-Type is as expected. if (aExpectedMimeType) { let contentType = aRequest.getHeader("Content-Type"); do_check_eq(contentType, aExpectedMimeType); } var data = String.fromCharCode.apply(null, bytes); do_check_eq(data, aExpectedData); aResponse.setStatusLine(null, 200, "OK"); aResponse.setHeader("Content-Type", "application/json"); aResponse.write("Success!"); } } add_test(function test_successCallback() { do_test_pending(); let options = { onLoad: function(aResponse) { do_check_eq(aResponse, "Success!"); do_test_finished(); run_next_test(); }, onError: function(e) { do_check_true(false); do_test_finished(); run_next_test(); } } httpRequest(kSuccessUrl, options); }); add_test(function test_errorCallback() { do_test_pending(); let options = { onSuccess: function(aResponse) { do_check_true(false); do_test_finished(); run_next_test(); }, onError: function(e, aResponse) { do_check_eq(e, "404 - Not Found"); do_test_finished(); run_next_test(); } } httpRequest(kBaseUrl + "/failure", options); }); add_test(function test_PostData() { do_test_pending(); let options = { onLoad: function(aResponse) { do_check_eq(aResponse, "Success!"); do_test_finished(); run_next_test(); }, onError: function(e) { do_check_true(false); do_test_finished(); run_next_test(); }, postData: kPostDataSent } httpRequest(kPostUrl, options); }); add_test(function test_PutData() { do_test_pending(); let options = { method: "PUT", onLoad: function(aResponse) { do_check_eq(aResponse, "Success!"); do_test_finished(); run_next_test(); }, onError: function(e) { do_check_true(false); do_test_finished(); run_next_test(); }, postData: kPutDataSent } httpRequest(kPutUrl, options); }); add_test(function test_GetData() { do_test_pending(); let options = { onLoad: function(aResponse) { do_check_eq(aResponse, "Success!"); do_test_finished(); run_next_test(); }, onError: function(e) { do_check_true(false); do_test_finished(); run_next_test(); }, postData: null } httpRequest(kGetUrl, options); }); add_test(function test_OptionalParameters() { let options = { onLoad: null, onError: null, logger: null }; // Just make sure that nothing throws when doing this (i.e. httpRequest // doesn't try to access null options). httpRequest(kGetUrl, options); run_next_test(); }); /** * Makes sure that httpRequest API allows setting a custom Content-Type header * for POST requests when data is a string. */ add_test(function test_CustomContentTypeOnPost() { do_test_pending(); // Preparing the request parameters. let options = { onLoad: function(aResponse) { do_check_eq(aResponse, "Success!"); do_test_finished(); run_next_test(); }, onError: function(e) { do_check_true(false); do_test_finished(); run_next_test(); }, postData: kJsonPostData, // Setting a custom Content-Type header. headers: [['Content-Type', "application/json"]] } // Firing the request. httpRequest(kJsonPostUrl, options); }); /** * Ensures that the httpRequest API provides a way to override the response * MIME type. */ add_test(function test_OverrideMimeType() { do_test_pending(); // Preparing the request parameters. const kMimeType = 'text/xml; charset=UTF-8'; let options = { onLoad: function(aResponse, xhr) { do_check_eq(aResponse, "Success!"); // Set the expected MIME-type. let reportedMimeType = xhr.getResponseHeader("Content-Type"); do_check_neq(reportedMimeType, kMimeType); // responseXML should not be not null if overriding mime type succeeded. do_check_true(xhr.responseXML != null); do_test_finished(); run_next_test(); }, onError: function(e) { do_check_true(false); do_test_finished(); run_next_test(); } }; // Firing the request. let xhr = httpRequest(kGetUrl, options); // Override the response MIME type. xhr.overrideMimeType(kMimeType); }); function run_test() { // Set up a mock HTTP server to serve a success page. server = new HttpServer(); server.registerPathHandler(kSuccessPath, successResult); server.registerPathHandler(kPostPath, getDataChecker("POST", kPostDataReceived, kPostMimeTypeReceived)); server.registerPathHandler(kPutPath, getDataChecker("PUT", kPutDataReceived)); server.registerPathHandler(kGetPath, getDataChecker("GET", "")); server.registerPathHandler(kJsonPostPath, getDataChecker("POST", kJsonPostData, kJsonPostMimeType)); server.start(kDefaultServerPort); run_next_test(); // Teardown. do_register_cleanup(function() { server.stop(function() { }); }); }