mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
466 lines
13 KiB
JavaScript
466 lines
13 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||
|
||
"use strict";
|
||
|
||
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||
|
||
const 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 _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||
.getService(Ci.nsIScriptSecurityManager)
|
||
.getAppCodebasePrincipal(uri, APP_ID, false);
|
||
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 _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||
.getService(Ci.nsIScriptSecurityManager)
|
||
.getAppCodebasePrincipal(uri, APP_ID, false);
|
||
let pm = Cc["@mozilla.org/permissionmanager;1"]
|
||
.getService(Ci.nsIPermissionManager);
|
||
pm.removeFromPrincipal(_principal, MOBILEID_PERM);
|
||
}
|
||
|
||
// === Mocks ===
|
||
|
||
let 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.
|
||
let 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.
|
||
let 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.
|
||
let 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);*/
|
||
|
||
let fakeMobileIdentityUIGlueFactory = {
|
||
createInstance: function(aOuter, aIid) {
|
||
return MobileIdentityUIGlue.QueryInterface(aIid);
|
||
}
|
||
};
|
||
|
||
// MobileIdentityUIGlue fake component.
|
||
let 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";
|
||
|
||
let 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,
|
||
])
|
||
};
|
||
|
||
let 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);
|