1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-request.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,442 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const { Request } = require("sdk/request"); 1.9 +const { pathFor } = require("sdk/system"); 1.10 +const file = require("sdk/io/file"); 1.11 +const { URL } = require("sdk/url"); 1.12 +const { extend } = require("sdk/util/object"); 1.13 +const { Loader } = require("sdk/test/loader"); 1.14 +const options = require("@test/options"); 1.15 + 1.16 +const loader = Loader(module); 1.17 +const httpd = loader.require("sdk/test/httpd"); 1.18 +if (options.parseable || options.verbose) 1.19 + loader.sandbox("sdk/test/httpd").DEBUG = true; 1.20 +const { startServerAsync } = httpd; 1.21 + 1.22 +const { Cc, Ci, Cu } = require("chrome"); 1.23 +const { Services } = Cu.import("resource://gre/modules/Services.jsm"); 1.24 + 1.25 +// Use the profile directory for the temporary files as that will be deleted 1.26 +// when tests are complete 1.27 +const basePath = pathFor("ProfD"); 1.28 +const port = 8099; 1.29 + 1.30 + 1.31 +exports.testOptionsValidator = function(assert) { 1.32 + // First, a simple test to make sure we didn't break normal functionality. 1.33 + assert.throws(function () { 1.34 + Request({ 1.35 + url: null 1.36 + }); 1.37 + }, /The option "url" is invalid./); 1.38 + 1.39 + // Next we'll have a Request that doesn't throw from c'tor, but from a setter. 1.40 + let req = Request({ 1.41 + url: "http://playground.zpao.com/jetpack/request/text.php", 1.42 + onComplete: function () {} 1.43 + }); 1.44 + assert.throws(function () { 1.45 + req.url = 'www.mozilla.org'; 1.46 + }, /The option "url" is invalid/); 1.47 + // The url shouldn't have changed, so check that 1.48 + assert.equal(req.url, "http://playground.zpao.com/jetpack/request/text.php"); 1.49 +}; 1.50 + 1.51 +exports.testContentValidator = function(assert, done) { 1.52 + runMultipleURLs(null, assert, done, { 1.53 + url: "data:text/html;charset=utf-8,response", 1.54 + content: { 'key1' : null, 'key2' : 'some value' }, 1.55 + onComplete: function(response) { 1.56 + assert.equal(response.text, "response?key1=null&key2=some+value"); 1.57 + } 1.58 + }); 1.59 +}; 1.60 + 1.61 +// This is a request to a file that exists. 1.62 +exports.testStatus200 = function (assert, done) { 1.63 + let srv = startServerAsync(port, basePath); 1.64 + let content = "Look ma, no hands!\n"; 1.65 + let basename = "test-request.txt" 1.66 + prepareFile(basename, content); 1.67 + 1.68 + var req = Request({ 1.69 + url: "http://localhost:" + port + "/" + basename, 1.70 + onComplete: function (response) { 1.71 + assert.equal(this, req, "`this` should be request"); 1.72 + assert.equal(response.status, 200); 1.73 + assert.equal(response.statusText, "OK"); 1.74 + assert.equal(response.headers["Content-Type"], "text/plain"); 1.75 + assert.equal(response.text, content); 1.76 + srv.stop(done); 1.77 + } 1.78 + }).get(); 1.79 +}; 1.80 + 1.81 +// This tries to get a file that doesn't exist 1.82 +exports.testStatus404 = function (assert, done) { 1.83 + var srv = startServerAsync(port, basePath); 1.84 + 1.85 + runMultipleURLs(srv, assert, done, { 1.86 + // the following URL doesn't exist 1.87 + url: "http://localhost:" + port + "/test-request-404.txt", 1.88 + onComplete: function (response) { 1.89 + assert.equal(response.status, 404); 1.90 + assert.equal(response.statusText, "Not Found"); 1.91 + } 1.92 + }); 1.93 +}; 1.94 + 1.95 +// a simple file with a known header 1.96 +exports.testKnownHeader = function (assert, done) { 1.97 + var srv = startServerAsync(port, basePath); 1.98 + 1.99 + // Create the file that will be requested with the associated headers file 1.100 + let content = "This tests adding headers to the server's response.\n"; 1.101 + let basename = "test-request-headers.txt"; 1.102 + let headerContent = "x-jetpack-header: Jamba Juice\n"; 1.103 + let headerBasename = "test-request-headers.txt^headers^"; 1.104 + prepareFile(basename, content); 1.105 + prepareFile(headerBasename, headerContent); 1.106 + 1.107 + runMultipleURLs(srv, assert, done, { 1.108 + url: "http://localhost:" + port + "/test-request-headers.txt", 1.109 + onComplete: function (response) { 1.110 + assert.equal(response.headers["x-jetpack-header"], "Jamba Juice"); 1.111 + } 1.112 + }); 1.113 +}; 1.114 + 1.115 +// complex headers 1.116 +exports.testComplexHeader = function (assert, done) { 1.117 + let srv = startServerAsync(port, basePath); 1.118 + 1.119 + let basename = "test-request-complex-headers.sjs"; 1.120 + let content = handleRequest.toString(); 1.121 + prepareFile(basename, content); 1.122 + 1.123 + let headers = { 1.124 + "x-jetpack-header": "Jamba Juice is: delicious", 1.125 + "x-jetpack-header-2": "foo,bar", 1.126 + "x-jetpack-header-3": "sup dawg, i heard you like x, so we put a x in " + 1.127 + "yo x so you can y while you y", 1.128 + "Set-Cookie": "foo=bar\nbaz=foo" 1.129 + }; 1.130 + 1.131 + runMultipleURLs(srv, assert, done, { 1.132 + url: "http://localhost:" + port + "/test-request-complex-headers.sjs", 1.133 + onComplete: function (response) { 1.134 + for (k in headers) { 1.135 + assert.equal(response.headers[k], headers[k]); 1.136 + } 1.137 + } 1.138 + }); 1.139 +}; 1.140 + 1.141 +// Force Allow Third Party cookies 1.142 +exports.test3rdPartyCookies = function (assert, done) { 1.143 + let srv = startServerAsync(port, basePath); 1.144 + 1.145 + let basename = "test-request-3rd-party-cookies.sjs"; 1.146 + 1.147 + // Function to handle the requests in the server 1.148 + let content = function handleRequest(request, response) { 1.149 + var cookiePresent = request.hasHeader("Cookie"); 1.150 + // If no cookie, set it 1.151 + if(!cookiePresent) { 1.152 + response.setHeader("Set-Cookie", "cookie=monster;", "true"); 1.153 + response.setHeader("x-jetpack-3rd-party", "false", "true"); 1.154 + } else { 1.155 + // We got the cookie, say so 1.156 + response.setHeader("x-jetpack-3rd-party", "true", "true"); 1.157 + } 1.158 + 1.159 + response.write("<html><body>This tests 3rd party cookies.</body></html>"); 1.160 + }.toString(); 1.161 + 1.162 + prepareFile(basename, content); 1.163 + 1.164 + // Disable the 3rd party cookies 1.165 + Services.prefs.setIntPref("network.cookie.cookieBehavior", 1); 1.166 + 1.167 + Request({ 1.168 + url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs", 1.169 + onComplete: function (response) { 1.170 + // Check that the server created the cookie 1.171 + assert.equal(response.headers['Set-Cookie'], 'cookie=monster;'); 1.172 + 1.173 + // Check it wasn't there before 1.174 + assert.equal(response.headers['x-jetpack-3rd-party'], 'false'); 1.175 + 1.176 + // Make a second request, and check that the server this time 1.177 + // got the cookie 1.178 + Request({ 1.179 + url: "http://localhost:" + port + "/test-request-3rd-party-cookies.sjs", 1.180 + onComplete: function (response) { 1.181 + assert.equal(response.headers['x-jetpack-3rd-party'], 'true'); 1.182 + srv.stop(done); 1.183 + } 1.184 + }).get(); 1.185 + } 1.186 + }).get(); 1.187 +}; 1.188 + 1.189 +exports.testSimpleJSON = function (assert, done) { 1.190 + let srv = startServerAsync(port, basePath); 1.191 + let json = { foo: "bar" }; 1.192 + let basename = "test-request.json"; 1.193 + prepareFile(basename, JSON.stringify(json)); 1.194 + 1.195 + runMultipleURLs(srv, assert, done, { 1.196 + url: "http://localhost:" + port + "/" + basename, 1.197 + onComplete: function (response) { 1.198 + assert.deepEqual(response.json, json); 1.199 + } 1.200 + }); 1.201 +}; 1.202 + 1.203 +exports.testInvalidJSON = function (assert, done) { 1.204 + let srv = startServerAsync(port, basePath); 1.205 + let basename = "test-request-invalid.json"; 1.206 + prepareFile(basename, '"this": "isn\'t JSON"'); 1.207 + 1.208 + runMultipleURLs(srv, assert, done, { 1.209 + url: "http://localhost:" + port + "/" + basename, 1.210 + onComplete: function (response) { 1.211 + assert.equal(response.json, null); 1.212 + } 1.213 + }); 1.214 +}; 1.215 + 1.216 +exports.testDelete = function (assert, done) { 1.217 + let srv = startServerAsync(port, basePath); 1.218 + 1.219 + srv.registerPathHandler("/test-delete", 1.220 + function handle(request, response) { 1.221 + response.setHeader("Content-Type", "text/plain", false); 1.222 + }); 1.223 + 1.224 + Request({ 1.225 + url: "http://localhost:" + port + "/test-delete", 1.226 + onComplete: function (response) { 1.227 + // We cannot access the METHOD of the request to verify it's set 1.228 + // correctly. 1.229 + assert.equal(response.text, ""); 1.230 + assert.equal(response.statusText, "OK"); 1.231 + assert.equal(response.headers["Content-Type"], "text/plain"); 1.232 + srv.stop(done); 1.233 + } 1.234 + }).delete(); 1.235 +}; 1.236 + 1.237 +exports.testHead = function (assert, done) { 1.238 + let srv = startServerAsync(port, basePath); 1.239 + 1.240 + srv.registerPathHandler("/test-head", 1.241 + function handle(request, response) { 1.242 + response.setHeader("Content-Type", "text/plain", false); 1.243 + }); 1.244 + 1.245 + Request({ 1.246 + url: "http://localhost:" + port + "/test-head", 1.247 + onComplete: function (response) { 1.248 + assert.equal(response.text, ""); 1.249 + assert.equal(response.statusText, "OK"); 1.250 + assert.equal(response.headers["Content-Type"], "text/plain"); 1.251 + srv.stop(done); 1.252 + } 1.253 + }).head(); 1.254 +}; 1.255 + 1.256 +function runMultipleURLs (srv, assert, done, options) { 1.257 + let urls = [options.url, URL(options.url)]; 1.258 + let cb = options.onComplete; 1.259 + let ran = 0; 1.260 + let onComplete = function (res) { 1.261 + cb(res); 1.262 + if (++ran === urls.length) 1.263 + srv ? srv.stop(done) : done(); 1.264 + }; 1.265 + urls.forEach(function (url) { 1.266 + Request(extend(options, { url: url, onComplete: onComplete })).get(); 1.267 + }); 1.268 +} 1.269 + 1.270 +// All tests below here require a network connection. They will be commented out 1.271 +// when checked in. If you'd like to run them, simply uncomment them. 1.272 +// 1.273 +// When we have the means, these tests will be converted so that they don't 1.274 +// require an external server nor a network connection. 1.275 + 1.276 +/* 1.277 +exports.testGetWithParamsNotContent = function (assert, done) { 1.278 + Request({ 1.279 + url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar", 1.280 + onComplete: function (response) { 1.281 + let expected = { 1.282 + "POST": [], 1.283 + "GET" : { foo: "bar" } 1.284 + }; 1.285 + assert.deepEqual(response.json, expected); 1.286 + done(); 1.287 + } 1.288 + }).get(); 1.289 +} 1.290 + 1.291 +exports.testGetWithContent = function (assert, done) { 1.292 + Request({ 1.293 + url: "http://playground.zpao.com/jetpack/request/getpost.php", 1.294 + content: { foo: "bar" }, 1.295 + onComplete: function (response) { 1.296 + let expected = { 1.297 + "POST": [], 1.298 + "GET" : { foo: "bar" } 1.299 + }; 1.300 + assert.deepEqual(response.json, expected); 1.301 + done(); 1.302 + } 1.303 + }).get(); 1.304 +} 1.305 + 1.306 +exports.testGetWithParamsAndContent = function (assert, done) { 1.307 + Request({ 1.308 + url: "http://playground.zpao.com/jetpack/request/getpost.php?foo=bar", 1.309 + content: { baz: "foo" }, 1.310 + onComplete: function (response) { 1.311 + let expected = { 1.312 + "POST": [], 1.313 + "GET" : { foo: "bar", baz: "foo" } 1.314 + }; 1.315 + assert.deepEqual(response.json, expected); 1.316 + done(); 1.317 + } 1.318 + }).get(); 1.319 +} 1.320 + 1.321 +exports.testSimplePost = function (assert, done) { 1.322 + Request({ 1.323 + url: "http://playground.zpao.com/jetpack/request/getpost.php", 1.324 + content: { foo: "bar" }, 1.325 + onComplete: function (response) { 1.326 + let expected = { 1.327 + "POST": { foo: "bar" }, 1.328 + "GET" : [] 1.329 + }; 1.330 + assert.deepEqual(response.json, expected); 1.331 + done(); 1.332 + } 1.333 + }).post(); 1.334 +} 1.335 + 1.336 +exports.testEncodedContent = function (assert, done) { 1.337 + Request({ 1.338 + url: "http://playground.zpao.com/jetpack/request/getpost.php", 1.339 + content: "foo=bar&baz=foo", 1.340 + onComplete: function (response) { 1.341 + let expected = { 1.342 + "POST": [], 1.343 + "GET" : { foo: "bar", baz: "foo" } 1.344 + }; 1.345 + assert.deepEqual(response.json, expected); 1.346 + done(); 1.347 + } 1.348 + }).get(); 1.349 +} 1.350 + 1.351 +exports.testEncodedContentWithSpaces = function (assert, done) { 1.352 + Request({ 1.353 + url: "http://playground.zpao.com/jetpack/request/getpost.php", 1.354 + content: "foo=bar+hop!&baz=foo", 1.355 + onComplete: function (response) { 1.356 + let expected = { 1.357 + "POST": [], 1.358 + "GET" : { foo: "bar hop!", baz: "foo" } 1.359 + }; 1.360 + assert.deepEqual(response.json, expected); 1.361 + done(); 1.362 + } 1.363 + }).get(); 1.364 +} 1.365 + 1.366 +exports.testGetWithArray = function (assert, done) { 1.367 + Request({ 1.368 + url: "http://playground.zpao.com/jetpack/request/getpost.php", 1.369 + content: { foo: [1, 2], baz: "foo" }, 1.370 + onComplete: function (response) { 1.371 + let expected = { 1.372 + "POST": [], 1.373 + "GET" : { foo: [1, 2], baz: "foo" } 1.374 + }; 1.375 + assert.deepEqual(response.json, expected); 1.376 + done(); 1.377 + } 1.378 + }).get(); 1.379 +} 1.380 + 1.381 +exports.testGetWithNestedArray = function (assert, done) { 1.382 + Request({ 1.383 + url: "http://playground.zpao.com/jetpack/request/getpost.php", 1.384 + content: { foo: [1, 2, [3, 4]], bar: "baz" }, 1.385 + onComplete: function (response) { 1.386 + let expected = { 1.387 + "POST": [], 1.388 + "GET" : this.content 1.389 + }; 1.390 + assert.deepEqual(response.json, expected); 1.391 + done(); 1.392 + } 1.393 + }).get(); 1.394 +} 1.395 + 1.396 +exports.testGetWithNestedArray = function (assert, done) { 1.397 + let request = Request({ 1.398 + url: "http://playground.zpao.com/jetpack/request/getpost.php", 1.399 + content: { 1.400 + foo: [1, 2, { 1.401 + omg: "bbq", 1.402 + "all your base!": "are belong to us" 1.403 + }], 1.404 + bar: "baz" 1.405 + }, 1.406 + onComplete: function (response) { 1.407 + let expected = { 1.408 + "POST": [], 1.409 + "GET" : request.content 1.410 + }; 1.411 + assert.deepEqual(response.json, expected); 1.412 + done(); 1.413 + } 1.414 + }).get(); 1.415 +} 1.416 +*/ 1.417 + 1.418 +function prepareFile(basename, content) { 1.419 + let filePath = file.join(basePath, basename); 1.420 + let fileStream = file.open(filePath, 'w'); 1.421 + fileStream.write(content); 1.422 + fileStream.close(); 1.423 +} 1.424 + 1.425 +// Helper function for testComplexHeaders 1.426 +function handleRequest(request, response) { 1.427 + // Test header with an extra colon 1.428 + response.setHeader("x-jetpack-header", "Jamba Juice is: delicious", "true"); 1.429 + 1.430 + // Test that multiple headers with the same name coalesce 1.431 + response.setHeader("x-jetpack-header-2", "foo", "true"); 1.432 + response.setHeader("x-jetpack-header-2", "bar", "true"); 1.433 + 1.434 + // Test that headers with commas work 1.435 + response.setHeader("x-jetpack-header-3", "sup dawg, i heard you like x, " + 1.436 + "so we put a x in yo x so you can y while you y", "true"); 1.437 + 1.438 + // Test that multiple cookies work 1.439 + response.setHeader("Set-Cookie", "foo=bar", "true"); 1.440 + response.setHeader("Set-Cookie", "baz=foo", "true"); 1.441 + 1.442 + response.write("<html><body>This file tests more complex headers.</body></html>"); 1.443 +} 1.444 + 1.445 +require('sdk/test').run(exports);