tenfourfox/services/mobileid/tests/xpcshell/head.js

468 lines
13 KiB
JavaScript
Raw Permalink Normal View History

2017-04-19 07:56:45 +00:00
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
var Cm = Components.manager;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
(function initMobileIdTestingInfrastructure() {
do_get_profile();
const PREF_FORCE_HTTPS = "services.mobileid.forcehttps";
Services.prefs.setBoolPref(PREF_FORCE_HTTPS, false);
Services.prefs.setCharPref("services.mobileid.loglevel", "Debug");
Services.prefs.setCharPref("services.mobileid.server.uri",
"https://dummyurl.com");
}).call(this);
const DEBUG = false;
const GET_ASSERTION_IPC_MSG = "MobileId:GetAssertion";
const GET_ASSERTION_RETURN_OK = "MobileId:GetAssertion:Return:OK";
const GET_ASSERTION_RETURN_KO = "MobileId:GetAssertion:Return:KO";
// === Globals ===
const ORIGIN = "app://afakeorigin";
const APP_ID = 1;
const PRINCIPAL = {
origin: ORIGIN,
appId: APP_ID
};
const PHONE_NUMBER = "+34666555444";
const ANOTHER_PHONE_NUMBER = "+44123123123";
const VERIFICATION_CODE = "123456";
const SESSION_TOKEN = "aSessionToken";
const ICC_ID = "aIccId";
const ANOTHER_ICC_ID = "anotherIccId";
const MNC = "aMnc";
const ANOTHER_MNC = "anotherMnc";
const MCC = "aMcc";
const ANOTHER_MCC = "anotherMcc";
const OPERATOR = "aOperator";
const ANOTHER_OPERATOR = "anotherOperator";
const ICC_INFO = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmIccInfo,
Ci.nsIIccInfo]),
iccType: "usim",
iccid: ICC_ID,
mcc: MCC,
mnc: MNC,
msisdn: PHONE_NUMBER,
operator: OPERATOR
};
const ANOTHER_ICC_INFO = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmIccInfo,
Ci.nsIIccInfo]),
iccType: "usim",
iccid: ANOTHER_ICC_ID,
mcc: ANOTHER_MCC,
mnc: ANOTHER_MNC,
msisdn: ANOTHER_PHONE_NUMBER,
operator: ANOTHER_OPERATOR
};
const INVALID_ICC_INFO = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmIccInfo,
Ci.nsIIccInfo]),
iccType: "usim",
iccid: null,
mcc: "",
mnc: "",
msisdn: "",
operator: ""
};
const RADIO_INTERFACE = {
voice: {
network: {
shortName: OPERATOR
},
roaming: false
},
data: {
network: {
shortName: OPERATOR
}
}
};
const ANOTHER_RADIO_INTERFACE = {
voice: {
network: {
shortName: ANOTHER_OPERATOR
},
roaming: false
},
data: {
network: {
shortName: ANOTHER_OPERATOR
}
}
};
const INVALID_RADIO_INTERFACE = {
voice: {
network: {
shortName: ""
},
roaming: undefined
},
data: {
network: {
shortName: ""
}
}
};
const CERTIFICATE = "eyJhbGciOiJEUzI1NiJ9.eyJsYXN0QXV0aEF0IjoxNDA0NDY5NzkyODc3LCJ2ZXJpZmllZE1TSVNETiI6IiszMTYxNzgxNTc1OCIsInB1YmxpYy1rZXkiOnsiYWxnb3JpdGhtIjoiRFMiLCJ5IjoiNGE5YzkzNDY3MWZhNzQ3YmM2ZjMyNjE0YTg1MzUyZjY5NDcwMDdhNTRkMDAxMDY4OWU5ZjJjZjc0ZGUwYTEwZTRlYjlmNDk1ZGFmZTA0NGVjZmVlNDlkN2YwOGU4ODQyMDJiOTE5OGRhNWZhZWE5MGUzZjRmNzE1YzZjNGY4Yjc3MGYxZTU4YWZhNDM0NzVhYmFiN2VlZGE1MmUyNjk2YzFmNTljNzMzYjFlYzBhNGNkOTM1YWIxYzkyNzAxYjNiYTA5ZDRhM2E2MzNjNTJmZjE2NGYxMWY3OTg1YzlmZjY3ZThmZDFlYzA2NDU3MTdkMjBiNDE4YmM5M2YzYzVkNCIsInAiOiJmZjYwMDQ4M2RiNmFiZmM1YjQ1ZWFiNzg1OTRiMzUzM2Q1NTBkOWYxYmYyYTk5MmE3YThkYWE2ZGMzNGY4MDQ1YWQ0ZTZlMGM0MjlkMzM0ZWVlYWFlZmQ3ZTIzZDQ4MTBiZTAwZTRjYzE0OTJjYmEzMjViYTgxZmYyZDVhNWIzMDVhOGQxN2ViM2JmNGEwNmEzNDlkMzkyZTAwZDMyOTc0NGE1MTc5MzgwMzQ0ZTgyYTE4YzQ3OTMzNDM4Zjg5MWUyMmFlZWY4MTJkNjljOGY3NWUzMjZjYjcwZWEwMDBjM2Y3NzZkZmRiZDYwNDYzOGMyZWY3MTdmYzI2ZDAyZTE3IiwicSI6ImUyMWUwNGY5MTFkMWVkNzk5MTAwOGVjYWFiM2JmNzc1OTg0MzA5YzMiLCJnIjoiYzUyYTRhMGZmM2I3ZTYxZmRmMTg2N2NlODQxMzgzNjlhNjE1NGY0YWZhOTI5NjZlM2M4MjdlMjVjZmE2Y2Y1MDhiOTBlNWRlNDE5ZTEzMzdlMDdhMmU5ZTJhM2NkNWRlYTcwNGQxNzVmOGViZjZhZjM5N2Q2OWUxMTBiOTZhZmIxN2M3YTAzMjU5MzI5ZTQ4MjliMGQwM2JiYzc4OTZiMTViNGFkZTUzZTEzMDg1OGNjMzRkOTYyNjlhYTg5MDQxZjQwOTEzNmM3MjQyYTM4ODk1YzlkNWJjY2FkNGYzODlhZjFkN2E0YmQxMzk4YmQwNzJkZmZhODk2MjMzMzk3YSJ9LCJwcmluY2lwYWwiOiIwMzgxOTgyYS0xZTgzLTI1NjYtNjgzZS05MDRmNDA0NGM1MGRAbXNpc2RuLWRldi5zdGFnZS5tb3phd3MubmV0IiwiaWF0IjoxNDA0NDY5NzgyODc3LCJleHAiOjE0MDQ0OTEzOTI4NzcsImlzcyI6Im1zaXNkbi1kZXYuc3RhZ2UubW96YXdzLm5ldCJ9."
// === Helpers ===
function addPermission(aAction) {
let uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(ORIGIN, null, null);
let attrs = {appId: APP_ID};
let _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager)
.createCodebasePrincipal(uri, attrs);
let pm = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
pm.addFromPrincipal(_principal, MOBILEID_PERM, aAction);
}
function removePermission() {
let uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(ORIGIN, null, null);
let attrs = {appId: APP_ID};
let _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager)
.createCodebasePrincipal(uri, attrs);
let pm = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
pm.removeFromPrincipal(_principal, MOBILEID_PERM);
}
// === Mocks ===
var Mock = function(aOptions) {
if (!aOptions) {
aOptions = {};
}
this._options = aOptions;
this._spied = {};
};
Mock.prototype = {
_: function(aMethod) {
DEBUG && do_print("_ " + aMethod + JSON.stringify(this._spied));
let self = this;
return {
callsLength: function(aNumberOfCalls) {
if (aNumberOfCalls == 0) {
do_check_eq(self._spied[aMethod], undefined);
return;
}
do_check_eq(self._spied[aMethod].length, aNumberOfCalls);
},
call: function(aCallNumber) {
return {
arg: function(aArgNumber, aValue) {
let _arg = self._spied[aMethod][aCallNumber - 1][aArgNumber - 1];
if (Array.isArray(aValue)) {
do_check_eq(_arg.length, aValue.length)
for (let i = 0; i < _arg.length; i++) {
do_check_eq(_arg[i], aValue[i]);
}
return;
}
if (typeof aValue === 'object') {
do_check_eq(JSON.stringify(_arg), JSON.stringify(aValue));
return;
}
do_check_eq(_arg, aValue);
}
}
}
}
},
_spy: function(aMethod, aArgs) {
DEBUG && do_print(aMethod + " - " + JSON.stringify(aArgs));
if (!this._spied[aMethod]) {
this._spied[aMethod] = [];
}
this._spied[aMethod].push(aArgs);
},
getSpiedCalls: function(aMethod) {
return this._spied[aMethod];
}
};
// UI Glue mock up.
var MockUi = function(aOptions) {
Mock.call(this, aOptions);
};
MockUi.prototype = {
__proto__: Mock.prototype,
_startFlowResult: {
phoneNumber: PHONE_NUMBER,
mcc: MNC
},
_verifyCodePromptResult: {
verificationCode: VERIFICATION_CODE
},
startFlow: function() {
this._spy("startFlow", arguments);
return Promise.resolve(this._options.startFlowResult ||
this._startFlowResult);
},
verificationCodePrompt: function() {
this._spy("verifyCodePrompt", arguments);
return Promise.resolve(this._options.verificationCodePromptResult ||
this._verifyCodePromptResult);
},
verify: function() {
this._spy("verify", arguments);
},
error: function() {
this._spy("error", arguments);
},
verified: function() {
this._spy("verified", arguments);
},
set oncancel(aCallback) {
},
set onresendcode(aCallback) {
}
};
// Credentials store mock up.
var MockCredStore = function(aOptions) {
Mock.call(this, aOptions);
};
MockCredStore.prototype = {
__proto__: Mock.prototype,
_getByOriginResult: null,
_getByMsisdnResult: null,
_getByIccIdResult: null,
getByOrigin: function() {
this._spy("getByOrigin", arguments);
let result = this._getByOriginResult;
if (this._options.getByOriginResult) {
if (Array.isArray(this._options.getByOriginResult)) {
result = this._options.getByOriginResult.length ?
this._options.getByOriginResult.shift() : null;
} else {
result = this._options.getByOriginResult;
}
}
return Promise.resolve(result);
},
getByMsisdn: function() {
this._spy("getByMsisdn", arguments);
return Promise.resolve(this._options.getByMsisdnResult ||
this._getByMsisdnResult);
},
getByIccId: function() {
this._spy("getByIccId", arguments);
return Promise.resolve(this._options.getByIccIdResult ||
this._getByIccIdResult);
},
add: function() {
this._spy("add", arguments);
return Promise.resolve();
},
setDeviceIccIds: function() {
this._spy("setDeviceIccIds", arguments);
return Promise.resolve();
},
removeOrigin: function() {
this._spy("removeOrigin", arguments);
return Promise.resolve();
},
delete: function() {
this._spy("delete", arguments);
return Promise.resolve();
}
};
// Client mock up.
var MockClient = function(aOptions) {
Mock.call(this, aOptions);
};
MockClient.prototype = {
__proto__: Mock.prototype,
_discoverResult: {
verificationMethods: ["sms/mt"],
verificationDetails: {
"sms/mt": {
mtSender: "123",
url: "https://msisdn.accounts.firefox.com/v1/msisdn/sms/mt/verify"
}
}
},
_registerResult: {
msisdnSessionToken: SESSION_TOKEN
},
_smsMtVerifyResult: {},
_verifyCodeResult: {
msisdn: PHONE_NUMBER
},
_signResult: {
cert: CERTIFICATE
},
hawk: {
now: function() {
return Date.now();
}
},
discover: function() {
this._spy("discover", arguments);
return Promise.resolve(this._options.discoverResult ||
this._discoverResult);
},
register: function() {
this._spy("register", arguments);
return Promise.resolve(this._options.registerResult ||
this._registerResult);
},
smsMtVerify: function() {
this._spy("smsMtVerify", arguments);
return Promise.resolve(this._options.smsMtVerifyResult ||
this._smsMtVerifyResult);
},
verifyCode: function() {
this._spy("verifyCode", arguments);
if (this._options.verifyCodeError) {
let error = Array.isArray(this._options.verifyCodeError) ?
this._options.verifyCodeError.shift() :
this._options.verifyCodeError;
if (!this._options.verifyCodeError.length) {
this._options.verifyCodeError = null;
}
return Promise.reject(error);
}
return Promise.resolve(this._options.verifyCodeResult ||
this._verifyCodeResult);
},
sign: function() {
this._spy("sign", arguments);
if (this._options.signError) {
let error = Array.isArray(this._options.signError) ?
this._options.signError.shift() :
this._options.signError;
return Promise.reject(error);
}
return Promise.resolve(this._options.signResult || this._signResult);
}
};
// Override MobileIdentityUIGlue.
const kMobileIdentityUIGlueUUID = "{05df0566-ca8a-4ec7-bc76-78626ebfbe9a}";
const kMobileIdentityUIGlueContractID =
"@mozilla.org/services/mobileid-ui-glue;1";
// Save original factory.
/*const kMobileIdentityUIGlueFactory =
Cm.getClassObject(Cc[kMobileIdentityUIGlueContractID], Ci.nsIFactory);*/
var fakeMobileIdentityUIGlueFactory = {
createInstance: function(aOuter, aIid) {
return MobileIdentityUIGlue.QueryInterface(aIid);
}
};
// MobileIdentityUIGlue fake component.
var MobileIdentityUIGlue = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileIdentityUIGlue]),
};
(function registerFakeMobileIdentityUIGlue() {
Cm.QueryInterface(Ci.nsIComponentRegistrar)
.registerFactory(Components.ID(kMobileIdentityUIGlueUUID),
"MobileIdentityUIGlue",
kMobileIdentityUIGlueContractID,
fakeMobileIdentityUIGlueFactory);
})();
// The tests rely on having an app registered. Otherwise, it will throw.
// Override XULAppInfo.
const XUL_APP_INFO_UUID = Components.ID("{84fdc459-d96d-421c-9bff-a8193233ae75}");
const XUL_APP_INFO_CONTRACT_ID = "@mozilla.org/xre/app-info;1";
var XULAppInfo = {
vendor: "Mozilla",
name: "MobileIdTest",
ID: "{230de50e-4cd1-11dc-8314-0800200b9a66}",
version: "1",
appBuildID: "2007010101",
platformVersion: "",
platformBuildID: "2007010101",
inSafeMode: false,
logConsoleErrors: true,
OS: "XPCShell",
XPCOMABI: "noarch-spidermonkey",
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIXULAppInfo,
Ci.nsIXULRuntime,
])
};
var XULAppInfoFactory = {
createInstance: function (outer, iid) {
if (outer != null) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return XULAppInfo.QueryInterface(iid);
}
};
Cm.QueryInterface(Ci.nsIComponentRegistrar)
.registerFactory(XUL_APP_INFO_UUID,
"XULAppInfo",
XUL_APP_INFO_CONTRACT_ID,
XULAppInfoFactory);