1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/common/tests/unit/test_hawkrequest.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,210 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +"use strict"; 1.8 + 1.9 +Cu.import("resource://gre/modules/Log.jsm"); 1.10 +Cu.import("resource://services-common/utils.js"); 1.11 +Cu.import("resource://services-common/hawkrequest.js"); 1.12 + 1.13 +function do_register_cleanup() { 1.14 + Services.prefs.resetUserPrefs(); 1.15 + 1.16 + // remove the pref change listener 1.17 + let hawk = new HAWKAuthenticatedRESTRequest("https://example.com"); 1.18 + hawk._intl.uninit(); 1.19 +} 1.20 + 1.21 +function run_test() { 1.22 + Log.repository.getLogger("Services.Common.RESTRequest").level = 1.23 + Log.Level.Trace; 1.24 + initTestLogging("Trace"); 1.25 + 1.26 + run_next_test(); 1.27 +} 1.28 + 1.29 + 1.30 +add_test(function test_intl_accept_language() { 1.31 + let testCount = 0; 1.32 + let languages = [ 1.33 + "zu-NP;vo", // Nepalese dialect of Zulu, defaulting to Volapük 1.34 + "fa-CG;ik", // Congolese dialect of Farsei, defaulting to Inupiaq 1.35 + ]; 1.36 + 1.37 + function setLanguagePref(lang) { 1.38 + let acceptLanguage = Cc["@mozilla.org/supports-string;1"] 1.39 + .createInstance(Ci.nsISupportsString); 1.40 + acceptLanguage.data = lang; 1.41 + Services.prefs.setComplexValue( 1.42 + "intl.accept_languages", Ci.nsISupportsString, acceptLanguage); 1.43 + } 1.44 + 1.45 + let hawk = new HAWKAuthenticatedRESTRequest("https://example.com"); 1.46 + 1.47 + Services.prefs.addObserver("intl.accept_languages", checkLanguagePref, false); 1.48 + setLanguagePref(languages[testCount]); 1.49 + 1.50 + function checkLanguagePref() { 1.51 + var _done = false; 1.52 + CommonUtils.nextTick(function() { 1.53 + // Ensure we're only called for the number of entries in languages[]. 1.54 + do_check_true(testCount < languages.length); 1.55 + 1.56 + do_check_eq(hawk._intl.accept_languages, languages[testCount]); 1.57 + 1.58 + testCount++; 1.59 + if (testCount < languages.length) { 1.60 + // Set next language in prefs; Pref service will call checkNextLanguage. 1.61 + setLanguagePref(languages[testCount]); 1.62 + return; 1.63 + } 1.64 + 1.65 + // We've checked all the entries in languages[]. Cleanup and move on. 1.66 + do_print("Checked " + testCount + " languages. Removing checkLanguagePref as pref observer."); 1.67 + Services.prefs.removeObserver("intl.accept_languages", checkLanguagePref); 1.68 + run_next_test(); 1.69 + return; 1.70 + }); 1.71 + } 1.72 +}); 1.73 + 1.74 +add_test(function test_hawk_authenticated_request() { 1.75 + let onProgressCalled = false; 1.76 + let postData = {your: "data"}; 1.77 + 1.78 + // An arbitrary date - Feb 2, 1971. It ends in a bunch of zeroes to make our 1.79 + // computation with the hawk timestamp easier, since hawk throws away the 1.80 + // millisecond values. 1.81 + let then = 34329600000; 1.82 + 1.83 + let clockSkew = 120000; 1.84 + let timeOffset = -1 * clockSkew; 1.85 + let localTime = then + clockSkew; 1.86 + 1.87 + // Set the accept-languages pref to the Nepalese dialect of Zulu. 1.88 + let acceptLanguage = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString); 1.89 + acceptLanguage.data = 'zu-NP'; // omit trailing ';', which our HTTP libs snip 1.90 + Services.prefs.setComplexValue('intl.accept_languages', Ci.nsISupportsString, acceptLanguage); 1.91 + 1.92 + let credentials = { 1.93 + id: "eyJleHBpcmVzIjogMTM2NTAxMDg5OC4x", 1.94 + key: "qTZf4ZFpAMpMoeSsX3zVRjiqmNs=", 1.95 + algorithm: "sha256" 1.96 + }; 1.97 + 1.98 + let server = httpd_setup({ 1.99 + "/elysium": function(request, response) { 1.100 + do_check_true(request.hasHeader("Authorization")); 1.101 + 1.102 + // check that the header timestamp is our arbitrary system date, not 1.103 + // today's date. Note that hawk header timestamps are in seconds, not 1.104 + // milliseconds. 1.105 + let authorization = request.getHeader("Authorization"); 1.106 + let tsMS = parseInt(/ts="(\d+)"/.exec(authorization)[1], 10) * 1000; 1.107 + do_check_eq(tsMS, then); 1.108 + 1.109 + // This testing can be a little wonky. In an environment where 1.110 + // pref("intl.accept_languages") === 'en-US, en' 1.111 + // the header is sent as: 1.112 + // 'en-US,en;q=0.5' 1.113 + // hence our fake value for acceptLanguage. 1.114 + let lang = request.getHeader("Accept-Language"); 1.115 + do_check_eq(lang, acceptLanguage); 1.116 + 1.117 + let message = "yay"; 1.118 + response.setStatusLine(request.httpVersion, 200, "OK"); 1.119 + response.bodyOutputStream.write(message, message.length); 1.120 + } 1.121 + }); 1.122 + 1.123 + function onProgress() { 1.124 + onProgressCalled = true; 1.125 + } 1.126 + 1.127 + function onComplete(error) { 1.128 + do_check_eq(200, this.response.status); 1.129 + do_check_eq(this.response.body, "yay"); 1.130 + do_check_true(onProgressCalled); 1.131 + 1.132 + Services.prefs.resetUserPrefs(); 1.133 + let pref = Services.prefs.getComplexValue( 1.134 + "intl.accept_languages", Ci.nsIPrefLocalizedString); 1.135 + do_check_neq(acceptLanguage.data, pref.data); 1.136 + 1.137 + server.stop(run_next_test); 1.138 + } 1.139 + 1.140 + let url = server.baseURI + "/elysium"; 1.141 + let extra = { 1.142 + now: localTime, 1.143 + localtimeOffsetMsec: timeOffset 1.144 + }; 1.145 + 1.146 + let request = new HAWKAuthenticatedRESTRequest(url, credentials, extra); 1.147 + 1.148 + // Allow hawk._intl to respond to the language pref change 1.149 + CommonUtils.nextTick(function() { 1.150 + request.post(postData, onComplete, onProgress); 1.151 + }); 1.152 +}); 1.153 + 1.154 +add_test(function test_hawk_language_pref_changed() { 1.155 + let languages = [ 1.156 + "zu-NP", // Nepalese dialect of Zulu 1.157 + "fa-CG", // Congolese dialect of Farsi 1.158 + ]; 1.159 + 1.160 + let credentials = { 1.161 + id: "eyJleHBpcmVzIjogMTM2NTAxMDg5OC4x", 1.162 + key: "qTZf4ZFpAMpMoeSsX3zVRjiqmNs=", 1.163 + algorithm: "sha256", 1.164 + }; 1.165 + 1.166 + function setLanguage(lang) { 1.167 + let acceptLanguage = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString); 1.168 + acceptLanguage.data = lang; 1.169 + Services.prefs.setComplexValue("intl.accept_languages", Ci.nsISupportsString, acceptLanguage); 1.170 + } 1.171 + 1.172 + let server = httpd_setup({ 1.173 + "/foo": function(request, response) { 1.174 + do_check_eq(languages[1], request.getHeader("Accept-Language")); 1.175 + 1.176 + response.setStatusLine(request.httpVersion, 200, "OK"); 1.177 + }, 1.178 + }); 1.179 + 1.180 + let url = server.baseURI + "/foo"; 1.181 + let postData = {}; 1.182 + let request; 1.183 + 1.184 + setLanguage(languages[0]); 1.185 + 1.186 + // A new request should create the stateful object for tracking the current 1.187 + // language. 1.188 + request = new HAWKAuthenticatedRESTRequest(url, credentials); 1.189 + CommonUtils.nextTick(testFirstLanguage); 1.190 + 1.191 + function testFirstLanguage() { 1.192 + do_check_eq(languages[0], request._intl.accept_languages); 1.193 + 1.194 + // Change the language pref ... 1.195 + setLanguage(languages[1]); 1.196 + CommonUtils.nextTick(testRequest); 1.197 + } 1.198 + 1.199 + function testRequest() { 1.200 + // Change of language pref should be picked up, which we can see on the 1.201 + // server by inspecting the request headers. 1.202 + request = new HAWKAuthenticatedRESTRequest(url, credentials); 1.203 + request.post({}, function(error) { 1.204 + do_check_null(error); 1.205 + do_check_eq(200, this.response.status); 1.206 + 1.207 + Services.prefs.resetUserPrefs(); 1.208 + 1.209 + server.stop(run_next_test); 1.210 + }); 1.211 + } 1.212 +}); 1.213 +