Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
16
gaia/tv_apps/smart-system/test/apps/contextmenuapp/index.html
Executable file
16
gaia/tv_apps/smart-system/test/apps/contextmenuapp/index.html
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Fake Context Menu</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a contextmenu="context-menu" href="http://example.com" id="link">A Link!</a>
|
||||
<menu type="context" id="context-menu">
|
||||
<menuitem id="test-menu-1" label="test-menu-1"></menuitem>
|
||||
<menuitem id="test-menu-2" label="test-menu-2"></menuitem>
|
||||
</menu>
|
||||
</body>
|
||||
</html>
|
||||
11
gaia/tv_apps/smart-system/test/apps/contextmenuapp/manifest.webapp
Executable file
11
gaia/tv_apps/smart-system/test/apps/contextmenuapp/manifest.webapp
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "Context Menu App",
|
||||
"description": "App used to test context menus",
|
||||
"type": "privileged",
|
||||
"launch_path": "/index.html",
|
||||
"fullscreen": true,
|
||||
"developer": {
|
||||
"name": "The Gaia Team",
|
||||
"url": "https://github.com/mozilla-b2g/gaia"
|
||||
}
|
||||
}
|
||||
24
gaia/tv_apps/smart-system/test/apps/hosted-app/ime_manifest.webapp
Executable file
24
gaia/tv_apps/smart-system/test/apps/hosted-app/ime_manifest.webapp
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "LOL Keyboard",
|
||||
"description": "An useless virtual keyboard that sends \\o/.",
|
||||
"role": "input",
|
||||
"launch_path": "/settings.html",
|
||||
"developer": {
|
||||
"name": "The Gaia Team",
|
||||
"url": "https://github.com/mozilla-b2g/gaia"
|
||||
},
|
||||
"permissions": {
|
||||
"input": {
|
||||
"description": "Send key events and characters to user focused input fields."
|
||||
}
|
||||
},
|
||||
"inputs": {
|
||||
"lol": {
|
||||
"launch_path": "/index.html",
|
||||
"name": "\\o/",
|
||||
"description": "LOL layout",
|
||||
"types": ["text", "url", "number"]
|
||||
}
|
||||
},
|
||||
"default_locale": "en-US"
|
||||
}
|
||||
12
gaia/tv_apps/smart-system/test/apps/hosted-app/index.html
Executable file
12
gaia/tv_apps/smart-system/test/apps/hosted-app/index.html
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Nothing</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
Nothing here
|
||||
</body>
|
||||
</html>
|
||||
10
gaia/tv_apps/smart-system/test/apps/hosted-app/manifest.webapp
Executable file
10
gaia/tv_apps/smart-system/test/apps/hosted-app/manifest.webapp
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "Hosted app for test",
|
||||
"description": "Hosted app for test",
|
||||
"launch_path": "/index.html",
|
||||
"fullscreen": true,
|
||||
"developer": {
|
||||
"name": "The Gaia Team",
|
||||
"url": "https://github.com/mozilla-b2g/gaia"
|
||||
}
|
||||
}
|
||||
12
gaia/tv_apps/smart-system/test/apps/modaldialogapp/index.html
Executable file
12
gaia/tv_apps/smart-system/test/apps/modaldialogapp/index.html
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Fake App Modal Dialog</title>
|
||||
<script defer src="modaldialog.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
11
gaia/tv_apps/smart-system/test/apps/modaldialogapp/manifest.webapp
Executable file
11
gaia/tv_apps/smart-system/test/apps/modaldialogapp/manifest.webapp
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": ">>> Modal Dialog <<<",
|
||||
"description": "App used to test modal dialogs",
|
||||
"type": "privileged",
|
||||
"launch_path": "/index.html",
|
||||
"fullscreen": true,
|
||||
"developer": {
|
||||
"name": "The Gaia Team",
|
||||
"url": "https://github.com/mozilla-b2g/gaia"
|
||||
}
|
||||
}
|
||||
18
gaia/tv_apps/smart-system/test/apps/modaldialogapp/modaldialog.js
Executable file
18
gaia/tv_apps/smart-system/test/apps/modaldialogapp/modaldialog.js
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
/* exported showDialog */
|
||||
'use strict';
|
||||
|
||||
function showDialog(type, message) {
|
||||
setTimeout(function() {
|
||||
switch(type) {
|
||||
case 'alert':
|
||||
alert(message);
|
||||
break;
|
||||
case 'prompt':
|
||||
prompt(message);
|
||||
break;
|
||||
case 'confirm':
|
||||
confirm(message);
|
||||
break;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
14
gaia/tv_apps/smart-system/test/marionette/.jshintrc
Executable file
14
gaia/tv_apps/smart-system/test/marionette/.jshintrc
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "../../../../.jshintrc",
|
||||
"node": true,
|
||||
"predef": [
|
||||
"suite",
|
||||
"test",
|
||||
"setup",
|
||||
"teardown",
|
||||
"suiteSetup",
|
||||
"suiteTeardown",
|
||||
"marionette",
|
||||
"marionetteScriptFinished"
|
||||
]
|
||||
}
|
||||
151
gaia/tv_apps/smart-system/test/marionette/app_install_dialog_test.js
Executable file
151
gaia/tv_apps/smart-system/test/marionette/app_install_dialog_test.js
Executable file
|
|
@ -0,0 +1,151 @@
|
|||
'use strict';
|
||||
|
||||
var Keys = {
|
||||
'enter': '\ue006',
|
||||
'left': '\ue012',
|
||||
'right': '\ue014'
|
||||
};
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var AppInstaller = require('./lib/app_install');
|
||||
var Server = require('../../../../shared/test/integration/server');
|
||||
|
||||
// Bug 1207453 - Skip the test due to unknown test enviroment issue for now.
|
||||
// We should investigate the issue and re-enable the test later.
|
||||
marionette.skip('app install manager tests', function() {
|
||||
|
||||
var opts = {
|
||||
apps: {},
|
||||
hostOptions: {
|
||||
screen: {
|
||||
width: 1920,
|
||||
height: 1080
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var client = marionette.client({
|
||||
profile: opts,
|
||||
// XXX: Set this to true once Accessibility is implemented in TV
|
||||
desiredCapabilities: { raisesAccessibilityExceptions: false }
|
||||
});
|
||||
var system;
|
||||
var appInstaller;
|
||||
var server;
|
||||
var serverManifestURL;
|
||||
var serverIMEURL;
|
||||
|
||||
suiteSetup(function(done) {
|
||||
Server.create(__dirname + '/../apps/hosted-app', function(err, _server) {
|
||||
server = _server;
|
||||
serverManifestURL = server.url('manifest.webapp');
|
||||
serverIMEURL = server.url('ime_manifest.webapp');
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
server.stop();
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
system = client.loader.getAppClass('smart-system', 'system', 'tv_apps');
|
||||
appInstaller = new AppInstaller(client);
|
||||
// Once the os-logo is disappeared, the first app is shown and focused. It
|
||||
// implies system is ready to go.
|
||||
client.helper.waitForElementToDisappear('#os-logo');
|
||||
});
|
||||
|
||||
test('install app', { devices: ['tv'] }, function() {
|
||||
// install app
|
||||
appInstaller.install(serverManifestURL);
|
||||
// press install button
|
||||
var installButton = client.helper.waitForElement(
|
||||
system.Selector.appInstallInstallButton);
|
||||
installButton.sendKeys(Keys.enter);
|
||||
// check app installed
|
||||
system.waitForAppInstalled(serverManifestURL);
|
||||
});
|
||||
|
||||
test('install app and cancel it', { devices: ['tv'] }, function() {
|
||||
// install app
|
||||
appInstaller.install(serverManifestURL);
|
||||
// press install button
|
||||
var cancelInstallButton = client.helper.waitForElement(
|
||||
system.Selector.appInstallCancelButton);
|
||||
|
||||
cancelInstallButton.sendKeys(Keys.left);
|
||||
assert.isTrue(cancelInstallButton.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}), 'cancel button should be focused.');
|
||||
|
||||
cancelInstallButton.sendKeys(Keys.enter);
|
||||
var cancelConfirmButton = client.helper.waitForElement(
|
||||
system.Selector.appCancelInstallConfirmButton);
|
||||
|
||||
system.waitForEvent('modal-dialog-opened');
|
||||
assert.isTrue(cancelConfirmButton.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}), 'confirm button should be focused.');
|
||||
cancelConfirmButton.sendKeys(Keys.enter);
|
||||
|
||||
assert.isFalse(system.isAppInstalled(serverManifestURL),
|
||||
'app should not be installed');
|
||||
});
|
||||
|
||||
test('install app and uninstall it', { devices: ['tv'] }, function() {
|
||||
// install app
|
||||
appInstaller.install(serverManifestURL);
|
||||
var installButton = client.helper.waitForElement(
|
||||
system.Selector.appInstallInstallButton);
|
||||
installButton.sendKeys(Keys.enter);
|
||||
system.waitForAppInstalled(serverManifestURL);
|
||||
|
||||
// uninstall app
|
||||
appInstaller.uninstall(serverManifestURL);
|
||||
|
||||
// wait for dialog
|
||||
var confirmButton = client.helper.waitForElement(
|
||||
system.Selector.appUninstallConfirmButton);
|
||||
confirmButton.sendKeys(Keys.right);
|
||||
assert.isTrue(confirmButton.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}), 'confirm button should be focused.');
|
||||
// uninstall it
|
||||
confirmButton.sendKeys(Keys.enter);
|
||||
system.waitForAppUninstalled(serverManifestURL);
|
||||
});
|
||||
|
||||
test('uninstall and cancel it', { devices: ['tv'] }, function() {
|
||||
// install app
|
||||
appInstaller.install(serverManifestURL);
|
||||
var installButton = client.helper.waitForElement(
|
||||
system.Selector.appInstallInstallButton);
|
||||
installButton.sendKeys(Keys.enter);
|
||||
system.waitForAppInstalled(serverManifestURL);
|
||||
|
||||
appInstaller.uninstall(serverManifestURL);
|
||||
|
||||
var cancelButton = client.helper.waitForElement(
|
||||
system.Selector.appUninstallCancelButton);
|
||||
cancelButton.sendKeys(Keys.enter);
|
||||
|
||||
assert.isTrue(system.isAppInstalled(serverManifestURL),
|
||||
'app should be installed');
|
||||
});
|
||||
|
||||
test('install keyboard app and test setup', { devices: ['tv'] }, function() {
|
||||
// install app
|
||||
appInstaller.install(serverIMEURL);
|
||||
var installButton = client.helper.waitForElement(
|
||||
system.Selector.appInstallInstallButton);
|
||||
installButton.sendKeys(Keys.enter);
|
||||
system.waitForAppInstalled(serverIMEURL);
|
||||
|
||||
var laterButton = client.helper.waitForElement(
|
||||
system.Selector.appInstallSetupLaterButton);
|
||||
laterButton.sendKeys(Keys.enter);
|
||||
client.helper.waitForElementToDisappear(
|
||||
system.Selector.appInstallSetupLaterButton);
|
||||
});
|
||||
});
|
||||
212
gaia/tv_apps/smart-system/test/marionette/app_modal_dialog_test.js
Executable file
212
gaia/tv_apps/smart-system/test/marionette/app_modal_dialog_test.js
Executable file
|
|
@ -0,0 +1,212 @@
|
|||
'use strict';
|
||||
|
||||
var APP_NAME = 'modaldialogapp';
|
||||
var APP_HOST = APP_NAME + '.gaiamobile.org';
|
||||
var APP_URL = 'app://' + APP_HOST;
|
||||
|
||||
var Keys = {
|
||||
'enter': '\ue006',
|
||||
'right': '\ue014',
|
||||
'esc': '\ue00c'
|
||||
};
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var AppModalDialog = require('./lib/app_modal_dialog');
|
||||
|
||||
// Bug 1207453 - Skip the test due to unknown test enviroment issue for now.
|
||||
// We should investigate the issue and re-enable the test later.
|
||||
marionette.skip('Test Modal Dialog Events', function() {
|
||||
|
||||
var opts = {
|
||||
apps: {},
|
||||
hostOptions: {
|
||||
screen: {
|
||||
width: 1920,
|
||||
height: 1080
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
opts.apps[APP_HOST] = __dirname + '/../apps/' + APP_NAME;
|
||||
|
||||
var client = marionette.client({
|
||||
profile: opts,
|
||||
// XXX: Set this to true once Accessibility is implemented in TV
|
||||
desiredCapabilities: { raisesAccessibilityExceptions: false }
|
||||
});
|
||||
var testOptions = { devices: ['tv'] };
|
||||
var actions;
|
||||
var system;
|
||||
var appModalDialog;
|
||||
var options = {
|
||||
// App name should be the same name in modaldialogapp/manifest.webapp,
|
||||
// appName will show on alert/prompt/confirm title and we will verify it
|
||||
// shows un-escaped message on it.
|
||||
appName: '>>> Modal Dialog <<<',
|
||||
// We are going to pass message with special characters to modal dialog
|
||||
// and verify it shows un-escaped message as expected.
|
||||
alert: {
|
||||
message: '<b>Alert message</b>'
|
||||
},
|
||||
prompt: {
|
||||
message: '<u>Prompt message</u>'
|
||||
},
|
||||
confirm: {
|
||||
message: '<i>Confrim message</i>'
|
||||
}
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
actions = client.loader.getActions();
|
||||
system = client.loader.getAppClass('smart-system', 'system', 'tv_apps');
|
||||
appModalDialog = new AppModalDialog(client);
|
||||
});
|
||||
|
||||
function launchModalDialogApp() {
|
||||
// Launch test app
|
||||
client.apps.launch(APP_URL);
|
||||
client.apps.switchToApp(APP_URL);
|
||||
}
|
||||
|
||||
test('alert modal dialog should disappear', testOptions, function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('alert', options.alert.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.alertDialog);
|
||||
|
||||
assert.equal(appModalDialog.alertMessage.scriptWith(function(el) {
|
||||
return el.textContent;
|
||||
}), options.alert.message);
|
||||
|
||||
appModalDialog.sendKeyToElement(appModalDialog.alertOk, Keys.enter);
|
||||
appModalDialog.waitForDialogClosed(appModalDialog.alertDialog);
|
||||
});
|
||||
|
||||
test('alert modal dialog should focus on ok when opened', testOptions,
|
||||
function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('alert', options.alert.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.alertDialog);
|
||||
assert.ok(appModalDialog.alertOk.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}));
|
||||
});
|
||||
|
||||
test('prompt modal dialog should disappear - ok', testOptions,
|
||||
function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('prompt', options.prompt.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.promptDialog);
|
||||
|
||||
assert.equal(appModalDialog.promptMessage.scriptWith(function(el) {
|
||||
return el.textContent;
|
||||
}), options.prompt.message);
|
||||
|
||||
appModalDialog.sendKeyToElement(appModalDialog.promptOk, Keys.enter);
|
||||
appModalDialog.waitForDialogClosed(appModalDialog.promptDialog);
|
||||
});
|
||||
|
||||
test('prompt modal dialog should disappear - cancel', testOptions,
|
||||
function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('prompt', options.prompt.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.promptDialog);
|
||||
|
||||
assert.equal(appModalDialog.promptMessage.scriptWith(function(el) {
|
||||
return el.textContent;
|
||||
}), options.prompt.message);
|
||||
|
||||
appModalDialog.sendKeyToElement(appModalDialog.promptCancel, Keys.enter);
|
||||
appModalDialog.waitForDialogClosed(appModalDialog.promptDialog);
|
||||
});
|
||||
|
||||
test('prompt modal dialog should focus on input when opened', testOptions,
|
||||
function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('prompt', options.prompt.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.promptDialog);
|
||||
|
||||
assert.ok(appModalDialog.promptInput.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}));
|
||||
});
|
||||
|
||||
test('confirm modal dialog should disappear - ok', testOptions,
|
||||
function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('confirm', options.confirm.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.confirmDialog);
|
||||
|
||||
assert.equal(appModalDialog.confirmMessage.scriptWith(function(el) {
|
||||
return el.textContent;
|
||||
}), options.confirm.message);
|
||||
|
||||
appModalDialog.sendKeyToElement(appModalDialog.confirmOk, Keys.enter);
|
||||
appModalDialog.waitForDialogClosed(appModalDialog.confirmDialog);
|
||||
});
|
||||
|
||||
test('confirm modal dialog should disappear - cancel', testOptions,
|
||||
function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('confirm', options.confirm.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.confirmDialog);
|
||||
|
||||
assert.equal(appModalDialog.confirmMessage.scriptWith(function(el) {
|
||||
return el.textContent;
|
||||
}), options.confirm.message);
|
||||
|
||||
appModalDialog.sendKeyToElement(appModalDialog.confirmCancel, Keys.enter);
|
||||
appModalDialog.waitForDialogClosed(appModalDialog.confirmDialog);
|
||||
});
|
||||
|
||||
test('confirm modal dialog should focus on ok when opened', testOptions,
|
||||
function() {
|
||||
launchModalDialogApp();
|
||||
client.executeAsyncScript(function(options) {
|
||||
window.wrappedJSObject.showDialog('confirm', options.confirm.message);
|
||||
marionetteScriptFinished();
|
||||
}, [options]);
|
||||
client.switchToFrame();
|
||||
|
||||
appModalDialog.waitForDialogOpened(appModalDialog.confirmDialog);
|
||||
|
||||
assert.ok(appModalDialog.confirmOk.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
122
gaia/tv_apps/smart-system/test/marionette/browser_context_menu_test.js
Executable file
122
gaia/tv_apps/smart-system/test/marionette/browser_context_menu_test.js
Executable file
|
|
@ -0,0 +1,122 @@
|
|||
'use strict';
|
||||
|
||||
var APP_NAME = 'contextmenuapp';
|
||||
var APP_HOST = APP_NAME + '.gaiamobile.org';
|
||||
var APP_URL = 'app://' + APP_HOST;
|
||||
|
||||
var Keys = {
|
||||
'enter': '\ue006',
|
||||
'right': '\ue014',
|
||||
'esc': '\ue00c'
|
||||
};
|
||||
|
||||
var assert = require('chai').assert;
|
||||
|
||||
// Bug 1207453 - Skip the test due to unknown test enviroment issue for now.
|
||||
// We should investigate the issue and re-enable the test later.
|
||||
marionette.skip('Test Context Menu Events', function() {
|
||||
|
||||
var opts = {
|
||||
apps: {},
|
||||
hostOptions: {
|
||||
screen: {
|
||||
width: 1920,
|
||||
height: 1080
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
opts.apps[APP_HOST] = __dirname + '/../apps/' + APP_NAME;
|
||||
|
||||
var client = marionette.client({
|
||||
profile: opts,
|
||||
// XXX: Set this to true once Accessibility is implemented in TV
|
||||
desiredCapabilities: { raisesAccessibilityExceptions: false }
|
||||
});
|
||||
var actions;
|
||||
var system;
|
||||
var menuSelectors = [
|
||||
'.appWindow.active .modal-dialog-button-group smart-button:nth-child(1)',
|
||||
'.appWindow.active .modal-dialog-button-group smart-button:nth-child(2)'
|
||||
];
|
||||
|
||||
setup(function() {
|
||||
actions = client.loader.getActions();
|
||||
system = client.loader.getAppClass('smart-system', 'system', 'tv_apps');
|
||||
});
|
||||
|
||||
function launchContextMenu() {
|
||||
// Launch test app
|
||||
client.apps.launch(APP_URL);
|
||||
client.apps.switchToApp(APP_URL);
|
||||
|
||||
// Long press on a link
|
||||
var link = client.helper.waitForElement('#link');
|
||||
actions.longPress(link, 1.5).perform();
|
||||
|
||||
}
|
||||
|
||||
test('press enter on first menu', { 'devices': ['tv'] }, function() {
|
||||
launchContextMenu();
|
||||
client.switchToFrame();
|
||||
|
||||
system.waitForEvent('appcontextmenu-shown');
|
||||
|
||||
var container = system.appChromeContextMenuContainer;
|
||||
// find the first context menu
|
||||
var firstMenu = client.helper.waitForElement(menuSelectors[0]);
|
||||
// check focus
|
||||
assert.isTrue(firstMenu.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}), 'first smart button should be focused.');
|
||||
// press enter and close it
|
||||
firstMenu.sendKeys(Keys.enter);
|
||||
|
||||
system.waitForEvent('appcontextmenu-hidden');
|
||||
assert.isFalse(firstMenu.displayed());
|
||||
assert.isFalse(container.displayed());
|
||||
});
|
||||
|
||||
test('press enter on second menu', { 'devices': ['tv'] }, function() {
|
||||
launchContextMenu();
|
||||
client.switchToFrame();
|
||||
|
||||
system.waitForEvent('appcontextmenu-shown');
|
||||
|
||||
var container = system.appChromeContextMenuContainer;
|
||||
|
||||
// wait for second menu
|
||||
var secondMenu = client.helper.waitForElement(menuSelectors[1]);
|
||||
// move focus to second one
|
||||
var menu = system.appChromeContextMenu;
|
||||
menu.sendKeys(Keys.right);
|
||||
|
||||
assert.isTrue(secondMenu.scriptWith(function(el) {
|
||||
return document.activeElement === el;
|
||||
}), 'second smart button should be focused.');
|
||||
// press enter and close it
|
||||
secondMenu.sendKeys(Keys.enter);
|
||||
|
||||
system.waitForEvent('appcontextmenu-hidden');
|
||||
assert.isFalse(menu.displayed());
|
||||
assert.isFalse(container.displayed());
|
||||
});
|
||||
|
||||
test('press esc after menu shown', { 'devices': ['tv'] }, function() {
|
||||
launchContextMenu();
|
||||
client.switchToFrame();
|
||||
|
||||
system.waitForEvent('appcontextmenu-shown');
|
||||
|
||||
var container = system.appChromeContextMenuContainer;
|
||||
|
||||
// move focus to second one
|
||||
var menu = system.appChromeContextMenu;
|
||||
menu.sendKeys(Keys.esc);
|
||||
|
||||
system.waitForEvent('appcontextmenu-hidden');
|
||||
assert.isFalse(menu.displayed());
|
||||
assert.isFalse(container.displayed());
|
||||
});
|
||||
|
||||
});
|
||||
112
gaia/tv_apps/smart-system/test/marionette/lib/app_install.js
Executable file
112
gaia/tv_apps/smart-system/test/marionette/lib/app_install.js
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* A Marionette test helper for app installation flow.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Marionette.Client} client Marionette client to use.
|
||||
*/
|
||||
function AppInstall(client) {
|
||||
this.client = client.scope({ searchTimeout: 200000 });
|
||||
}
|
||||
|
||||
module.exports = AppInstall;
|
||||
|
||||
AppInstall.prototype = {
|
||||
|
||||
_install: function(type, manifestURL) {
|
||||
this.client.executeScript(function install(type, url) {
|
||||
window.wrappedJSObject.navigator.mozApps[type](url);
|
||||
}, [type, manifestURL]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Install an app.
|
||||
* @param {string} manifestURL The manifestURL of the app to be installed.
|
||||
* @param {Object} [options] The options for installation.
|
||||
*/
|
||||
installPackage: function install(manifestURL) {
|
||||
return this._install('installPackage', manifestURL);
|
||||
},
|
||||
|
||||
/**
|
||||
* Install an app.
|
||||
* @param {string} manifestURL The manifestURL of the app to be installed.
|
||||
* @param {Object} [options] The options for installation.
|
||||
*/
|
||||
install: function install(manifestURL) {
|
||||
return this._install('install', manifestURL);
|
||||
},
|
||||
|
||||
/**
|
||||
* Uninstall an app.
|
||||
* @param {string} [manifestURL] The manifestURL of the app.
|
||||
*/
|
||||
uninstall: function(manifestURL) {
|
||||
this.client.switchToFrame();
|
||||
|
||||
this.client.executeAsyncScript(function uninstall(url) {
|
||||
var win = window.wrappedJSObject;
|
||||
var mgmt = win.navigator.mozApps.mgmt;
|
||||
|
||||
mgmt.getAll().onsuccess = function(e) {
|
||||
var app = e.target.result.find(function(app) {
|
||||
return app.manifestURL === url;
|
||||
});
|
||||
|
||||
mgmt.uninstall(app);
|
||||
marionetteScriptFinished();
|
||||
};
|
||||
}, [manifestURL]);
|
||||
},
|
||||
|
||||
/**
|
||||
Checks for downloads without applying them.
|
||||
*/
|
||||
stageUpdate: function(manifestURL) {
|
||||
// do it in chrome so we don't need to switch contexts...
|
||||
var client = this.client.scope({ context: 'chrome' });
|
||||
return client.executeAsyncScript(function(manifestURL) {
|
||||
navigator.mozApps.mgmt.getAll().onsuccess = function(e) {
|
||||
var list = e.target.result;
|
||||
var app = list.find(function(app) {
|
||||
return app.manifestURL === manifestURL;
|
||||
});
|
||||
var req = app.checkForUpdate();
|
||||
req.onsuccess = req.onerror = function() {
|
||||
marionetteScriptFinished();
|
||||
};
|
||||
};
|
||||
}, [manifestURL]);
|
||||
},
|
||||
|
||||
/**
|
||||
Updates an installed app by it's manifest url.
|
||||
|
||||
@param {String} manifestURL for the application.
|
||||
*/
|
||||
update: function(manifestURL) {
|
||||
// do it in chrome so we don't need to switch contexts...
|
||||
var client = this.client.scope({ context: 'chrome' });
|
||||
return client.executeAsyncScript(function(manifestURL) {
|
||||
navigator.mozApps.mgmt.getAll().onsuccess = function(e) {
|
||||
var list = e.target.result;
|
||||
var app = list.find(function(app) {
|
||||
return app.manifestURL === manifestURL;
|
||||
});
|
||||
|
||||
var req = app.checkForUpdate();
|
||||
req.onsuccess = function() {
|
||||
app.download();
|
||||
marionetteScriptFinished();
|
||||
};
|
||||
|
||||
req.onerror = function() {
|
||||
marionetteScriptFinished();
|
||||
};
|
||||
};
|
||||
}, [manifestURL]);
|
||||
}
|
||||
};
|
||||
136
gaia/tv_apps/smart-system/test/marionette/lib/app_modal_dialog.js
Executable file
136
gaia/tv_apps/smart-system/test/marionette/lib/app_modal_dialog.js
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* A Marionette test helper for modal dialog flow.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Marionette.Client} client Marionette client to use.
|
||||
*/
|
||||
function ModalDialog(client) {
|
||||
this.client = client.scope({ searchTimeout: 200000 });
|
||||
this.client.helper = client.helper;
|
||||
}
|
||||
|
||||
module.exports = ModalDialog;
|
||||
|
||||
ModalDialog.Selector = Object.freeze({
|
||||
alert: {
|
||||
dialog: '.appWindow.active .smart-modal-dialog-container' +
|
||||
' .modal-dialog-opened',
|
||||
ok: '.appWindow.active .modal-dialog-opened' +
|
||||
' .modal-dialog-button-group smart-button:nth-child(1)',
|
||||
message: '.appWindow.active .modal-dialog-opened .modal-dialog-message'
|
||||
},
|
||||
prompt: {
|
||||
dialog: '.appWindow.active .smart-modal-dialog-container' +
|
||||
' .modal-dialog-opened',
|
||||
ok: '.appWindow.active .modal-dialog-opened' +
|
||||
' .modal-dialog-button-group smart-button:nth-child(2)',
|
||||
cancel: '.appWindow.active .modal-dialog-opened' +
|
||||
' .modal-dialog-button-group smart-button:nth-child(1)',
|
||||
message: '.appWindow.active .modal-dialog-opened .modal-dialog-message',
|
||||
input: '.appWindow.active .modal-dialog-opened' +
|
||||
' .modal-dialog-input-group input'
|
||||
},
|
||||
confirm: {
|
||||
dialog: '.appWindow.active .smart-modal-dialog-container' +
|
||||
' .modal-dialog-opened',
|
||||
ok: '.appWindow.active .modal-dialog-opened' +
|
||||
' .modal-dialog-button-group smart-button:nth-child(2)',
|
||||
cancel: '.appWindow.active' +
|
||||
' .modal-dialog-button-group smart-button:nth-child(1)',
|
||||
message: '.appWindow.active .modal-dialog-opened .modal-dialog-message'
|
||||
}
|
||||
});
|
||||
|
||||
ModalDialog.prototype = {
|
||||
|
||||
get alertDialog() {
|
||||
return this.client.findElement(ModalDialog.Selector.alert.dialog);
|
||||
},
|
||||
|
||||
get alertOk() {
|
||||
return this.client.findElement(ModalDialog.Selector.alert.ok);
|
||||
},
|
||||
|
||||
get alertMessage() {
|
||||
return this.client.findElement(ModalDialog.Selector.alert.message);
|
||||
},
|
||||
|
||||
get promptDialog() {
|
||||
return this.client.findElement(ModalDialog.Selector.prompt.dialog);
|
||||
},
|
||||
|
||||
get promptOk() {
|
||||
return this.client.findElement(ModalDialog.Selector.prompt.ok);
|
||||
},
|
||||
|
||||
get promptCancel() {
|
||||
return this.client.findElement(ModalDialog.Selector.prompt.cancel);
|
||||
},
|
||||
|
||||
get promptTitle() {
|
||||
return this.client.findElement(ModalDialog.Selector.prompt.title);
|
||||
},
|
||||
|
||||
get promptMessage() {
|
||||
return this.client.findElement(ModalDialog.Selector.prompt.message);
|
||||
},
|
||||
|
||||
get promptInput() {
|
||||
return this.client.findElement(ModalDialog.Selector.prompt.input);
|
||||
},
|
||||
|
||||
get confirmDialog() {
|
||||
return this.client.findElement(ModalDialog.Selector.confirm.dialog);
|
||||
},
|
||||
|
||||
get confirmOk() {
|
||||
return this.client.findElement(ModalDialog.Selector.confirm.ok);
|
||||
},
|
||||
|
||||
get confirmCancel() {
|
||||
return this.client.findElement(ModalDialog.Selector.confirm.cancel);
|
||||
},
|
||||
|
||||
get confirmMessage() {
|
||||
return this.client.findElement(ModalDialog.Selector.confirm.message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Wait for the specified element to show and send key to it
|
||||
* @param {Marionette.Element} element The element to wait for.
|
||||
* @param {String} key The desired key to send to element.
|
||||
*/
|
||||
sendKeyToElement: function(element, key) {
|
||||
this.client.waitFor(function() {
|
||||
return element.displayed();
|
||||
}, function() {
|
||||
element.sendKeys(key);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Wait for the specified dialog to open.
|
||||
* @param {Marionette.Element} element The dialog element to wait for.
|
||||
*/
|
||||
waitForDialogOpened: function(element) {
|
||||
this.client.waitFor(function() {
|
||||
var dialogClass = element.getAttribute('class');
|
||||
return dialogClass.indexOf('visible') != -1;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Wait for the specified dialog to close.
|
||||
* @param {Marionette.Element} element The dialog element to wait for.
|
||||
*/
|
||||
waitForDialogClosed: function(element) {
|
||||
this.client.waitFor(function() {
|
||||
var dialogClass = element.getAttribute('class');
|
||||
return dialogClass.indexOf('visible') == -1;
|
||||
});
|
||||
}
|
||||
};
|
||||
116
gaia/tv_apps/smart-system/test/marionette/lib/system.js
Executable file
116
gaia/tv_apps/smart-system/test/marionette/lib/system.js
Executable file
|
|
@ -0,0 +1,116 @@
|
|||
'use strict';
|
||||
|
||||
function System(client) {
|
||||
this.client = client.scope({
|
||||
searchTimeout: 20000
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = System;
|
||||
|
||||
System.URL = 'app://smart-system.gaiamobile.org/manifest.webapp';
|
||||
|
||||
System.Selector = Object.freeze({
|
||||
appChromeContextMenuContainer: '.appWindow.active .modal-dialog',
|
||||
appChromeContextMenuDialog: '.appWindow.active .contextmenu .modal-dialog',
|
||||
appInstallCancelButton: '.app-install-dialog smart-button:nth-child(1)',
|
||||
appInstallInstallButton: '.app-install-dialog smart-button:nth-child(2)',
|
||||
appCancelInstallConfirmButton:
|
||||
'.app-install-cancel-dialog smart-button:nth-child(1)',
|
||||
appCanelInstallResumeButton:
|
||||
'.app-install-cancel-dialog smart-button:nth-child(2)',
|
||||
appUninstallCancelButton: '.app-uninstall-dialog smart-button:nth-child(1)',
|
||||
appUninstallConfirmButton: '.app-uninstall-dialog smart-button:nth-child(2)',
|
||||
appInstallSetupLaterButton: '.setup-app-dialog smart-button:nth-child(1)',
|
||||
appInstallSetupNowButton: '.setup-app-dialog smart-button:nth-child(2)'
|
||||
});
|
||||
|
||||
System.prototype = {
|
||||
client: null,
|
||||
|
||||
URL: System.URL,
|
||||
|
||||
Selector: System.Selector,
|
||||
|
||||
get appChromeContextMenuContainer() {
|
||||
return this.client.helper.waitForElement(
|
||||
System.Selector.appChromeContextMenuContainer);
|
||||
},
|
||||
|
||||
get appChromeContextMenu() {
|
||||
return this.client.helper.waitForElement(
|
||||
System.Selector.appChromeContextMenuDialog);
|
||||
},
|
||||
|
||||
getAppIframe: function(url) {
|
||||
return this.client.findElement('iframe[src*="' + url + '"]');
|
||||
},
|
||||
|
||||
getHomescreenIframe: function() {
|
||||
return this.client.findElement('#homescreen iframe');
|
||||
},
|
||||
|
||||
waitForLaunch: function(url) {
|
||||
this.client.apps.launch(url);
|
||||
var iframe = this.getAppIframe(url);
|
||||
this.client.waitFor(function() {
|
||||
return iframe.displayed();
|
||||
});
|
||||
|
||||
return iframe;
|
||||
},
|
||||
|
||||
waitForEvent: function(evt) {
|
||||
this.client.switchToFrame();
|
||||
this.client.executeAsyncScript(function(evt) {
|
||||
var win = window.wrappedJSObject;
|
||||
win.addEventListener(evt, function trWait() {
|
||||
win.removeEventListener(evt, trWait);
|
||||
marionetteScriptFinished();
|
||||
});
|
||||
}, [evt]);
|
||||
},
|
||||
|
||||
_waitForAppState: function(manifestURL, installed) {
|
||||
this.client.waitFor(function() {
|
||||
return this.client.executeScript(function(manifestURL, installed) {
|
||||
var apps = window.wrappedJSObject.applications;
|
||||
var hasApp = !!apps.installedApps[manifestURL];
|
||||
return hasApp === installed;
|
||||
}, [manifestURL, installed]);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
waitForAppInstalled: function(manifestURL) {
|
||||
return this._waitForAppState(manifestURL, true);
|
||||
},
|
||||
|
||||
waitForAppUninstalled: function(manifestURL) {
|
||||
return this._waitForAppState(manifestURL, false);
|
||||
},
|
||||
|
||||
isAppInstalled: function(manifestURL) {
|
||||
return this.client.executeScript(function(manifestURL) {
|
||||
return !!window.wrappedJSObject.applications.installedApps[manifestURL];
|
||||
}, [manifestURL]);
|
||||
},
|
||||
|
||||
goHome: function() {
|
||||
this.client.switchToFrame();
|
||||
this.client.executeAsyncScript(function() {
|
||||
var win = window.wrappedJSObject;
|
||||
win.addEventListener('homescreenopened', function trWait() {
|
||||
win.removeEventListener('homescreenopened', trWait);
|
||||
marionetteScriptFinished();
|
||||
});
|
||||
win.dispatchEvent(new CustomEvent('home'));
|
||||
});
|
||||
},
|
||||
|
||||
tapHome: function() {
|
||||
this.client.switchToFrame();
|
||||
this.client.executeScript(function() {
|
||||
window.wrappedJSObject.dispatchEvent(new CustomEvent('home'));
|
||||
});
|
||||
}
|
||||
};
|
||||
18
gaia/tv_apps/smart-system/test/unit/.jshintrc
Executable file
18
gaia/tv_apps/smart-system/test/unit/.jshintrc
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "../../../../.jshintrc",
|
||||
"predef": [
|
||||
"assert",
|
||||
"suite",
|
||||
"test",
|
||||
"setup",
|
||||
"teardown",
|
||||
"suiteSetup",
|
||||
"suiteTeardown",
|
||||
"require",
|
||||
"requireApp",
|
||||
"sinon",
|
||||
"mocha",
|
||||
"loadBodyHTML"
|
||||
]
|
||||
}
|
||||
|
||||
747
gaia/tv_apps/smart-system/test/unit/base_module_test.js
Executable file
747
gaia/tv_apps/smart-system/test/unit/base_module_test.js
Executable file
|
|
@ -0,0 +1,747 @@
|
|||
/* global BaseModule, MocksHelper, MockService, MockLazyLoader, MockPromise,
|
||||
Deferred */
|
||||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mock_service.js');
|
||||
require('/shared/test/unit/mocks/mock_promise.js');
|
||||
require('/shared/test/unit/mocks/mock_lazy_loader.js');
|
||||
requireApp('smart-system/test/unit/deferred.js');
|
||||
|
||||
var mocksForBaseModule = new MocksHelper([
|
||||
'LazyLoader', 'Service'
|
||||
]).init();
|
||||
|
||||
suite('smart-system/BaseModule', function() {
|
||||
mocksForBaseModule.attachTestHelpers();
|
||||
|
||||
setup(function(done) {
|
||||
requireApp('smart-system/js/base_module.js', done);
|
||||
});
|
||||
|
||||
test('lowercase capital', function() {
|
||||
assert.equal('appWindowManager',
|
||||
BaseModule.lowerCapital('AppWindowManager'));
|
||||
});
|
||||
|
||||
test('parse module path', function() {
|
||||
var module = BaseModule.parsePath('path/to/ModuleName');
|
||||
assert.equal(module.path, 'path/to/');
|
||||
assert.equal(module.name, 'ModuleName');
|
||||
});
|
||||
|
||||
test('object name to file name', function() {
|
||||
assert.deepEqual('/js/app_window_manager.js',
|
||||
BaseModule.object2fileName('AppWindowManager'));
|
||||
assert.deepEqual('/js/path/to/module_name.js',
|
||||
BaseModule.object2fileName('path/to/ModuleName'));
|
||||
});
|
||||
|
||||
test('lazy load from an array of submodule strings', function(done) {
|
||||
var stubLoad = this.sinon.stub(MockLazyLoader, 'load');
|
||||
BaseModule.lazyLoad(['AppWindowManager']).then(function() {
|
||||
done();
|
||||
});
|
||||
assert.isTrue(stubLoad.calledWith(['/js/app_window_manager.js']));
|
||||
stubLoad.yield();
|
||||
});
|
||||
|
||||
suite('Launching promise', function() {
|
||||
test('start should resolve right away', function(done) {
|
||||
var LaunchingPromiseTester = function() {};
|
||||
BaseModule.create(LaunchingPromiseTester, {
|
||||
name: 'LaunchingPromiseTester'
|
||||
});
|
||||
var lpt = BaseModule.instantiate('LaunchingPromiseTester');
|
||||
lpt.start().catch((e) => {throw e || 'Should not throw'; })
|
||||
.then(done, done);
|
||||
});
|
||||
|
||||
test('custom start', function(done) {
|
||||
var LaunchingPromiseTester = function() {};
|
||||
BaseModule.create(LaunchingPromiseTester, {
|
||||
name: 'LaunchingPromiseTester',
|
||||
_start: function() {
|
||||
return new Promise(function(resolve) {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
var lpt = BaseModule.instantiate('LaunchingPromiseTester');
|
||||
lpt.start().catch((e) => {throw e || 'Should not throw'; })
|
||||
.then(done, done);
|
||||
});
|
||||
});
|
||||
|
||||
suite('BaseModule.instantiate', function() {
|
||||
test('Get a new instance if the module is available', function() {
|
||||
var InstantiationTester = function() {};
|
||||
BaseModule.create(InstantiationTester, {
|
||||
name: 'InstantiationTester'
|
||||
});
|
||||
|
||||
assert.isDefined(BaseModule.instantiate('InstantiationTester'));
|
||||
assert.equal(BaseModule.instantiate('InstantiationTester').name,
|
||||
'InstantiationTester');
|
||||
});
|
||||
|
||||
test('Get undefined if the module is unavailable', function() {
|
||||
assert.isUndefined(BaseModule.instantiate('NoSuchModule'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('Centralized settins observer', function() {
|
||||
var fakeAppWindowManager, settings;
|
||||
setup(function() {
|
||||
var FakeAppWindowManager = function() {};
|
||||
FakeAppWindowManager.SETTINGS = ['app-suspending.enabled'];
|
||||
BaseModule.create(FakeAppWindowManager, {
|
||||
name: 'FakeAppWindowManager'
|
||||
});
|
||||
settings = {
|
||||
'app-suspending.enabled': true
|
||||
};
|
||||
fakeAppWindowManager = new FakeAppWindowManager();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
fakeAppWindowManager.stop();
|
||||
});
|
||||
|
||||
test('addObserver will be called if SETTINGS is specified', function(done) {
|
||||
var spy = this.sinon.stub(fakeAppWindowManager, 'observe');
|
||||
this.sinon.stub(MockService, 'request',
|
||||
function(service, name, consumer) {
|
||||
if (service === 'SettingsCore:addObserver') {
|
||||
assert.equal(name, 'app-suspending.enabled');
|
||||
assert.deepEqual(consumer, fakeAppWindowManager);
|
||||
consumer.observe(name, settings[name]);
|
||||
assert.isTrue(spy.calledWith('app-suspending.enabled', true));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
fakeAppWindowManager.start();
|
||||
});
|
||||
|
||||
test('get settings', function(done) {
|
||||
this.sinon.stub(MockService, 'request').returns(
|
||||
new Promise(function(resolve) {
|
||||
resolve(new Promise(function(iresolve) {
|
||||
iresolve(true);
|
||||
}));
|
||||
}));
|
||||
|
||||
fakeAppWindowManager.readSetting('app-suspending.enabled')
|
||||
.then(function(value) {
|
||||
assert.equal(value, true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('set settings', function(done) {
|
||||
this.sinon.stub(MockService, 'request',
|
||||
function(service, object) {
|
||||
for (var key in object) {
|
||||
settings[key] = object[key];
|
||||
}
|
||||
assert.equal(settings['app-suspending.enabled'], false);
|
||||
done();
|
||||
});
|
||||
|
||||
fakeAppWindowManager.writeSetting({'app-suspending.enabled': false});
|
||||
});
|
||||
|
||||
test('settings relation function will not be injected if not specified',
|
||||
function() {
|
||||
var fakeAppWindowManager2;
|
||||
var FakeAppWindowManager2 = function() {};
|
||||
BaseModule.create(FakeAppWindowManager2, {
|
||||
name: 'FakeAppWindowManager2'
|
||||
});
|
||||
fakeAppWindowManager2 = new FakeAppWindowManager2();
|
||||
assert.isUndefined(fakeAppWindowManager2.observe);
|
||||
assert.isUndefined(fakeAppWindowManager2._observeSettings);
|
||||
assert.isUndefined(fakeAppWindowManager2._unobserveSettings);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Centralized event handler', function() {
|
||||
var fakeAppWindowManager;
|
||||
setup(function() {
|
||||
var FakeAppWindowManager = function() {};
|
||||
FakeAppWindowManager.EVENTS = ['ftuskip'];
|
||||
BaseModule.create(FakeAppWindowManager, {
|
||||
name: 'FakeAppWindowManager'
|
||||
});
|
||||
fakeAppWindowManager = new FakeAppWindowManager();
|
||||
});
|
||||
teardown(function() {
|
||||
fakeAppWindowManager.stop();
|
||||
});
|
||||
|
||||
test('handleEvent should be called when registering events', function() {
|
||||
var stubHandleEvent =
|
||||
this.sinon.stub(fakeAppWindowManager, 'handleEvent');
|
||||
window.dispatchEvent(new CustomEvent('ftuskip'));
|
||||
assert.isFalse(stubHandleEvent.called);
|
||||
fakeAppWindowManager.start();
|
||||
var ftuskipEvent = new CustomEvent('ftuskip');
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isTrue(stubHandleEvent.calledWith(ftuskipEvent));
|
||||
});
|
||||
|
||||
test('specific handler should be called if it exists', function() {
|
||||
var stubHandleFtuskip =
|
||||
fakeAppWindowManager._handle_ftuskip = this.sinon.spy();
|
||||
window.dispatchEvent(new CustomEvent('ftuskip'));
|
||||
assert.isFalse(stubHandleFtuskip.called);
|
||||
fakeAppWindowManager.start();
|
||||
var ftuskipEvent = new CustomEvent('ftuskip');
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isTrue(stubHandleFtuskip.calledWith(ftuskipEvent));
|
||||
});
|
||||
|
||||
test('pre handler should be called if it exists', function() {
|
||||
var spy = fakeAppWindowManager._handle_ftuskip = this.sinon.spy();
|
||||
var ftuskipEvent = new CustomEvent('ftuskip');
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isFalse(spy.called);
|
||||
fakeAppWindowManager.start();
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isTrue(spy.calledWith(ftuskipEvent));
|
||||
});
|
||||
|
||||
test('pre handler should be called if it exists', function() {
|
||||
var spy = fakeAppWindowManager._pre_handleEvent = this.sinon.spy();
|
||||
var spyFtuskip = fakeAppWindowManager._handle_ftuskip = this.sinon.spy();
|
||||
var ftuskipEvent = new CustomEvent('ftuskip');
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isFalse(spy.called);
|
||||
assert.isFalse(spyFtuskip.called);
|
||||
fakeAppWindowManager.start();
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isTrue(spy.calledWith(ftuskipEvent));
|
||||
assert.isTrue(spyFtuskip.calledWith(ftuskipEvent));
|
||||
});
|
||||
|
||||
test('specific event handler should be not called ' +
|
||||
'if pre handler returns false', function() {
|
||||
fakeAppWindowManager._pre_handleEvent = function() {};
|
||||
var spy = this.sinon.stub(fakeAppWindowManager,
|
||||
'_pre_handleEvent').returns(false);
|
||||
var spyFtuskip = fakeAppWindowManager._handle_ftuskip = this.sinon.spy();
|
||||
var ftuskipEvent = new CustomEvent('ftuskip');
|
||||
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isFalse(spy.called);
|
||||
assert.isFalse(spyFtuskip.called);
|
||||
fakeAppWindowManager.start();
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isTrue(spy.calledWith(ftuskipEvent));
|
||||
assert.isFalse(spyFtuskip.calledWith(ftuskipEvent));
|
||||
});
|
||||
|
||||
test('post handler should be called if it exists', function() {
|
||||
var spy = fakeAppWindowManager._post_handleEvent = this.sinon.spy();
|
||||
var ftuskipEvent = new CustomEvent('ftuskip');
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isFalse(spy.called);
|
||||
fakeAppWindowManager.start();
|
||||
window.dispatchEvent(ftuskipEvent);
|
||||
assert.isTrue(spy.calledWith(ftuskipEvent));
|
||||
});
|
||||
|
||||
test('event relation function will not be injected if not specified',
|
||||
function() {
|
||||
var FakeAppWindowManager2 = function() {};
|
||||
BaseModule.create(FakeAppWindowManager2, {
|
||||
name: 'FakeAppWindowManager2'
|
||||
});
|
||||
var fakeAppWindowManager2 = new FakeAppWindowManager2();
|
||||
assert.isUndefined(fakeAppWindowManager2.handleEvent);
|
||||
assert.isUndefined(fakeAppWindowManager2._pre_handleEvent);
|
||||
assert.isUndefined(fakeAppWindowManager2._post_handleEvent);
|
||||
assert.isUndefined(fakeAppWindowManager2._subscribeEvents);
|
||||
assert.isUndefined(fakeAppWindowManager2._unsubscribeEvents);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Submodule management', function() {
|
||||
var fakeAppWindowManager, fakePromise;
|
||||
setup(function() {
|
||||
BaseModule.__clearDefined();
|
||||
});
|
||||
suite('Already defined submodules with array SUB_MODULES', function() {
|
||||
setup(function() {
|
||||
fakePromise = new MockPromise();
|
||||
this.sinon.stub(BaseModule, 'lazyLoad', function() {
|
||||
return fakePromise;
|
||||
});
|
||||
window.FakeAppWindowManager = function() {};
|
||||
window.FakeAppWindowManager.SUB_MODULES = ['FakeTaskManager'];
|
||||
BaseModule.create(window.FakeAppWindowManager, {
|
||||
name: 'FakeAppWindowManager'
|
||||
});
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
fakeAppWindowManager = new window.FakeAppWindowManager();
|
||||
fakeAppWindowManager.start();
|
||||
});
|
||||
|
||||
test('submodule should be not loaded', function() {
|
||||
fakeAppWindowManager._fakeTaskManager_loaded = this.sinon.spy();
|
||||
assert.isDefined(fakeAppWindowManager.fakeTaskManager);
|
||||
assert.isFalse(fakeAppWindowManager._fakeTaskManager_loaded.called);
|
||||
});
|
||||
});
|
||||
suite('Already defined submodules with object SUB_MODULES', function() {
|
||||
setup(function() {
|
||||
fakePromise = new MockPromise();
|
||||
this.sinon.stub(BaseModule, 'lazyLoad', function() {
|
||||
return fakePromise;
|
||||
});
|
||||
window.FakeAppWindowManager = function() {};
|
||||
window.FakeAppWindowManager.SUB_MODULES = {
|
||||
default: ['FakeTaskManager']
|
||||
};
|
||||
BaseModule.create(window.FakeAppWindowManager, {
|
||||
name: 'FakeAppWindowManager'
|
||||
});
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
fakeAppWindowManager = new window.FakeAppWindowManager();
|
||||
fakeAppWindowManager.start();
|
||||
});
|
||||
|
||||
test('submodule should be not loaded', function() {
|
||||
fakeAppWindowManager._fakeTaskManager_loaded = this.sinon.spy();
|
||||
assert.isDefined(fakeAppWindowManager.fakeTaskManager);
|
||||
assert.isFalse(fakeAppWindowManager._fakeTaskManager_loaded.called);
|
||||
});
|
||||
});
|
||||
suite('Not defined submodules with array SUB_MODULES', function() {
|
||||
setup(function() {
|
||||
fakePromise = new MockPromise();
|
||||
this.sinon.stub(BaseModule, 'lazyLoad', function() {
|
||||
return fakePromise;
|
||||
});
|
||||
window.FakeAppWindowManager = function() {};
|
||||
window.FakeAppWindowManager.SUB_MODULES = [
|
||||
'FakeTaskManager',
|
||||
'path/to/FakeSubModuleInDir'
|
||||
];
|
||||
BaseModule.create(window.FakeAppWindowManager, {
|
||||
name: 'FakeAppWindowManager'
|
||||
});
|
||||
window.FakeTaskManager = null;
|
||||
window.FakeSubModuleInDir = null;
|
||||
fakeAppWindowManager = new window.FakeAppWindowManager();
|
||||
fakeAppWindowManager.start();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
fakeAppWindowManager.stop();
|
||||
window.FakeTaskManager = null;
|
||||
window.FakeAppWindowManager = null;
|
||||
window.FakeSubModuleInDir = null;
|
||||
});
|
||||
|
||||
test('submodule should be loaded', function() {
|
||||
var spy = fakeAppWindowManager._fakeTaskManager_loaded =
|
||||
this.sinon.spy();
|
||||
var spy2 = fakeAppWindowManager._fakeSubModuleInDir_loaded =
|
||||
this.sinon.spy();
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
window.FakeSubModuleInDir = function() {};
|
||||
BaseModule.create(window.FakeSubModuleInDir, {
|
||||
name: 'FakeSubModuleInDir'
|
||||
});
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isDefined(fakeAppWindowManager.fakeTaskManager);
|
||||
assert.isTrue(spy.called);
|
||||
assert.isDefined(fakeAppWindowManager.fakeSubModuleInDir);
|
||||
assert.isTrue(spy2.called);
|
||||
});
|
||||
|
||||
test('submodule loaded handler should be called if it exists',
|
||||
function() {
|
||||
var spy = fakeAppWindowManager._fakeTaskManager_loaded =
|
||||
this.sinon.spy();
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isDefined(fakeAppWindowManager.fakeTaskManager);
|
||||
assert.isTrue(spy.called);
|
||||
});
|
||||
|
||||
test('submodule should be started once parent is started', function() {
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
var spyStart = this.sinon.stub(window.FakeTaskManager.prototype,
|
||||
'start');
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isTrue(spyStart.called);
|
||||
});
|
||||
|
||||
test('submodule should be stopped once parent is stopped', function() {
|
||||
window.FakeTaskManager = function() {};
|
||||
window.FakeSubModuleInDir = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
BaseModule.create(window.FakeSubModuleInDir, {
|
||||
name: 'FakeSubModuleInDir'
|
||||
});
|
||||
fakePromise.mFulfillToValue();
|
||||
var spyStop =
|
||||
this.sinon.stub(fakeAppWindowManager.fakeTaskManager, 'stop');
|
||||
var spyStop2 =
|
||||
this.sinon.stub(fakeAppWindowManager.fakeSubModuleInDir, 'stop');
|
||||
|
||||
fakeAppWindowManager.stop();
|
||||
assert.isTrue(spyStop.called);
|
||||
assert.isTrue(spyStop2.called);
|
||||
});
|
||||
|
||||
test('submodule should not be started if the parent is already stopped',
|
||||
function() {
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
var spyStart =
|
||||
this.sinon.stub(window.FakeTaskManager.prototype, 'start');
|
||||
fakeAppWindowManager.stop();
|
||||
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isFalse(spyStart.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Not defined submodules with object SUB_MODULES', function() {
|
||||
setup(function() {
|
||||
fakePromise = new MockPromise();
|
||||
this.sinon.stub(BaseModule, 'lazyLoad', function() {
|
||||
return fakePromise;
|
||||
});
|
||||
window.FakeAppWindowManager = function() {};
|
||||
window.FakeAppWindowManager.SUB_MODULES = {
|
||||
default: ['FakeTaskManager'],
|
||||
_GAIA_DEVICE_TYPE_: ['path/to/FakeSubModuleInDir']
|
||||
};
|
||||
BaseModule.create(window.FakeAppWindowManager, {
|
||||
name: 'FakeAppWindowManager'
|
||||
});
|
||||
window.FakeTaskManager = null;
|
||||
window.FakeSubModuleInDir = null;
|
||||
fakeAppWindowManager = new window.FakeAppWindowManager();
|
||||
fakeAppWindowManager.start();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
fakeAppWindowManager.stop();
|
||||
window.FakeTaskManager = null;
|
||||
window.FakeAppWindowManager = null;
|
||||
window.FakeSubModuleInDir = null;
|
||||
});
|
||||
|
||||
test('submodule should be loaded', function() {
|
||||
var spy = fakeAppWindowManager._fakeTaskManager_loaded =
|
||||
this.sinon.spy();
|
||||
var spy2 = fakeAppWindowManager._fakeSubModuleInDir_loaded =
|
||||
this.sinon.spy();
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
window.FakeSubModuleInDir = function() {};
|
||||
BaseModule.create(window.FakeSubModuleInDir, {
|
||||
name: 'FakeSubModuleInDir'
|
||||
});
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isDefined(fakeAppWindowManager.fakeTaskManager);
|
||||
assert.isTrue(spy.called);
|
||||
assert.isDefined(fakeAppWindowManager.fakeSubModuleInDir);
|
||||
assert.isTrue(spy2.called);
|
||||
});
|
||||
|
||||
test('submodule loaded handler should be called if it exists',
|
||||
function() {
|
||||
var spy = fakeAppWindowManager._fakeTaskManager_loaded =
|
||||
this.sinon.spy();
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isDefined(fakeAppWindowManager.fakeTaskManager);
|
||||
assert.isTrue(spy.called);
|
||||
});
|
||||
|
||||
test('submodule should be started once parent is started', function() {
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
var spyStart = this.sinon.stub(window.FakeTaskManager.prototype,
|
||||
'start');
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isTrue(spyStart.called);
|
||||
});
|
||||
|
||||
test('submodule should be stopped once parent is stopped', function() {
|
||||
window.FakeTaskManager = function() {};
|
||||
window.FakeSubModuleInDir = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
BaseModule.create(window.FakeSubModuleInDir, {
|
||||
name: 'FakeSubModuleInDir'
|
||||
});
|
||||
fakePromise.mFulfillToValue();
|
||||
var spyStop =
|
||||
this.sinon.stub(fakeAppWindowManager.fakeTaskManager, 'stop');
|
||||
var spyStop2 =
|
||||
this.sinon.stub(fakeAppWindowManager.fakeSubModuleInDir, 'stop');
|
||||
|
||||
fakeAppWindowManager.stop();
|
||||
assert.isTrue(spyStop.called);
|
||||
assert.isTrue(spyStop2.called);
|
||||
});
|
||||
|
||||
test('submodule should not be started if the parent is already stopped',
|
||||
function() {
|
||||
window.FakeTaskManager = function() {};
|
||||
BaseModule.create(window.FakeTaskManager, {
|
||||
name: 'FakeTaskManager'
|
||||
});
|
||||
var spyStart =
|
||||
this.sinon.stub(window.FakeTaskManager.prototype, 'start');
|
||||
fakeAppWindowManager.stop();
|
||||
|
||||
fakePromise.mFulfillToValue();
|
||||
assert.isFalse(spyStart.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Service registration', function() {
|
||||
var fakeAppWindowManager;
|
||||
setup(function() {
|
||||
var FakeAppWindowManager = function() {};
|
||||
FakeAppWindowManager.SERVICES = ['isBusyLoading'];
|
||||
BaseModule.create(FakeAppWindowManager, {
|
||||
name: 'FakeAppWindowManager',
|
||||
isBusyLoading: function() {}
|
||||
});
|
||||
fakeAppWindowManager = new FakeAppWindowManager();
|
||||
fakeAppWindowManager.start();
|
||||
});
|
||||
teardown(function() {
|
||||
fakeAppWindowManager.stop();
|
||||
});
|
||||
|
||||
test('register/unregister functions should be injected', function() {
|
||||
assert.isDefined(fakeAppWindowManager._registerServices);
|
||||
assert.isDefined(fakeAppWindowManager._unregisterServices);
|
||||
});
|
||||
|
||||
test('Should register service to System when starting', function() {
|
||||
fakeAppWindowManager.stop();
|
||||
var stubRegister = this.sinon.stub(MockService, 'register');
|
||||
fakeAppWindowManager.start();
|
||||
assert.isTrue(stubRegister.calledWith('isBusyLoading',
|
||||
fakeAppWindowManager));
|
||||
});
|
||||
|
||||
test('Should unregister service to System when stopping', function() {
|
||||
var stubRegister = this.sinon.stub(MockService, 'unregister');
|
||||
fakeAppWindowManager.stop();
|
||||
assert.isTrue(stubRegister.calledWith('isBusyLoading',
|
||||
fakeAppWindowManager));
|
||||
});
|
||||
|
||||
test('Should not inject service registration functions', function() {
|
||||
var FakeAppWindowManager2 = function() {};
|
||||
BaseModule.create(FakeAppWindowManager2, {
|
||||
name: 'FakeAppWindowManager2',
|
||||
isBusyLoading: function() {}
|
||||
});
|
||||
var fakeAppWindowManager2 = new FakeAppWindowManager2();
|
||||
assert.isUndefined(fakeAppWindowManager2._registerServices);
|
||||
assert.isUndefined(fakeAppWindowManager2._unregisterServices);
|
||||
});
|
||||
});
|
||||
|
||||
suite('State registration', function() {
|
||||
var fakeFtuLauncher;
|
||||
setup(function() {
|
||||
var FakeFtuLauncher = function() {};
|
||||
FakeFtuLauncher.STATES = ['isUpgrading'];
|
||||
BaseModule.create(FakeFtuLauncher, {
|
||||
_upgrading: false,
|
||||
name: 'FakeFtuLauncher',
|
||||
isUpgrading: function() {
|
||||
return this._upgrading;
|
||||
}
|
||||
});
|
||||
fakeFtuLauncher = new FakeFtuLauncher();
|
||||
fakeFtuLauncher.start();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
fakeFtuLauncher.stop();
|
||||
});
|
||||
|
||||
test('Should register service to System when starting', function() {
|
||||
fakeFtuLauncher.stop();
|
||||
var stubRegister = this.sinon.stub(MockService, 'registerState');
|
||||
fakeFtuLauncher.start();
|
||||
assert.isTrue(stubRegister.calledWith('isUpgrading',
|
||||
fakeFtuLauncher));
|
||||
});
|
||||
|
||||
test('Should unregister service to System when stopping', function() {
|
||||
var stubRegister = this.sinon.stub(MockService, 'unregisterState');
|
||||
fakeFtuLauncher.stop();
|
||||
assert.isTrue(stubRegister.calledWith('isUpgrading',
|
||||
fakeFtuLauncher));
|
||||
});
|
||||
|
||||
test('Should not inject service registration functions', function() {
|
||||
var FakeFtuLauncher2 = function() {};
|
||||
BaseModule.create(FakeFtuLauncher2, {
|
||||
name: 'FakeFtuLauncher2',
|
||||
isUpgrading: function() {}
|
||||
});
|
||||
var fakeFtuLauncher2 = new FakeFtuLauncher2();
|
||||
this.sinon.stub(MockService, 'registerState');
|
||||
this.sinon.stub(MockService, 'unregisterState');
|
||||
fakeFtuLauncher2.start();
|
||||
assert.isFalse(MockService.registerState.called);
|
||||
fakeFtuLauncher2.stop();
|
||||
assert.isFalse(MockService.unregisterState.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Start chain', function() {
|
||||
var chainTester;
|
||||
var chainTester_startDeferred, cModule_startDeferred;
|
||||
setup(function() {
|
||||
chainTester_startDeferred = new Deferred();
|
||||
cModule_startDeferred = new Deferred();
|
||||
var ChainTester = function() {};
|
||||
var CModule = function() {};
|
||||
BaseModule.create(CModule, {
|
||||
name: 'CModule',
|
||||
DEBUG: true,
|
||||
_start: sinon.spy(function() {
|
||||
return cModule_startDeferred.promise;
|
||||
})
|
||||
});
|
||||
ChainTester.SUB_MODULES = ['CModule'];
|
||||
BaseModule.create(ChainTester, {
|
||||
name: 'ChainTester',
|
||||
DEBUG: true,
|
||||
_start: sinon.spy(function() {
|
||||
return chainTester_startDeferred.promise;
|
||||
})
|
||||
});
|
||||
chainTester = new ChainTester();
|
||||
});
|
||||
test('Should wait until child start', function(done) {
|
||||
var p = chainTester.start();
|
||||
assert.isTrue(chainTester._start.calledOnce);
|
||||
assert.isTrue(chainTester.cModule._start.calledOnce);
|
||||
p.then(done, done);
|
||||
chainTester_startDeferred.resolve();
|
||||
cModule_startDeferred.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
suite('Import', function() {
|
||||
var importTester;
|
||||
setup(function() {
|
||||
var ImportTester = function() {};
|
||||
ImportTester.IMPORTS = ['BModule', 'CModule'];
|
||||
BaseModule.create(ImportTester, {
|
||||
name: 'ImportTester',
|
||||
_start: function() {}
|
||||
});
|
||||
importTester = new ImportTester();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
importTester.stop();
|
||||
});
|
||||
|
||||
test('Module start will be executed until import loaded', function() {
|
||||
var p = new MockPromise();
|
||||
this.sinon.stub(MockLazyLoader, 'load', function() {
|
||||
return p;
|
||||
});
|
||||
var stubCustomStart = this.sinon.stub(importTester, '_start');
|
||||
importTester.start();
|
||||
assert.isFalse(stubCustomStart.called);
|
||||
p.mFulfillToValue();
|
||||
assert.isTrue(stubCustomStart.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Module life cycle control', function() {
|
||||
var lifeCycleTester;
|
||||
setup(function() {
|
||||
var LifeCycleTester = function() {};
|
||||
BaseModule.create(LifeCycleTester, {
|
||||
name: 'LifeCycleTester',
|
||||
_start: function() {},
|
||||
_stop: function() {}
|
||||
});
|
||||
|
||||
lifeCycleTester = new LifeCycleTester();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
lifeCycleTester.stop();
|
||||
});
|
||||
|
||||
test('custom start should be triggered', function() {
|
||||
var spy = this.sinon.stub(lifeCycleTester, '_start');
|
||||
lifeCycleTester.start();
|
||||
assert.isTrue(spy.calledOnce);
|
||||
});
|
||||
|
||||
test('custom start will not execute if already started', function() {
|
||||
lifeCycleTester.start();
|
||||
var spy = this.sinon.stub(lifeCycleTester, '_start');
|
||||
lifeCycleTester.start();
|
||||
assert.isFalse(spy.called);
|
||||
});
|
||||
|
||||
test('custom stop should be triggered', function() {
|
||||
var spy = this.sinon.stub(lifeCycleTester, '_stop');
|
||||
lifeCycleTester.start();
|
||||
lifeCycleTester.stop();
|
||||
assert.isTrue(spy.calledOnce);
|
||||
});
|
||||
|
||||
test('custom stop will not execute if already stopped', function() {
|
||||
lifeCycleTester.start();
|
||||
lifeCycleTester.stop();
|
||||
var spy = this.sinon.stub(lifeCycleTester, '_stop');
|
||||
lifeCycleTester.stop();
|
||||
assert.isFalse(spy.called);
|
||||
});
|
||||
});
|
||||
});
|
||||
12
gaia/tv_apps/smart-system/test/unit/deferred.js
Executable file
12
gaia/tv_apps/smart-system/test/unit/deferred.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
var Deferred = function() {
|
||||
this.promise = new Promise(function(resolve, reject) {
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
}.bind(this));
|
||||
return this;
|
||||
};
|
||||
exports.Deferred = Deferred;
|
||||
}(window));
|
||||
371
gaia/tv_apps/smart-system/test/unit/fx_accounts_client_test.js
Executable file
371
gaia/tv_apps/smart-system/test/unit/fx_accounts_client_test.js
Executable file
|
|
@ -0,0 +1,371 @@
|
|||
/* global FxAccountsClient */
|
||||
'use strict';
|
||||
|
||||
requireApp('smart-system/js/fx_accounts_client.js');
|
||||
|
||||
var MockEventListener = {};
|
||||
var MockDispatchedEvents = [];
|
||||
|
||||
function MockAddEventListener(event, listener) {
|
||||
MockEventListener[event] = listener;
|
||||
}
|
||||
|
||||
function MockRemoveEventListener(event, listener) {
|
||||
delete MockEventListener[event];
|
||||
}
|
||||
|
||||
function MockDispatchEvent(event) {
|
||||
MockDispatchedEvents.push(event);
|
||||
}
|
||||
|
||||
|
||||
suite('system/FxAccountsClient >', function() {
|
||||
var result = null;
|
||||
var error = null;
|
||||
|
||||
var expectedData = 'data';
|
||||
var expectedError = 'error';
|
||||
|
||||
var successCbCalled = false;
|
||||
var errorCbCalled = false;
|
||||
|
||||
var stubAddEventListener;
|
||||
var stubRemoveEventListener;
|
||||
var stubDispatchEvent;
|
||||
|
||||
function successCb(data) {
|
||||
successCbCalled = true;
|
||||
result = data;
|
||||
}
|
||||
|
||||
function errorCb(errorMsg) {
|
||||
errorCbCalled = true;
|
||||
error = errorMsg;
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
stubAddEventListener = this.sinon.stub(window, 'addEventListener',
|
||||
MockAddEventListener);
|
||||
stubRemoveEventListener = this.sinon.stub(window, 'removeEventListener',
|
||||
MockRemoveEventListener);
|
||||
stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent',
|
||||
MockDispatchEvent);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
stubAddEventListener.restore();
|
||||
stubRemoveEventListener.restore();
|
||||
stubDispatchEvent.restore();
|
||||
});
|
||||
|
||||
suite('Init', function() {
|
||||
test('Integrity', function() {
|
||||
assert.isNotNull(FxAccountsClient);
|
||||
assert.equal(Object.keys(FxAccountsClient).length, 9);
|
||||
});
|
||||
|
||||
test('No event listeners', function() {
|
||||
assert.isUndefined(MockEventListener.mozFxAccountsChromeEvent);
|
||||
});
|
||||
});
|
||||
|
||||
// API calls
|
||||
|
||||
suite('getAccount', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.getAccount(successCb, errorCb);
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 1);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'getAccount'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAccount reply success', function() {
|
||||
setup(function() {
|
||||
MockEventListener.mozFxAccountsChromeEvent({
|
||||
detail: {
|
||||
id: MockDispatchedEvents[0].detail.id,
|
||||
data: expectedData
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
result = null;
|
||||
error = null;
|
||||
successCbCalled = false;
|
||||
errorCbCalled = false;
|
||||
});
|
||||
|
||||
test('On chrome event', function() {
|
||||
assert.isTrue(successCbCalled);
|
||||
assert.isFalse(errorCbCalled);
|
||||
assert.equal(result, expectedData);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAccount', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.getAccount(successCb, errorCb);
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 1);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'getAccount'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAccount reply error', function() {
|
||||
setup(function() {
|
||||
MockEventListener.mozFxAccountsChromeEvent({
|
||||
detail: {
|
||||
id: MockDispatchedEvents[0].detail.id,
|
||||
error: expectedError
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
result = null;
|
||||
error = null;
|
||||
successCbCalled = false;
|
||||
errorCbCalled = false;
|
||||
});
|
||||
|
||||
test('On chrome event', function() {
|
||||
assert.isFalse(successCbCalled);
|
||||
assert.isTrue(errorCbCalled);
|
||||
assert.equal(error, expectedError);
|
||||
});
|
||||
});
|
||||
|
||||
suite('logout', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.logout(successCb, errorCb);
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 1);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'logout'
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
});
|
||||
});
|
||||
|
||||
suite('queryAccount/verificationStatus', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.queryAccount('email', successCb, errorCb);
|
||||
FxAccountsClient.verificationStatus('email', successCb, errorCb);
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 2);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[1].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.ok(MockDispatchedEvents[1].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'queryAccount',
|
||||
email: 'email'
|
||||
});
|
||||
assert.deepEqual(MockDispatchedEvents[1].detail.data, {
|
||||
method: 'verificationStatus',
|
||||
email: 'email'
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
});
|
||||
});
|
||||
|
||||
suite('signIn/signUp', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.signIn('email', 'pass', successCb, errorCb);
|
||||
FxAccountsClient.signUp('email', 'pass', successCb, errorCb);
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 2);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[1].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.ok(MockDispatchedEvents[1].detail.data);
|
||||
|
||||
var signInData = MockDispatchedEvents[0].detail.data;
|
||||
assert.equal(signInData.method, 'signIn');
|
||||
assert.equal(signInData.email, 'email');
|
||||
assert.equal(signInData.password, 'pass');
|
||||
assert.ok(signInData.fetchKeys !== undefined);
|
||||
|
||||
var signUpData = MockDispatchedEvents[1].detail.data;
|
||||
assert.equal(signUpData.method, 'signUp');
|
||||
assert.equal(signUpData.email, 'email');
|
||||
assert.equal(signUpData.password, 'pass');
|
||||
assert.ok(signUpData.fetchKeys !== undefined);
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
});
|
||||
});
|
||||
|
||||
suite('resendVerificationEmail', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.resendVerificationEmail('email', successCb, errorCb);
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 1);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'resendVerificationEmail',
|
||||
email: 'email'
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
});
|
||||
});
|
||||
|
||||
suite('getKeys', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.getKeys(successCb, errorCb);
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 1);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'getKeys'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getKeys response', function() {
|
||||
setup(function() {
|
||||
MockEventListener.mozFxAccountsChromeEvent({
|
||||
detail: {
|
||||
id: MockDispatchedEvents[0].detail.id,
|
||||
data: expectedData
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
result = null;
|
||||
error = null;
|
||||
successCbCalled = false;
|
||||
errorCbCalled = false;
|
||||
});
|
||||
|
||||
test('On chrome event', function() {
|
||||
assert.isTrue(successCbCalled);
|
||||
assert.isFalse(errorCbCalled);
|
||||
assert.equal(result, expectedData);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAssertion', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.getAssertion({
|
||||
silent: true,
|
||||
audience: 'audience'
|
||||
}, successCb, errorCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 1);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'getAssertion',
|
||||
silent: true,
|
||||
audience: 'audience'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAssertion - no options', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.getAssertion(null, successCb, errorCb);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
});
|
||||
|
||||
test('Event dispatched to chrome side', function() {
|
||||
assert.equal(MockDispatchedEvents.length, 1);
|
||||
assert.ok(MockEventListener.mozFxAccountsChromeEvent);
|
||||
assert.ok(MockDispatchedEvents[0].detail.id);
|
||||
assert.ok(MockDispatchedEvents[0].detail.data);
|
||||
assert.deepEqual(MockDispatchedEvents[0].detail.data, {
|
||||
method: 'getAssertion',
|
||||
silent: null,
|
||||
audience: null
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('getAssertion response', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient.getAssertion(null, successCb, errorCb);
|
||||
MockEventListener.mozFxAccountsChromeEvent({
|
||||
detail: {
|
||||
id: MockDispatchedEvents[0].detail.id,
|
||||
data: expectedData
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
MockDispatchedEvents = [];
|
||||
result = null;
|
||||
error = null;
|
||||
successCbCalled = false;
|
||||
errorCbCalled = false;
|
||||
});
|
||||
|
||||
test('On chrome event', function() {
|
||||
assert.isTrue(successCbCalled);
|
||||
assert.isFalse(errorCbCalled);
|
||||
assert.equal(result, expectedData);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
445
gaia/tv_apps/smart-system/test/unit/fx_accounts_manager_test.js
Executable file
445
gaia/tv_apps/smart-system/test/unit/fx_accounts_manager_test.js
Executable file
|
|
@ -0,0 +1,445 @@
|
|||
/* global FxAccountsClient, FxAccountsManager, FxAccountsUI,
|
||||
MocksHelper, MockIACPort */
|
||||
'use strict';
|
||||
|
||||
requireApp('system/js/fx_accounts_manager.js');
|
||||
requireApp('system/test/unit/mock_fxa_client.js');
|
||||
requireApp('system/test/unit/mock_fxa_ui.js');
|
||||
requireApp('system/test/unit/mock_iac_handler.js');
|
||||
|
||||
require('/shared/test/unit/mocks/mock_lazy_loader.js');
|
||||
|
||||
var MockEventListener = {};
|
||||
function MockAddEventListener(event, listener) {
|
||||
MockEventListener[event] = listener;
|
||||
}
|
||||
|
||||
var mocksHelperFxAManager = new MocksHelper([
|
||||
'FxAccountsClient',
|
||||
'FxAccountsUI',
|
||||
'IACHandler',
|
||||
'LazyLoader'
|
||||
]).init();
|
||||
|
||||
suite('system/FxAccountManager >', function() {
|
||||
var stubAddEventListener;
|
||||
|
||||
mocksHelperFxAManager.attachTestHelpers();
|
||||
|
||||
setup(function() {
|
||||
stubAddEventListener = this.sinon.stub(window, 'addEventListener',
|
||||
MockAddEventListener);
|
||||
FxAccountsManager.start();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
stubAddEventListener.restore();
|
||||
});
|
||||
|
||||
suite('Init', function() {
|
||||
test('Integrity', function() {
|
||||
assert.isNotNull(FxAccountsManager);
|
||||
assert.equal(Object.keys(FxAccountsManager).length, 5);
|
||||
});
|
||||
|
||||
test('Test event listeners', function() {
|
||||
assert.ok(MockEventListener['iac-fxa-mgmt']);
|
||||
assert.ok(MockEventListener['iac-fxa-mgmt'] instanceof Function);
|
||||
assert.ok(MockEventListener.mozFxAccountsUnsolChromeEvent);
|
||||
assert.ok(MockEventListener.mozFxAccountsUnsolChromeEvent instanceof
|
||||
Object);
|
||||
});
|
||||
});
|
||||
|
||||
suite('On getAccount port message, successCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient._successMsg = 'success';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'getAccount'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsClient._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsClient.getAccount called', function() {
|
||||
assert.equal(FxAccountsClient._call, 'getAccount');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'getAccount',
|
||||
'data': 'success'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On getAccount port message, errorCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient._errorMsg = 'error';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'getAccount'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsClient._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsClient.getAccount called', function() {
|
||||
assert.equal(FxAccountsClient._call, 'getAccount');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'getAccount',
|
||||
'error': 'error'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On logout port message, successCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient._successMsg = 'success';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'logout'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsClient._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsClient.logout called', function() {
|
||||
assert.equal(FxAccountsClient._call, 'logout');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'logout',
|
||||
'data': 'success'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On logout port message, errorCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient._errorMsg = 'error';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'logout'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsClient._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsClient.logout called', function() {
|
||||
assert.equal(FxAccountsClient._call, 'logout');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'logout',
|
||||
'error': 'error'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On openFlow port message, successCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsUI._successMsg = 'success';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'openFlow'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsUI._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsUI.login called', function() {
|
||||
assert.equal(FxAccountsUI._call, 'login');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'openFlow',
|
||||
'data': 'success'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On openFlow port message, errorCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsUI._errorMsg = 'error';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'openFlow'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsUI._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsUI.login called', function() {
|
||||
assert.equal(FxAccountsUI._call, 'login');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'openFlow',
|
||||
'error': 'error'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On openFlow mozFxAccountsRPChromeEvent', function() {
|
||||
var id = 123;
|
||||
var dispatchEventStub;
|
||||
setup(function() {
|
||||
dispatchEventStub = this.sinon.stub(window, 'dispatchEvent');
|
||||
|
||||
FxAccountsUI._successMsg = 'success';
|
||||
FxAccountsManager.handleEvent({
|
||||
'detail': {
|
||||
'id': id,
|
||||
'eventName': 'openFlow'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
dispatchEventStub.restore();
|
||||
FxAccountsUI._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsUI.login called', function() {
|
||||
assert.equal(FxAccountsUI._call, 'login');
|
||||
});
|
||||
|
||||
test('on FxAccountsUI reply sendContentEvent', function() {
|
||||
sinon.assert.calledOnce(dispatchEventStub);
|
||||
});
|
||||
});
|
||||
|
||||
suite('On refreshAuthentication port message, successCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsUI._successMsg = 'success';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'refreshAuthentication',
|
||||
'email': 'dummy@domain.org'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsUI._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsUI.refreshAuthentication called', function() {
|
||||
assert.equal(FxAccountsUI._call, 'refreshAuthentication');
|
||||
assert.equal(FxAccountsUI._email, 'dummy@domain.org');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'refreshAuthentication',
|
||||
'data': 'success'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On refreshAuthentication port message, errorCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsUI._errorMsg = 'error';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'refreshAuthentication',
|
||||
'email': 'dummy@domain.org'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsUI._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsUI.refreshAuthentication called', function() {
|
||||
assert.equal(FxAccountsUI._call, 'refreshAuthentication');
|
||||
assert.equal(FxAccountsUI._email, 'dummy@domain.org');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'refreshAuthentication',
|
||||
'error': 'error'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On refreshAuthentication mozFxAccountsRPChromeEvent', function() {
|
||||
var id = 123;
|
||||
var dispatchEventStub;
|
||||
setup(function() {
|
||||
dispatchEventStub = this.sinon.stub(window, 'dispatchEvent');
|
||||
|
||||
FxAccountsUI._successMsg = 'success';
|
||||
FxAccountsManager.handleEvent({
|
||||
'detail': {
|
||||
'id': id,
|
||||
'eventName': 'refreshAuthentication',
|
||||
'data': {
|
||||
'email': 'dummy@domain.org'
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
dispatchEventStub.restore();
|
||||
FxAccountsUI._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsUI.refreshAuthentication called', function() {
|
||||
assert.equal(FxAccountsUI._call, 'refreshAuthentication');
|
||||
assert.equal(FxAccountsUI._email, 'dummy@domain.org');
|
||||
});
|
||||
|
||||
test('on FxAccountsUI reply sendContentEvent', function() {
|
||||
sinon.assert.calledOnce(dispatchEventStub);
|
||||
});
|
||||
});
|
||||
|
||||
suite('On resendVerificationEmail port message, successCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient._successMsg = 'success';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'resendVerificationEmail',
|
||||
'email': 'dummy@domain.org'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsClient._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsClient.resendVerificationEmail called', function() {
|
||||
assert.equal(FxAccountsClient._call, 'resendVerificationEmail');
|
||||
assert.equal(FxAccountsClient._email, 'dummy@domain.org');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'resendVerificationEmail',
|
||||
'data': 'success'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('On resendVerificationEmail port message, errorCb', function() {
|
||||
setup(function() {
|
||||
FxAccountsClient._errorMsg = 'error';
|
||||
FxAccountsManager.onPortMessage({
|
||||
'detail': {
|
||||
'name': 'resendVerificationEmail',
|
||||
'email': 'dummy@domain.org'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsClient._reset();
|
||||
});
|
||||
|
||||
test('FxAccountsClient.resendVerificationEmail called', function() {
|
||||
assert.equal(FxAccountsClient._call, 'resendVerificationEmail');
|
||||
assert.equal(FxAccountsClient._email, 'dummy@domain.org');
|
||||
});
|
||||
|
||||
test('Got fxa-mgmt port', function() {
|
||||
assert.equal(MockIACPort._name, 'fxa-mgmt');
|
||||
});
|
||||
|
||||
test('Sent success message through port', function() {
|
||||
assert.equal(MockIACPort._messages.length, 1);
|
||||
assert.ok(MockIACPort._messages[0] instanceof Object);
|
||||
assert.deepEqual(MockIACPort._messages[0], {
|
||||
'methodName': 'resendVerificationEmail',
|
||||
'error': 'error'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
227
gaia/tv_apps/smart-system/test/unit/fxa_dialog_test.js
Executable file
227
gaia/tv_apps/smart-system/test/unit/fxa_dialog_test.js
Executable file
|
|
@ -0,0 +1,227 @@
|
|||
'use strict';
|
||||
/* global MocksHelper, FxAccountsDialog, SystemDialog, LayoutManager,
|
||||
focusManager */
|
||||
/* jshint nonew: false */
|
||||
|
||||
require('/test/unit/mock_app_window_manager.js');
|
||||
require('/test/unit/mock_layout_manager.js');
|
||||
require('/test/unit/mock_system_dialog_manager.js');
|
||||
require('/test/unit/mock_keyboard_manager.js');
|
||||
require('/test/unit/mock_focus_manager.js');
|
||||
require('/js/service.js');
|
||||
require('/js/base_ui.js');
|
||||
require('/js/system_dialog.js');
|
||||
require('/js/fxa_dialog.js');
|
||||
|
||||
var mocksForFxAccountsDialog = new MocksHelper([
|
||||
'AppWindowManager',
|
||||
'LayoutManager',
|
||||
'SystemDialogManager',
|
||||
'KeyboardManager',
|
||||
'focusManager'
|
||||
]).init();
|
||||
|
||||
suite('smart-system/FxAccountsDialog', function() {
|
||||
var stubDispatch, container,
|
||||
fakeOptions = {
|
||||
onShow: function() {},
|
||||
onHide: function() {}
|
||||
};
|
||||
mocksForFxAccountsDialog.attachTestHelpers();
|
||||
|
||||
setup(function() {
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
SystemDialog.prototype.containerElement = container;
|
||||
|
||||
stubDispatch = this.sinon.stub(window, 'dispatchEvent');
|
||||
|
||||
window.layoutManager = new LayoutManager();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.removeChild(container);
|
||||
SystemDialog.prototype.containerElement = container = null;
|
||||
|
||||
stubDispatch.restore();
|
||||
|
||||
window.layoutManager = null;
|
||||
});
|
||||
|
||||
suite('Handle events', function() {
|
||||
test('Create system dialog would trigger events', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
assert.isTrue(stubDispatch.calledWithMatch(sinon.match(
|
||||
function(e) {
|
||||
return 'system-dialog-created' === e.type;
|
||||
})),
|
||||
'the event has not been fired');
|
||||
fxAccountsDialog = null;
|
||||
});
|
||||
|
||||
test('Show system dialog would trigger events', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.show();
|
||||
assert.isTrue(stubDispatch.calledWithMatch(sinon.match(
|
||||
function(e) {
|
||||
return 'system-dialog-show' === e.type;
|
||||
})),
|
||||
'the event has not been fired');
|
||||
});
|
||||
|
||||
test('Hide system dialog would trigger events', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.hide();
|
||||
assert.isTrue(stubDispatch.calledWithMatch(sinon.match(
|
||||
function(e) {
|
||||
return 'system-dialog-hide' === e.type;
|
||||
})),
|
||||
'the event has not been fired');
|
||||
});
|
||||
|
||||
test('The attribute "onShow" should be called with reason ' +
|
||||
'after system dialog is shown.', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
var stubOnShowCallback = this.sinon.stub(fxAccountsDialog.options,
|
||||
'onShow');
|
||||
var fakeReason = null;
|
||||
fxAccountsDialog.onShow(fakeReason);
|
||||
assert.isTrue(stubOnShowCallback.calledWith(null));
|
||||
});
|
||||
|
||||
test('The attribute "onHide" should be called with reason ' +
|
||||
'after system dialog is hidden.', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
var stubOnHideCallback = this.sinon.stub(fxAccountsDialog.options,
|
||||
'onHide');
|
||||
var fakeReason = 'home';
|
||||
fxAccountsDialog.onHide(fakeReason);
|
||||
assert.isTrue(stubOnHideCallback.calledWith('home'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('Create instance ID', function() {
|
||||
test('Create system Firefox accounts dialog ' +
|
||||
'would create instanceID = "fxa-dialog"', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
assert.equal('fxa-dialog', fxAccountsDialog.instanceID);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Get element', function() {
|
||||
test('Return element while called getView() function', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
var stubGetView = this.sinon.stub(fxAccountsDialog, 'getView');
|
||||
fxAccountsDialog.getView();
|
||||
assert.isTrue(stubGetView.called);
|
||||
});
|
||||
|
||||
test('Create system Firefox accounts dialog ' +
|
||||
'would get dialog element.', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
assert.isNotNull(fxAccountsDialog.element);
|
||||
});
|
||||
|
||||
test('Created system dialog should be hidden', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
assert.isTrue(fxAccountsDialog.element.hidden,
|
||||
'Element is created hidden.');
|
||||
});
|
||||
});
|
||||
|
||||
suite('Resize functions', function() {
|
||||
var isCalled;
|
||||
|
||||
setup(function(done) {
|
||||
isCalled = false;
|
||||
Object.defineProperty(FxAccountsDialog.prototype.containerElement.style,
|
||||
'height', {
|
||||
configurable: true,
|
||||
set: function() {
|
||||
isCalled = true;
|
||||
}
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
delete FxAccountsDialog.prototype.containerElement.style.height;
|
||||
});
|
||||
|
||||
test('The dialog height should be updated ' +
|
||||
'while "updateHeight()" called.', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.updateHeight();
|
||||
assert.isTrue(isCalled);
|
||||
});
|
||||
|
||||
test('The dialog height should be updated ' +
|
||||
'while resize request is coming.', function() {
|
||||
var fxAccountsDialog = new window.FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.resize();
|
||||
assert.isTrue(isCalled);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Handle focus', () => {
|
||||
var focusSpy;
|
||||
var addUISpy;
|
||||
var removeUISpy;
|
||||
|
||||
setup(() => {
|
||||
focusSpy = sinon.spy(focusManager, 'focus');
|
||||
addUISpy = sinon.spy(focusManager, 'addUI');
|
||||
removeUISpy = sinon.spy(focusManager, 'removeUI');
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
focusSpy.restore();
|
||||
addUISpy.restore();
|
||||
removeUISpy.restore();
|
||||
});
|
||||
|
||||
test('The created FxAccountsDialog will be added into focusManager', () => {
|
||||
new FxAccountsDialog(fakeOptions);
|
||||
sinon.assert.calledOnce(addUISpy);
|
||||
});
|
||||
|
||||
test('The destroyed FxAccountsDialog will be removed from focusManager',
|
||||
() => {
|
||||
var fxAccountsDialog = new FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.destroy();
|
||||
sinon.assert.calledOnce(removeUISpy);
|
||||
});
|
||||
|
||||
test('Should be able to get the "#fxa-dialog" element', () => {
|
||||
var fxAccountsDialog = new FxAccountsDialog(fakeOptions);
|
||||
var element = fxAccountsDialog.getElement();
|
||||
assert.equal('fxa-dialog', element.id);
|
||||
});
|
||||
|
||||
test('Should be focusable when the dialog is visible', () => {
|
||||
var fxAccountsDialog = new FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.element.classList.add('visible');
|
||||
assert.isTrue(fxAccountsDialog.isFocusable());
|
||||
});
|
||||
|
||||
test('Should not be focusable when the dialog is not visible', () => {
|
||||
var fxAccountsDialog = new FxAccountsDialog(fakeOptions);
|
||||
assert.isFalse(fxAccountsDialog.isFocusable());
|
||||
});
|
||||
|
||||
test('Should remove focus when the dialog is hidden', () => {
|
||||
var fxAccountsDialog = new FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.hide();
|
||||
sinon.assert.calledOnce(focusSpy);
|
||||
});
|
||||
|
||||
test('Should focus when the dialog is shown', () => {
|
||||
var fxAccountsDialog = new FxAccountsDialog(fakeOptions);
|
||||
fxAccountsDialog.show();
|
||||
sinon.assert.calledOnce(focusSpy);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
326
gaia/tv_apps/smart-system/test/unit/fxa_iac_client_test.js
Executable file
326
gaia/tv_apps/smart-system/test/unit/fxa_iac_client_test.js
Executable file
|
|
@ -0,0 +1,326 @@
|
|||
/* global FxAccountsIACHelper, MockApp, MockAppsMgmt */
|
||||
'use strict';
|
||||
|
||||
requireApp('system/test/unit/mock_apps_mgmt.js');
|
||||
requireApp('system/test/unit/mock_app.js');
|
||||
// XXX consider moving this to a separate file if it gets much more complex
|
||||
|
||||
// arthurcc's suggested replacement:
|
||||
var port = {
|
||||
postMessage: function(message) {
|
||||
var msg = {
|
||||
data: {
|
||||
data: {},
|
||||
methodName: message.name
|
||||
}
|
||||
};
|
||||
setTimeout(function() {
|
||||
port._onmessage(msg);
|
||||
});
|
||||
},
|
||||
_onmessage: null,
|
||||
set onmessage(cb) {
|
||||
port._onmessage = cb;
|
||||
}
|
||||
};
|
||||
|
||||
suite('FirefoxOS Accounts IAC Client Suite', function() {
|
||||
var realMozApps;
|
||||
|
||||
var postMessageSpy;
|
||||
|
||||
suiteSetup(function() {
|
||||
realMozApps = navigator.mozApps;
|
||||
navigator.mozApps = MockAppsMgmt;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
navigator.mozApps = realMozApps;
|
||||
});
|
||||
|
||||
setup(function(done) {
|
||||
// For each test, setup the 'self' app, able to
|
||||
// do IAC
|
||||
var app = new MockApp({
|
||||
'connect': function(keyword) {
|
||||
var future = {
|
||||
'then': function(cb) {}
|
||||
};
|
||||
sinon.stub(future, 'then', function(cb) {
|
||||
cb([port]);
|
||||
});
|
||||
return future;
|
||||
}
|
||||
});
|
||||
navigator.mozApps.setSelf(app);
|
||||
// XXX we have to require() the system under test *after* we define the
|
||||
// MockApp, because the code calls app.connect() as soon as it is loaded
|
||||
require('/shared/js/fxa_iac_client.js', done);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
if (postMessageSpy && postMessageSpy.restore) {
|
||||
postMessageSpy.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test('Library integrity', function() {
|
||||
assert.isNotNull(FxAccountsIACHelper);
|
||||
assert.equal(Object.keys(FxAccountsIACHelper).length, 9);
|
||||
});
|
||||
|
||||
['getAccount', 'openFlow', 'logout'].forEach(function(method) {
|
||||
suite(method + ' suite', function() {
|
||||
setup(function() {
|
||||
postMessageSpy = sinon.spy(port, 'postMessage');
|
||||
});
|
||||
|
||||
test('Check that we send the ' + method + ' message', function(done) {
|
||||
this.timeout(20000);
|
||||
port.methodName = method;
|
||||
FxAccountsIACHelper[method](
|
||||
function() {
|
||||
assert.ok(postMessageSpy.called);
|
||||
var arg = postMessageSpy.args[0][0];
|
||||
// We do have an id for this message
|
||||
assert.isNotNull(arg.id);
|
||||
assert.isNotNull(arg);
|
||||
// Remove the id, as it's automatically generated
|
||||
delete arg.id;
|
||||
|
||||
assert.deepEqual(arg, {
|
||||
'name': method
|
||||
});
|
||||
done();
|
||||
},
|
||||
function() {
|
||||
// Break if we are called.
|
||||
assert.ok(false);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
postMessageSpy.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('refreshAuthentication suite', function() {
|
||||
setup(function() {
|
||||
postMessageSpy = sinon.spy(port, 'postMessage');
|
||||
});
|
||||
|
||||
test('Check that we send the refreshAuth message', function(done) {
|
||||
this.timeout(20000);
|
||||
port.methodName = 'refreshAuthentication';
|
||||
FxAccountsIACHelper.refreshAuthentication('dummy@domain.org',
|
||||
function() {
|
||||
assert.ok(postMessageSpy.called);
|
||||
var arg = postMessageSpy.args[0][0];
|
||||
// We do have an id for this message
|
||||
assert.isNotNull(arg.id);
|
||||
assert.isNotNull(arg);
|
||||
// Remove the id, as it's automatically generated
|
||||
delete arg.id;
|
||||
|
||||
assert.deepEqual(arg, {
|
||||
'name': 'refreshAuthentication',
|
||||
'email': 'dummy@domain.org'
|
||||
});
|
||||
done();
|
||||
},
|
||||
function() {
|
||||
// Break if we are called.
|
||||
assert.ok(false);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
postMessageSpy.restore();
|
||||
});
|
||||
});
|
||||
|
||||
suite('resendVerificationEmail suite', function() {
|
||||
setup(function() {
|
||||
postMessageSpy = sinon.spy(port, 'postMessage');
|
||||
});
|
||||
|
||||
test('Check that we send the resend message', function(done) {
|
||||
this.timeout(20000);
|
||||
port.methodName = 'resendVerificationEmail';
|
||||
FxAccountsIACHelper.resendVerificationEmail('dummy@domain.org',
|
||||
function() {
|
||||
assert.ok(postMessageSpy.called);
|
||||
var arg = postMessageSpy.args[0][0];
|
||||
// We do have an id for this message
|
||||
assert.isNotNull(arg.id);
|
||||
assert.isNotNull(arg);
|
||||
// Remove the id, as it's automatically generated
|
||||
delete arg.id;
|
||||
|
||||
assert.deepEqual(arg, {
|
||||
'name': 'resendVerificationEmail',
|
||||
'email': 'dummy@domain.org'
|
||||
});
|
||||
done();
|
||||
},
|
||||
function() {
|
||||
// Break if we are called.
|
||||
assert.ok(false);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
postMessageSpy.restore();
|
||||
});
|
||||
});
|
||||
|
||||
suite('addEventListener tests', function() {
|
||||
var callbackCalled = false;
|
||||
var otherCallbackCalled = false;
|
||||
|
||||
var listener = function() {
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
var otherListener = function() {
|
||||
otherCallbackCalled = true;
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
FxAccountsIACHelper.addEventListener('myEvent', listener);
|
||||
FxAccountsIACHelper.addEventListener('myOtherEvent', otherListener);
|
||||
|
||||
port._onmessage({
|
||||
data: {
|
||||
data: {},
|
||||
eventName: 'myEvent'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('Check that we trigger the appropriate callback', function() {
|
||||
assert.ok(callbackCalled);
|
||||
assert.ok(!otherCallbackCalled);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
FxAccountsIACHelper.removeEventListener('myEvent', listener);
|
||||
FxAccountsIACHelper.removeEventListener('myOtherEvent', otherListener);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('removeEventListener tests', function() {
|
||||
var callbackCalled = false;
|
||||
var otherCallbackCalled = false;
|
||||
|
||||
var listener = function() {
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
var otherListener = function() {
|
||||
otherCallbackCalled = true;
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
FxAccountsIACHelper.addEventListener('myEvent', listener);
|
||||
FxAccountsIACHelper.addEventListener('myOtherEvent', otherListener);
|
||||
FxAccountsIACHelper.removeEventListener('myEvent', listener);
|
||||
|
||||
port._onmessage({
|
||||
data: {
|
||||
data: {},
|
||||
eventName: 'myEvent'
|
||||
}
|
||||
});
|
||||
|
||||
port._onmessage({
|
||||
data: {
|
||||
data: {},
|
||||
eventName: 'myOtherEvent'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('Check that we trigger the appropriate callback', function() {
|
||||
assert.ok(!callbackCalled);
|
||||
assert.ok(otherCallbackCalled);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('Startup race condition tests - bug 974108', function() {
|
||||
var callbackCalled, otherCallbackCalled;
|
||||
|
||||
var listener = function() {
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
var otherListener = function() {
|
||||
otherCallbackCalled = true;
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
this.clock = sinon.useFakeTimers();
|
||||
callbackCalled = false;
|
||||
otherCallbackCalled = false;
|
||||
// we are testing that postmessage requests are queued, not overwritten,
|
||||
// during the period between starting the Helper and the port being open.
|
||||
// we need to clear out the port, add 2 new subscribers, then check both
|
||||
// are called.
|
||||
var app = new MockApp({
|
||||
'connect': function(keyword) {
|
||||
var future = {
|
||||
'then': function(cb) {}
|
||||
};
|
||||
sinon.stub(future, 'then', function(cb) {
|
||||
// wait a turn so that we can queue up multiple requests
|
||||
setTimeout(function() {
|
||||
cb([port]);
|
||||
}, 0);
|
||||
});
|
||||
return future;
|
||||
}
|
||||
});
|
||||
navigator.mozApps.setSelf(app);
|
||||
FxAccountsIACHelper.reset();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.clock.restore();
|
||||
});
|
||||
|
||||
test('Should queue multiple requests until port is opened', function() {
|
||||
callbackCalled = false;
|
||||
otherCallbackCalled = false;
|
||||
// reset() will destroy the existing port, forcing message requests
|
||||
// to be queued up.
|
||||
FxAccountsIACHelper.reset();
|
||||
// two requests -- one to be sent as soon as the connection's ready,
|
||||
// the other after that.
|
||||
FxAccountsIACHelper.logout(otherListener);
|
||||
FxAccountsIACHelper.getAccount(listener);
|
||||
this.clock.tick(1000);
|
||||
assert.isTrue(callbackCalled);
|
||||
assert.isTrue(otherCallbackCalled);
|
||||
});
|
||||
|
||||
test('Should queue multiple callbacks for one request', function() {
|
||||
callbackCalled = false;
|
||||
otherCallbackCalled = false;
|
||||
FxAccountsIACHelper.reset();
|
||||
FxAccountsIACHelper.getAccount(listener);
|
||||
FxAccountsIACHelper.getAccount(otherListener);
|
||||
this.clock.tick(1000);
|
||||
assert.isTrue(callbackCalled);
|
||||
assert.isTrue(otherCallbackCalled);
|
||||
});
|
||||
});
|
||||
});
|
||||
436
gaia/tv_apps/smart-system/test/unit/interactive_notifications_test.js
Executable file
436
gaia/tv_apps/smart-system/test/unit/interactive_notifications_test.js
Executable file
|
|
@ -0,0 +1,436 @@
|
|||
/* global MockSimpleKeyNavigation, InteractiveNotifications, focusManager */
|
||||
|
||||
'use strict';
|
||||
requireApp('smart-system/test/unit/mock_iac_handler.js');
|
||||
requireApp('smart-system/test/unit/mock_simple_key_navigation.js');
|
||||
requireApp('smart-system/bower_components/evt/index.js');
|
||||
requireApp('smart-system/bower_components/smart-banner/script.js');
|
||||
requireApp('smart-system/js/interactive_notifications.js');
|
||||
|
||||
suite('interactive notifications', function() {
|
||||
var testTarget;
|
||||
var TYPE;
|
||||
var message1 = {
|
||||
'text': 'message1',
|
||||
'onClosed': function(){}
|
||||
};
|
||||
|
||||
var message2 = {
|
||||
'title': 'title2',
|
||||
'text': 'message2',
|
||||
'buttons': [{'id': 'button-1', 'label': 'button1'}],
|
||||
'onClosed': function(){}
|
||||
};
|
||||
|
||||
var message3 = {
|
||||
'text': 'message3',
|
||||
'onClosed': function(){}
|
||||
};
|
||||
|
||||
var message4 = {
|
||||
'text': 'message4',
|
||||
'buttons': [{'id': 'button-2', 'label': 'button2'}],
|
||||
'onClosed': function(){}
|
||||
};
|
||||
|
||||
var fakeApp = {
|
||||
'focus': function() {},
|
||||
'getTopMostWindow': function() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
var fakeAppWinMgr = {
|
||||
'getActiveApp': function() {
|
||||
return fakeApp;
|
||||
}
|
||||
};
|
||||
|
||||
var stubs = {};
|
||||
var fakeTimer;
|
||||
var realSimpleKeyNavigation;
|
||||
var realFocusManager;
|
||||
var mockElements = {};
|
||||
|
||||
function createMockElement(options) {
|
||||
var id = options.id;
|
||||
var mockOpenClose = options.mockOpenClose;
|
||||
var tagName = options.tagName || 'div';
|
||||
var element = document.createElement(tagName);
|
||||
element.id = id;
|
||||
if (mockOpenClose) {
|
||||
element.open = element.close = function(){};
|
||||
element.on = element.once = element.off = function(){};
|
||||
}
|
||||
if (tagName === 'smart-banner') {
|
||||
element.hide = element.flyOpen = function() {};
|
||||
}
|
||||
document.body.appendChild(element);
|
||||
return element;
|
||||
}
|
||||
|
||||
function createMockUI() {
|
||||
// containerElement
|
||||
mockElements['notification-container'] = createMockElement({
|
||||
id: 'notification-container',
|
||||
mockOpenClose: true,
|
||||
tagName: 'smart-banner'
|
||||
});
|
||||
// buttonGroupElement
|
||||
mockElements['notification-button-group'] =
|
||||
createMockElement({id: 'notification-button-group'});
|
||||
// titleElement
|
||||
mockElements['notification-title'] =
|
||||
createMockElement({id: 'notification-title'});
|
||||
// bodyElement
|
||||
mockElements['notification-body'] =
|
||||
createMockElement({id: 'notification-body'});
|
||||
// button1Element
|
||||
mockElements['notification-button-0'] =
|
||||
createMockElement({id: 'notification-button-0'});
|
||||
// button2Element
|
||||
mockElements['notification-button-1'] =
|
||||
createMockElement({id: 'notification-button-1'});
|
||||
}
|
||||
|
||||
// var getElementByIdStub;
|
||||
suiteSetup(function() {
|
||||
window.IACHandler = window.MockIACHandler;
|
||||
window.AppWindowManager = fakeAppWinMgr;
|
||||
realFocusManager = window.focusManager;
|
||||
window.focusManager = {
|
||||
focus: function() {},
|
||||
addUI: function() {}
|
||||
};
|
||||
realSimpleKeyNavigation = window.SimpleKeyNavigation;
|
||||
window.SimpleKeyNavigation = MockSimpleKeyNavigation;
|
||||
createMockUI();
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.SimpleKeyNavigation = realSimpleKeyNavigation;
|
||||
window.focusManager = realFocusManager;
|
||||
mockElements = {};
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
TYPE = InteractiveNotifications.TYPE;
|
||||
testTarget = new InteractiveNotifications();
|
||||
testTarget.start();
|
||||
|
||||
stubs.msg1Closed = sinon.stub(message1, 'onClosed');
|
||||
stubs.msg2Closed = sinon.stub(message2, 'onClosed');
|
||||
stubs.msg3Closed = sinon.stub(message3, 'onClosed');
|
||||
stubs.msg4Closed = sinon.stub(message4, 'onClosed');
|
||||
stubs.updateUISpy = sinon.spy(testTarget, '_updateNotificationUI');
|
||||
stubs.bannerHide =
|
||||
sinon.spy(mockElements['notification-container'], 'hide');
|
||||
stubs.focusManagerFocus = sinon.spy(focusManager, 'focus');
|
||||
fakeTimer = sinon.useFakeTimers();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
stubs.msg1Closed.restore();
|
||||
stubs.msg2Closed.restore();
|
||||
stubs.msg3Closed.restore();
|
||||
stubs.msg4Closed.restore();
|
||||
stubs.updateUISpy.restore();
|
||||
stubs.bannerHide.restore();
|
||||
stubs.focusManagerFocus.restore();
|
||||
fakeTimer.restore();
|
||||
testTarget.stop();
|
||||
});
|
||||
|
||||
test('show normal notification without buttons', function() {
|
||||
testTarget.showNotification(TYPE.NORMAL, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message1));
|
||||
assert.isFalse(stubs.bannerHide.called);
|
||||
assert.isTrue(mockElements['notification-body'].textContent !== '');
|
||||
assert.isTrue(mockElements['notification-title'].textContent === '');
|
||||
fakeTimer.tick(5000);
|
||||
assert.isTrue(stubs.bannerHide.calledOnce);
|
||||
});
|
||||
|
||||
test('show normal notification with buttons', function() {
|
||||
testTarget.showNotification(TYPE.NORMAL, message2);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message2));
|
||||
assert.isTrue(mockElements['notification-title'].titleContent !== '');
|
||||
assert.isTrue(mockElements['notification-container'].classList.contains(
|
||||
'has-title'));
|
||||
assert.isFalse(stubs.bannerHide.called);
|
||||
fakeTimer.tick(5000);
|
||||
assert.isFalse(stubs.bannerHide.called);
|
||||
fakeTimer.tick(3000);
|
||||
assert.isTrue(stubs.bannerHide.calledOnce);
|
||||
});
|
||||
|
||||
test('show alert notification without buttons', function() {
|
||||
testTarget.showNotification(TYPE.ALERT, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message1));
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
fakeTimer.tick(8000);
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
});
|
||||
|
||||
test('show alert notification with buttons', function() {
|
||||
testTarget.showNotification(TYPE.ALERT, message2);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message2));
|
||||
assert.isFalse(stubs.msg2Closed.called);
|
||||
fakeTimer.tick(8000);
|
||||
assert.isFalse(stubs.msg2Closed.called);
|
||||
});
|
||||
|
||||
test('should set focus back after hideNotification()', function() {
|
||||
testTarget.showNotification(TYPE.NORMAL, message1);
|
||||
fakeTimer.tick(5000);
|
||||
assert.isTrue(stubs.focusManagerFocus.calledOnce);
|
||||
});
|
||||
|
||||
suite('> queue normal notification', function() {
|
||||
|
||||
setup(function() {
|
||||
testTarget.showNotification(TYPE.NORMAL, message1);
|
||||
testTarget.showNotification(TYPE.NORMAL, message3);
|
||||
});
|
||||
|
||||
test('> close first', function() {
|
||||
testTarget.hideNotification(TYPE.NORMAL, message1);
|
||||
assert.isTrue(stubs.bannerHide.called);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message3));
|
||||
});
|
||||
|
||||
test('> auto hide first', function() {
|
||||
fakeTimer.tick(5000);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(stubs.msg1Closed.called);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message3));
|
||||
});
|
||||
|
||||
test('> close wrong type (alert)', function() {
|
||||
testTarget.hideNotification(TYPE.ALERT, message1);
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.NORMAL, message3));
|
||||
assert.isFalse(stubs.msg3Closed.called);
|
||||
});
|
||||
|
||||
test('> close wrong msg', function() {
|
||||
testTarget.hideNotification(TYPE.NORMAL, message2);
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.NORMAL, message3));
|
||||
assert.isFalse(stubs.msg3Closed.called);
|
||||
});
|
||||
|
||||
test('> close queued', function() {
|
||||
testTarget.hideNotification(TYPE.NORMAL, message3);
|
||||
assert.isTrue(stubs.msg3Closed.called);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.NORMAL, message3));
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('> queue alert notification', function() {
|
||||
|
||||
setup(function() {
|
||||
testTarget.showNotification(TYPE.ALERT, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message1));
|
||||
testTarget.showNotification(TYPE.ALERT, message3);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isFalse(stubs.msg3Closed.called);
|
||||
});
|
||||
|
||||
test('> close first', function() {
|
||||
testTarget.hideNotification(TYPE.ALERT, message1);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(stubs.msg1Closed.called);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
});
|
||||
|
||||
test('> close wrong type (normal)', function() {
|
||||
testTarget.hideNotification(TYPE.NORMAL, message1);
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isFalse(stubs.msg3Closed.called);
|
||||
});
|
||||
|
||||
test('> close wrong msg', function() {
|
||||
testTarget.hideNotification(TYPE.ALERT, message2);
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isFalse(stubs.msg3Closed.called);
|
||||
});
|
||||
|
||||
test('> close queued', function() {
|
||||
testTarget.hideNotification(TYPE.ALERT, message3);
|
||||
assert.isTrue(stubs.msg3Closed.called);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('> notification priority from low to high', function() {
|
||||
|
||||
setup(function() {
|
||||
testTarget.showNotification(TYPE.NORMAL, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message1));
|
||||
});
|
||||
|
||||
test('> show alert', function() {
|
||||
testTarget.showNotification(TYPE.ALERT, message3);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isTrue(stubs.msg1Closed.called);
|
||||
fakeTimer.tick(5000);
|
||||
// recheck if onclosed is double called
|
||||
assert.isTrue(stubs.msg1Closed.calledOnce);
|
||||
});
|
||||
|
||||
test('> queue normal and show alert', function() {
|
||||
// 1, 2 is normal, 3 is alert
|
||||
testTarget.showNotification(TYPE.NORMAL, message2);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.NORMAL, message2));
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
testTarget.showNotification(TYPE.ALERT, message3);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isTrue(stubs.msg1Closed.called);
|
||||
fakeTimer.tick(5000);
|
||||
// recheck if onclosed is double called
|
||||
assert.isTrue(stubs.msg1Closed.calledOnce);
|
||||
// hide alert
|
||||
testTarget.hideNotification(TYPE.ALERT, message3);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
// check queued normal
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message2));
|
||||
assert.isTrue(stubs.msg3Closed.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('> notification priority from high to low', function() {
|
||||
|
||||
setup(function() {
|
||||
testTarget.showNotification(TYPE.ALERT, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message1));
|
||||
});
|
||||
|
||||
test('> show alert', function() {
|
||||
// 1 is alert, 3 is normal
|
||||
testTarget.showNotification(TYPE.NORMAL, message3);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.NORMAL, message3));
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
// hide alert
|
||||
testTarget.hideNotification(TYPE.ALERT, message1);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
// check queued
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message3));
|
||||
assert.isTrue(stubs.msg1Closed.called);
|
||||
});
|
||||
|
||||
test('> queue normal, show alert, and hide previous alert', function() {
|
||||
// 2 is normal, 1, 3 is alert
|
||||
// queue normal
|
||||
testTarget.showNotification(TYPE.NORMAL, message2);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.NORMAL, message2));
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
|
||||
// queue alert
|
||||
testTarget.showNotification(TYPE.ALERT, message3);
|
||||
assert.isFalse(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isFalse(stubs.msg1Closed.called);
|
||||
|
||||
// hide alert 1
|
||||
testTarget.hideNotification(TYPE.ALERT, message1);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message3));
|
||||
assert.isTrue(stubs.msg1Closed.called);
|
||||
|
||||
// hide alert 3
|
||||
testTarget.hideNotification(TYPE.ALERT, message3);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message2));
|
||||
assert.isTrue(stubs.msg3Closed.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('IAC Connections', function() {
|
||||
var port = {
|
||||
postMessage: function(data){}
|
||||
};
|
||||
var portStub;
|
||||
var postedData;
|
||||
|
||||
function sendIACMessage(id, type, message) {
|
||||
var iacEvt = document.createEvent('CustomEvent');
|
||||
iacEvt.initCustomEvent('iac-interactivenotifications',
|
||||
/* canBubble: */ true, /* cancelable */ false, {
|
||||
'id': id,
|
||||
'type': type,
|
||||
'message': message
|
||||
});
|
||||
|
||||
window.dispatchEvent(iacEvt);
|
||||
}
|
||||
|
||||
suiteSetup(function() {
|
||||
window.MockIACHandler._portMap.interactivenotifications = port;
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
window.MockIACHandler.reset();
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
portStub = sinon.stub(port, 'postMessage', function(data) {
|
||||
postedData = data;
|
||||
});
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
portStub.restore();
|
||||
});
|
||||
|
||||
test('send normal', function() {
|
||||
sendIACMessage('a', TYPE.NORMAL, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message1));
|
||||
// auto hide
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
fakeTimer.tick(5000);
|
||||
assert.isTrue(portStub.calledOnce);
|
||||
assert.equal('notification-closed', postedData.action);
|
||||
assert.equal('a', postedData.id);
|
||||
assert.equal(TYPE.NORMAL, postedData.type);
|
||||
assert.isUndefined(postedData.button);
|
||||
});
|
||||
|
||||
test('send alert', function() {
|
||||
sendIACMessage('a', TYPE.ALERT, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.ALERT, message1));
|
||||
assert.isFalse(portStub.calledOnce);
|
||||
// hide alert
|
||||
testTarget.hideNotification(TYPE.ALERT, message1);
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(portStub.calledOnce);
|
||||
assert.equal('notification-closed', postedData.action);
|
||||
assert.equal('a', postedData.id);
|
||||
assert.equal(TYPE.ALERT, postedData.type);
|
||||
assert.isUndefined(postedData.button);
|
||||
});
|
||||
|
||||
test('hide normal with button', function() {
|
||||
sendIACMessage('a', TYPE.NORMAL, message1);
|
||||
assert.isTrue(stubs.updateUISpy.calledWith(TYPE.NORMAL, message1));
|
||||
|
||||
testTarget.hideNotification(TYPE.NORMAL, message1, 'buttonX');
|
||||
testTarget.handleEvent({type: 'hidden'});
|
||||
assert.isTrue(portStub.calledOnce);
|
||||
assert.equal('notification-closed', postedData.action);
|
||||
assert.equal('a', postedData.id);
|
||||
assert.equal(TYPE.NORMAL, postedData.type);
|
||||
assert.equal('buttonX', postedData.button);
|
||||
|
||||
// check auto hide
|
||||
fakeTimer.tick(5000);
|
||||
assert.isTrue(portStub.calledOnce);
|
||||
});
|
||||
});
|
||||
});
|
||||
62
gaia/tv_apps/smart-system/test/unit/mock_app_window_manager.js
Executable file
62
gaia/tv_apps/smart-system/test/unit/mock_app_window_manager.js
Executable file
|
|
@ -0,0 +1,62 @@
|
|||
'use strict';
|
||||
|
||||
var MockAppWindowManager = function() {};
|
||||
MockAppWindowManager.prototype = {
|
||||
isRunning: function(config) {
|
||||
return (config.origin in this.mRunningApps);
|
||||
},
|
||||
|
||||
mRunningApps: {},
|
||||
|
||||
// TODO: Remove this.
|
||||
getRunningApps: function mawm_getRunningApps() {
|
||||
return this.mRunningApps;
|
||||
},
|
||||
|
||||
// TODO: Remove this.
|
||||
getApps: function mawm_getRunningApps() {
|
||||
return this.mRunningApps;
|
||||
},
|
||||
|
||||
getActiveApp: function mawm_getActiveApp() {
|
||||
return this.mActiveApp;
|
||||
},
|
||||
|
||||
getApp: function mawm_getActiveApp(origin) {
|
||||
return this.mRunningApps[origin];
|
||||
},
|
||||
|
||||
getAppByURL: function mawm_getAppByUrl() {
|
||||
return null;
|
||||
},
|
||||
|
||||
// reference to active appWindow instance.
|
||||
mActiveApp: null,
|
||||
|
||||
slowTransition: false,
|
||||
|
||||
// Switch to a different app
|
||||
display: function mawm_display(origin, callback) {
|
||||
this.mActiveApp = this.mRunningApps[origin];
|
||||
},
|
||||
|
||||
kill: function mawm_kill(origin) {
|
||||
this.mLastKilledOrigin = origin;
|
||||
},
|
||||
|
||||
mTeardown: function mawm_mTeardown() {
|
||||
this.mRunningApps = {};
|
||||
this.mActiveApp = null;
|
||||
},
|
||||
|
||||
broadcastMessage: function() {
|
||||
},
|
||||
|
||||
sendStopRecordingRequest: function(callback) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
start: function() {}
|
||||
};
|
||||
42
gaia/tv_apps/smart-system/test/unit/mock_asyncStorage.js
Executable file
42
gaia/tv_apps/smart-system/test/unit/mock_asyncStorage.js
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
'use strict';
|
||||
|
||||
/* exported MockasyncStorage */
|
||||
|
||||
var MockasyncStorage = {
|
||||
mItems: {},
|
||||
|
||||
setItem: function(key, value, callback) {
|
||||
this.mItems[key] = value;
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
getItem: function(key, callback) {
|
||||
var value = this.mItems[key];
|
||||
// use '|| null' will turn a 'false' to null
|
||||
if (value === undefined) {
|
||||
value = null;
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
callback(value);
|
||||
}
|
||||
},
|
||||
|
||||
removeItem: function(key, callback) {
|
||||
if (key in this.mItems) {
|
||||
delete this.mItems[key];
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
mTeardown: function() {
|
||||
this.mItems = {};
|
||||
}
|
||||
};
|
||||
17
gaia/tv_apps/smart-system/test/unit/mock_focus_manager.js
Executable file
17
gaia/tv_apps/smart-system/test/unit/mock_focus_manager.js
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
/* exported MockfocusManager */
|
||||
|
||||
'use strict';
|
||||
|
||||
var MockfocusManager = {
|
||||
|
||||
addUI() {},
|
||||
|
||||
removeUI() {},
|
||||
|
||||
start() {},
|
||||
|
||||
stop() {},
|
||||
|
||||
focus() {}
|
||||
|
||||
};
|
||||
50
gaia/tv_apps/smart-system/test/unit/mock_fxa_client.js
Executable file
50
gaia/tv_apps/smart-system/test/unit/mock_fxa_client.js
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
'use strict';
|
||||
/* exported MockFxAccountsClient */
|
||||
|
||||
var MockFxAccountsClient = {
|
||||
_errorMsg: null,
|
||||
_successMsg: null,
|
||||
_call: null,
|
||||
_email: null,
|
||||
|
||||
_reset: function() {
|
||||
this._call = null;
|
||||
this._errorMsg = null;
|
||||
this._successMsg = null;
|
||||
this._email = null;
|
||||
},
|
||||
|
||||
_triggerCallback: function(successCb, errorCb) {
|
||||
if (this._errorMsg && errorCb) {
|
||||
errorCb(this._errorMsg);
|
||||
return;
|
||||
}
|
||||
successCb && successCb(this._successMsg);
|
||||
},
|
||||
|
||||
getAccount: function(successCb, errorCb) {
|
||||
this._call = 'getAccount';
|
||||
this._triggerCallback(successCb, errorCb);
|
||||
},
|
||||
|
||||
getAssertion: function(options, successCb, errorCb) {
|
||||
this._call = 'getAssertion';
|
||||
if (this._errorMsg) {
|
||||
errorCb(this._errorMsg);
|
||||
return;
|
||||
}
|
||||
successCb(Date.now() /* fake assertion */);
|
||||
},
|
||||
|
||||
resendVerificationEmail: function(email, successCb, errorCb) {
|
||||
this._email = email;
|
||||
this._call = 'resendVerificationEmail';
|
||||
this._triggerCallback(successCb, errorCb);
|
||||
},
|
||||
|
||||
logout: function(successCb, errorCb) {
|
||||
this._call = 'logout';
|
||||
this._triggerCallback(successCb, errorCb);
|
||||
}
|
||||
};
|
||||
|
||||
17
gaia/tv_apps/smart-system/test/unit/mock_iac_handler.js
Executable file
17
gaia/tv_apps/smart-system/test/unit/mock_iac_handler.js
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
var MockIACHandler = {
|
||||
_portMap: {},
|
||||
|
||||
reset: function() {
|
||||
this._portMap = {};
|
||||
},
|
||||
|
||||
getPort: function(name) {
|
||||
return this._portMap[name];
|
||||
}
|
||||
};
|
||||
|
||||
exports.MockIACHandler = MockIACHandler;
|
||||
}(window));
|
||||
13
gaia/tv_apps/smart-system/test/unit/mock_keyboard_manager.js
Executable file
13
gaia/tv_apps/smart-system/test/unit/mock_keyboard_manager.js
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
/* exported MockKeyboardManager */
|
||||
|
||||
var MockKeyboardManager = {
|
||||
mHeight: 0,
|
||||
init: function() {},
|
||||
mTeardown: function() {
|
||||
this.mHeight = 0;
|
||||
},
|
||||
_onKeyboardReady: function() {},
|
||||
_onKeyboardKilled: function() {},
|
||||
inputTypeTable: {}
|
||||
};
|
||||
27
gaia/tv_apps/smart-system/test/unit/mock_layout_manager.js
Executable file
27
gaia/tv_apps/smart-system/test/unit/mock_layout_manager.js
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
var MockLayoutManager = function MockLayoutManager() {};
|
||||
MockLayoutManager.prototype = {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
mKeyboardHeight: 0,
|
||||
keyboardEnabled: false,
|
||||
match: function() {
|
||||
return true;
|
||||
},
|
||||
getHeightFor: function(win, ignoreKeyboard) {
|
||||
return this.height - (ignoreKeyboard ? 0 : this.mKeyboardHeight);
|
||||
},
|
||||
start: function() {
|
||||
return this;
|
||||
},
|
||||
mTeardown: function mlm_mTeardown() {
|
||||
this.width = window.innerWidth;
|
||||
this.height = window.innerHeight;
|
||||
this.keyboardEnabled = false;
|
||||
this.mKeyboardHeight = 0;
|
||||
}
|
||||
};
|
||||
exports.MockLayoutManager = MockLayoutManager;
|
||||
}(window));
|
||||
12
gaia/tv_apps/smart-system/test/unit/mock_simple_key_navigation.js
Executable file
12
gaia/tv_apps/smart-system/test/unit/mock_simple_key_navigation.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
(function(exports) {
|
||||
'use strict';
|
||||
var MockSimpleKeyNavigation = function() {};
|
||||
|
||||
MockSimpleKeyNavigation.prototype = {
|
||||
start: function() {},
|
||||
stop: function() {},
|
||||
focus: function() {}
|
||||
};
|
||||
|
||||
exports.MockSimpleKeyNavigation = MockSimpleKeyNavigation;
|
||||
}(window));
|
||||
12
gaia/tv_apps/smart-system/test/unit/mock_system_dialog_manager.js
Executable file
12
gaia/tv_apps/smart-system/test/unit/mock_system_dialog_manager.js
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
|
||||
var MockSystemDialogManager = function SystemDialogManager() {};
|
||||
|
||||
// It should be exposed only events.
|
||||
MockSystemDialogManager.prototype.handleEvent =
|
||||
function() {};
|
||||
|
||||
exports.MockSystemDialogManager = MockSystemDialogManager;
|
||||
})(window);
|
||||
3
gaia/tv_apps/smart-system/test/unit/setup.js
Executable file
3
gaia/tv_apps/smart-system/test/unit/setup.js
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
'use strict';
|
||||
|
||||
require('/shared/test/unit/mocks/mocks_helper.js');
|
||||
1657
gaia/tv_apps/smart-system/test/unit/sync_manager_test.js
Executable file
1657
gaia/tv_apps/smart-system/test/unit/sync_manager_test.js
Executable file
File diff suppressed because it is too large
Load diff
369
gaia/tv_apps/smart-system/test/unit/sync_state_machine_test.js
Executable file
369
gaia/tv_apps/smart-system/test/unit/sync_state_machine_test.js
Executable file
|
|
@ -0,0 +1,369 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* global Deferred */
|
||||
/* global SyncStateMachine */
|
||||
/* global SyncStateMachineTransitions */
|
||||
|
||||
'use strict';
|
||||
|
||||
requireApp('smart-system/test/unit/deferred.js');
|
||||
requireApp('smart-system/js/sync_state_machine.js');
|
||||
|
||||
suite('smart-system/SyncStateMachine >', () => {
|
||||
|
||||
suite('Initial state', () => {
|
||||
test('Integrity', () => {
|
||||
assert.ok(SyncStateMachine !== undefined);
|
||||
|
||||
// SyncStateMachine is supposed to expose a function per transition.
|
||||
for (var name in SyncStateMachineTransitions) {
|
||||
if (!SyncStateMachineTransitions.hasOwnProperty(name)) {
|
||||
continue;
|
||||
}
|
||||
assert.ok(SyncStateMachine[name] !== undefined);
|
||||
assert.ok(SyncStateMachine[name] instanceof Function);
|
||||
}
|
||||
});
|
||||
|
||||
test('Initial state should be disabled', () => {
|
||||
assert.equal(SyncStateMachine.state, 'disabled');
|
||||
});
|
||||
});
|
||||
|
||||
suite('Transitions invalid for state', () => {
|
||||
[{
|
||||
from: 'disabled',
|
||||
invalidTransitions: [
|
||||
'disable',
|
||||
'sync',
|
||||
'error',
|
||||
'success'
|
||||
],
|
||||
transition: 'enable'
|
||||
}, {
|
||||
from: 'enabling',
|
||||
invalidTransitions: [
|
||||
'enable',
|
||||
'disable',
|
||||
'sync'
|
||||
],
|
||||
transition: 'success'
|
||||
}, {
|
||||
from: 'enabled',
|
||||
invalidTransitions: [
|
||||
'enable',
|
||||
'success'
|
||||
],
|
||||
transition: 'sync'
|
||||
}, {
|
||||
from: 'syncing',
|
||||
invalidTransitions: [
|
||||
'enable',
|
||||
'sync'
|
||||
],
|
||||
transition: 'error'
|
||||
}, {
|
||||
from: 'errored',
|
||||
invalidTransitions: [
|
||||
'sync',
|
||||
'success',
|
||||
'error'
|
||||
],
|
||||
transition: 'disable'
|
||||
}, {
|
||||
from: 'disabling',
|
||||
invalidTransitions: [
|
||||
'enable',
|
||||
'disable',
|
||||
'sync'
|
||||
],
|
||||
transition: 'success'
|
||||
}].forEach(config => {
|
||||
test(config.from + ' - invalid transitions', () => {
|
||||
config.invalidTransitions.forEach(transition => {
|
||||
try {
|
||||
SyncStateMachine[transition]();
|
||||
assert.ok(false, 'Should have thrown exception');
|
||||
} catch(e) {
|
||||
assert.ok(true, 'Expected exception');
|
||||
assert.equal(e.message, 'Transition ' + transition +
|
||||
' invalid for the current state');
|
||||
assert.equal(SyncStateMachine.state, config.from);
|
||||
}
|
||||
});
|
||||
SyncStateMachine[config.transition]();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('State transitions', () => {
|
||||
// Some of the transitions are repeated so we can test all the possible
|
||||
// transitions.
|
||||
[{
|
||||
from: 'disabled',
|
||||
to: 'enabling',
|
||||
transition: 'enable',
|
||||
expectedEvent: 'enabling',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabled',
|
||||
'errored',
|
||||
'disabled',
|
||||
'syncing'
|
||||
],
|
||||
}, {
|
||||
from: 'enabling',
|
||||
to: 'errored',
|
||||
transition: 'error',
|
||||
expectedEvent: 'errored',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabled',
|
||||
'disabled',
|
||||
'enabling',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'errored',
|
||||
to: 'disabling',
|
||||
transition: 'disable',
|
||||
expectedEvent: 'disabling',
|
||||
unexpectedEvents: [
|
||||
'disabled',
|
||||
'enabled',
|
||||
'enabling',
|
||||
'errored',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'disabling',
|
||||
to: 'disabled',
|
||||
transition: 'success',
|
||||
expectedEvent: 'disabled',
|
||||
unexpectedEvents: [
|
||||
'enabled',
|
||||
'enabling',
|
||||
'errored',
|
||||
'disabling',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'disabled',
|
||||
to: 'enabling',
|
||||
transition: 'enable',
|
||||
expectedEvent: 'enabling',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabled',
|
||||
'errored',
|
||||
'disabled',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'enabling',
|
||||
to: 'enabled',
|
||||
transition: 'success',
|
||||
expectedEvent: 'enabled',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabling',
|
||||
'errored',
|
||||
'disabled',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'enabled',
|
||||
to: 'syncing',
|
||||
transition: 'sync',
|
||||
expectedEvent: 'syncing',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabled',
|
||||
'enabling',
|
||||
'disabled',
|
||||
'errored'
|
||||
]
|
||||
}, {
|
||||
from: 'syncing',
|
||||
to: 'enabled',
|
||||
transition: 'success',
|
||||
expectedEvent: 'enabled',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'disabled',
|
||||
'enabling',
|
||||
'errored',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'enabled',
|
||||
to: 'syncing',
|
||||
transition: 'sync',
|
||||
expectedEvent: 'syncing',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabled',
|
||||
'enabling',
|
||||
'disabled',
|
||||
'errored'
|
||||
]
|
||||
}, {
|
||||
from: 'syncing',
|
||||
to: 'disabling',
|
||||
transition: 'disable',
|
||||
expectedEvent: 'disabling',
|
||||
unexpectedEvents: [
|
||||
'disabled',
|
||||
'enabled',
|
||||
'errored',
|
||||
'enabling',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'disabling',
|
||||
to: 'disabled',
|
||||
transition: 'success',
|
||||
expectedEvent: 'disabled',
|
||||
unexpectedEvents: [
|
||||
'enabled',
|
||||
'enabling',
|
||||
'errored',
|
||||
'disabling',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'disabled',
|
||||
to: 'enabling',
|
||||
transition: 'enable',
|
||||
expectedEvent: 'enabling',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'disabled',
|
||||
'errored',
|
||||
'enabled',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'enabling',
|
||||
to: 'enabled',
|
||||
transition: 'success',
|
||||
expectedEvent: 'enabled',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabling',
|
||||
'errored',
|
||||
'disabled',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'enabled',
|
||||
to: 'syncing',
|
||||
transition: 'sync',
|
||||
expectedEvent: 'syncing',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabled',
|
||||
'enabling',
|
||||
'disabled',
|
||||
'errored'
|
||||
]
|
||||
}, {
|
||||
from: 'syncing',
|
||||
to: 'errored',
|
||||
transition: 'error',
|
||||
expectedEvent: 'errored',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'enabled',
|
||||
'disabled',
|
||||
'enabling',
|
||||
'syncing'
|
||||
],
|
||||
arg: 'error'
|
||||
}, {
|
||||
from: 'errored',
|
||||
to: 'enabled',
|
||||
transition: 'enable',
|
||||
expectedEvent: 'enabled',
|
||||
unexpectedEvents: [
|
||||
'disabling',
|
||||
'disabled',
|
||||
'enabling',
|
||||
'syncing',
|
||||
'errored'
|
||||
]
|
||||
}, {
|
||||
from: 'enabled',
|
||||
to: 'disabling',
|
||||
transition: 'disable',
|
||||
expectedEvent: 'disabling',
|
||||
unexpectedEvents: [
|
||||
'disabled',
|
||||
'enabled',
|
||||
'enabling',
|
||||
'errored',
|
||||
'syncing'
|
||||
]
|
||||
}, {
|
||||
from: 'disabling',
|
||||
to: 'disabled',
|
||||
transition: 'success',
|
||||
expectedEvent: 'disabled',
|
||||
unexpectedEvents: [
|
||||
'enabled',
|
||||
'enabling',
|
||||
'errored',
|
||||
'disabling',
|
||||
'syncing'
|
||||
]
|
||||
}].forEach(config => {
|
||||
test('Transition ' + config.transition + ' while on ' +
|
||||
config.from + ' state', done => {
|
||||
var promises = [];
|
||||
|
||||
var onexpectedDeferred = new Deferred();
|
||||
promises.push(onexpectedDeferred.promise);
|
||||
var onexpected = (from, transition, args) => {
|
||||
assert.ok(true, 'Received expected SyncStateMachine' +
|
||||
config.expectedEvent);
|
||||
assert.equal(transition, config.transition);
|
||||
assert.equal(from, config.from);
|
||||
if (args) {
|
||||
assert.equal(args, config.arg);
|
||||
}
|
||||
onexpectedDeferred.resolve();
|
||||
};
|
||||
|
||||
var onunexpected = () => {
|
||||
assert.ok(false, 'Received unexpected event');
|
||||
cleanup();
|
||||
};
|
||||
|
||||
function cleanup() {
|
||||
config.unexpectedEvents.forEach(unexpectedEvent => {
|
||||
SyncStateMachine['on' + unexpectedEvent] = null;
|
||||
});
|
||||
SyncStateMachine['on' + config.expectedEvent] = null;
|
||||
done();
|
||||
}
|
||||
|
||||
SyncStateMachine['on' + config.expectedEvent] = onexpected;
|
||||
config.unexpectedEvents.forEach(unexpectedEvent => {
|
||||
SyncStateMachine['on' + unexpectedEvent] = onunexpected;
|
||||
});
|
||||
|
||||
promises.push(new Promise(resolve => {
|
||||
SyncStateMachine[config.transition](config.arg);
|
||||
assert.equal(SyncStateMachine.state, config.to);
|
||||
resolve();
|
||||
}));
|
||||
|
||||
Promise.all(promises).then(cleanup);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue