1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/b2g/components/test/unit/head_identity.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,159 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +const Ci = Components.interfaces; 1.8 +const Cu = Components.utils; 1.9 + 1.10 +// The following boilerplate makes sure that XPCom calls 1.11 +// that use the profile directory work. 1.12 + 1.13 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.14 +Cu.import("resource://gre/modules/Services.jsm"); 1.15 + 1.16 +XPCOMUtils.defineLazyModuleGetter(this, "MinimalIDService", 1.17 + "resource://gre/modules/identity/MinimalIdentity.jsm", 1.18 + "IdentityService"); 1.19 + 1.20 +XPCOMUtils.defineLazyModuleGetter(this, 1.21 + "Logger", 1.22 + "resource://gre/modules/identity/LogUtils.jsm"); 1.23 + 1.24 +XPCOMUtils.defineLazyServiceGetter(this, 1.25 + "uuidGenerator", 1.26 + "@mozilla.org/uuid-generator;1", 1.27 + "nsIUUIDGenerator"); 1.28 + 1.29 +const TEST_URL = "https://myfavoriteflan.com"; 1.30 +const TEST_USER = "uumellmahaye1969@hotmail.com"; 1.31 +const TEST_PRIVKEY = "i-am-a-secret"; 1.32 +const TEST_CERT = "i~like~pie"; 1.33 + 1.34 +// The following are utility functions for Identity testing 1.35 + 1.36 +function log(...aMessageArgs) { 1.37 + Logger.log.apply(Logger, ["test"].concat(aMessageArgs)); 1.38 +} 1.39 + 1.40 +function partial(fn) { 1.41 + let args = Array.prototype.slice.call(arguments, 1); 1.42 + return function() { 1.43 + return fn.apply(this, args.concat(Array.prototype.slice.call(arguments))); 1.44 + }; 1.45 +} 1.46 + 1.47 +function uuid() { 1.48 + return uuidGenerator.generateUUID().toString(); 1.49 +} 1.50 + 1.51 +// create a mock "doc" object, which the Identity Service 1.52 +// uses as a pointer back into the doc object 1.53 +function mockDoc(aParams, aDoFunc) { 1.54 + let mockedDoc = {}; 1.55 + mockedDoc.id = uuid(); 1.56 + 1.57 + // Properties of aParams may include loggedInUser 1.58 + Object.keys(aParams).forEach(function(param) { 1.59 + mockedDoc[param] = aParams[param]; 1.60 + }); 1.61 + 1.62 + // the origin is set inside nsDOMIdentity by looking at the 1.63 + // document.nodePrincipal.origin. Here we, we must satisfy 1.64 + // ourselves with pretending. 1.65 + mockedDoc.origin = "https://jedp.gov"; 1.66 + 1.67 + mockedDoc['do'] = aDoFunc; 1.68 + mockedDoc.doReady = partial(aDoFunc, 'ready'); 1.69 + mockedDoc.doLogin = partial(aDoFunc, 'login'); 1.70 + mockedDoc.doLogout = partial(aDoFunc, 'logout'); 1.71 + mockedDoc.doError = partial(aDoFunc, 'error'); 1.72 + mockedDoc.doCancel = partial(aDoFunc, 'cancel'); 1.73 + mockedDoc.doCoffee = partial(aDoFunc, 'coffee'); 1.74 + 1.75 + return mockedDoc; 1.76 +} 1.77 + 1.78 +// create a mock "pipe" object that would normally communicate 1.79 +// messages up to gaia (either the trusty ui or the hidden iframe), 1.80 +// and convey messages back down from gaia to the controller through 1.81 +// the message callback. 1.82 + 1.83 +// The mock receiving pipe simulates gaia which, after receiving messages 1.84 +// through the pipe, will call back with instructions to invoke 1.85 +// certain methods. It mocks what comes back from the other end of 1.86 +// the pipe. 1.87 +function mockReceivingPipe() { 1.88 + let MockedPipe = { 1.89 + communicate: function(aRpOptions, aGaiaOptions, aMessageCallback) { 1.90 + switch (aGaiaOptions.message) { 1.91 + case "identity-delegate-watch": 1.92 + aMessageCallback({json: {method: "ready"}}); 1.93 + break; 1.94 + case "identity-delegate-request": 1.95 + aMessageCallback({json: {method: "login", assertion: TEST_CERT}}); 1.96 + break; 1.97 + case "identity-delegate-logout": 1.98 + aMessageCallback({json: {method: "logout"}}); 1.99 + break; 1.100 + default: 1.101 + throw("what the what?? " + aGaiaOptions.message); 1.102 + break; 1.103 + } 1.104 + } 1.105 + }; 1.106 + return MockedPipe; 1.107 +} 1.108 + 1.109 +// The mock sending pipe lets us test what's actually getting put in the 1.110 +// pipe. 1.111 +function mockSendingPipe(aMessageCallback) { 1.112 + let MockedPipe = { 1.113 + communicate: function(aRpOptions, aGaiaOptions, aDummyCallback) { 1.114 + aMessageCallback(aRpOptions, aGaiaOptions); 1.115 + } 1.116 + }; 1.117 + return MockedPipe; 1.118 +} 1.119 + 1.120 +// mimicking callback funtionality for ease of testing 1.121 +// this observer auto-removes itself after the observe function 1.122 +// is called, so this is meant to observe only ONE event. 1.123 +function makeObserver(aObserveTopic, aObserveFunc) { 1.124 + let observer = { 1.125 + // nsISupports provides type management in C++ 1.126 + // nsIObserver is to be an observer 1.127 + QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]), 1.128 + 1.129 + observe: function (aSubject, aTopic, aData) { 1.130 + if (aTopic == aObserveTopic) { 1.131 + Services.obs.removeObserver(observer, aObserveTopic); 1.132 + aObserveFunc(aSubject, aTopic, aData); 1.133 + } 1.134 + } 1.135 + }; 1.136 + 1.137 + Services.obs.addObserver(observer, aObserveTopic, false); 1.138 +} 1.139 + 1.140 +// a hook to set up the ID service with an identity with keypair and all 1.141 +// when ready, invoke callback with the identity. It's there if we need it. 1.142 +function setup_test_identity(identity, cert, cb) { 1.143 + cb(); 1.144 +} 1.145 + 1.146 +// takes a list of functions and returns a function that 1.147 +// when called the first time, calls the first func, 1.148 +// then the next time the second, etc. 1.149 +function call_sequentially() { 1.150 + let numCalls = 0; 1.151 + let funcs = arguments; 1.152 + 1.153 + return function() { 1.154 + if (!funcs[numCalls]) { 1.155 + let argString = Array.prototype.slice.call(arguments).join(","); 1.156 + do_throw("Too many calls: " + argString); 1.157 + return; 1.158 + } 1.159 + funcs[numCalls].apply(funcs[numCalls],arguments); 1.160 + numCalls += 1; 1.161 + }; 1.162 +}