VulpesOS/gaia/apps/system/test/unit/hierarchy_manager_test.js
OverSu b38dea0597 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.
2026-09-30 23:13:03 +02:00

445 lines
18 KiB
JavaScript
Executable file

/* global MocksHelper, BaseModule, MockAppWindow, MockAttentionWindow */
'use strict';
requireApp('system/test/unit/mock_app_window.js');
requireApp('system/test/unit/mock_attention_window.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
requireApp('system/js/service.js');
requireApp('system/js/base_module.js');
requireApp('system/js/hierarchy_manager.js');
var mocksForHierarchyManager = new MocksHelper([
'LazyLoader'
]).init();
suite('system/HierarchyManager', function() {
var subject;
mocksForHierarchyManager.attachTestHelpers();
var fakeAttentionWindowManager = {
name: 'AttentionWindowManager',
EVENT_PREFIX: 'attwm',
isActive: function() {},
getActiveWindow: function() {},
setHierarchy: function() {},
setFocus: function() {},
respondToHierarchyEvent: function() {}
};
var fakeAppWindowManager = {
name: 'AppWindowManager',
EVENT_PREFIX: 'awm',
isActive: function() {},
getActiveWindow: function() {},
setHierarchy: function() {},
setFocus: function() {},
respondToHierarchyEvent: function() {}
};
var fakeActionMenu = {
name: 'ActionMenu',
EVENT_PREFIX: 'actionmenu',
isActive: function() {},
getActiveWindow: function() {},
setHierarchy: function() {},
setFocus: function() {},
respondToHierarchyEvent: function() {}
};
var fakeSystemDialogManager = {
name: 'SystemDialogManager',
EVENT_PREFIX: 'sdm',
isActive: function() {},
setHierarchy: function() {},
setFocus: function() {},
respondToHierarchyEvent: function() {}
};
var fakeRocketbar = {
name: 'Rocketbar',
EVENT_PREFIX: 'rb',
isActive: function() {},
getActiveWindow: function() {},
setHierarchy: function() {},
setFocus: function() {},
respondToHierarchyEvent: function() {}
};
var fakeInitLogoHandler = {
name: 'InitLogoHandler',
EVENT_PREFIX: 'il',
isActive: function() {},
setHierarchy: function() {},
setFocus: function() {},
respondToHierarchyEvent: function() {}
};
var fakeTaskManager = {
name: 'TaskManager',
EVENT_PREFIX: 'tm',
isActive: function() {},
setHierarchy: function() {},
setFocus: function() {},
respondToHierarchyEvent: function() {}
};
setup(function() {
subject = BaseModule.instantiate('HierarchyManager');
subject.start();
});
teardown(function() {
subject.stop();
});
suite('Update top most window', function() {
setup(function() {
this.sinon.stub(subject, 'publish');
this.sinon.stub(subject, 'getTopMostWindow').returns(new MockAppWindow());
});
test('should update top most window when window is opened', function() {
window.dispatchEvent(new CustomEvent('windowopened'));
assert.isTrue(subject.publish.calledWith('topmostwindowchanged'));
});
test('should update top most window when window is closed', function() {
window.dispatchEvent(new CustomEvent('windowclosed'));
assert.isTrue(subject.publish.calledWith('topmostwindowchanged'));
});
test('should update top most window when card view is closed', function() {
window.dispatchEvent(new CustomEvent('cardviewclosed'));
assert.isTrue(subject.publish.calledWith('topmostwindowchanged'));
});
});
suite('Get top most window', function() {
setup(function() {
subject.registerHierarchy(fakeAppWindowManager);
subject.registerHierarchy(fakeAttentionWindowManager);
});
teardown(function() {
subject.unregisterHierarchy(fakeAppWindowManager);
subject.unregisterHierarchy(fakeAttentionWindowManager);
});
test('Should get top most window instance ' +
'if there is active window manager and it is having active window',
function() {
var fakeAppWindow = new MockAppWindow();
this.sinon.stub(fakeAppWindowManager, 'getActiveWindow')
.returns(fakeAppWindow);
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(true);
assert.equal(subject.getTopMostWindow(), fakeAppWindow);
var fakeAttentionWindow = new MockAttentionWindow();
this.sinon.stub(fakeAttentionWindowManager, 'getActiveWindow')
.returns(fakeAttentionWindow);
this.sinon.stub(fakeAttentionWindowManager, 'isActive').returns(true);
assert.equal(subject.getTopMostWindow(), fakeAttentionWindow);
});
test('Should get undefined if there is no active window manager',
function() {
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(false);
assert.isUndefined(subject.getTopMostWindow());
});
});
suite('Update Hierarchy', function() {
setup(function() {
subject.registerHierarchy(fakeAppWindowManager);
subject.registerHierarchy(fakeActionMenu);
subject.registerHierarchy(fakeSystemDialogManager);
subject.registerHierarchy(fakeRocketbar);
});
teardown(function() {
subject.unregisterHierarchy(fakeAppWindowManager);
subject.unregisterHierarchy(fakeActionMenu);
subject.unregisterHierarchy(fakeSystemDialogManager);
subject.unregisterHierarchy(fakeRocketbar);
});
test('-activated/-activating/-deactivating/-deactivated',
function() {
subject.registerHierarchy(fakeInitLogoHandler);
var stubILisActive = this.sinon.stub(fakeInitLogoHandler, 'isActive');
stubILisActive.returns(true);
window.dispatchEvent(
new CustomEvent(fakeInitLogoHandler.EVENT_PREFIX + '-activated'));
assert.equal(subject.getTopMostUI(), fakeInitLogoHandler);
subject.unregisterHierarchy(fakeInitLogoHandler);
assert.isNull(subject.getTopMostUI());
var stubAWMisActive = this.sinon.stub(fakeAppWindowManager, 'isActive');
stubAWMisActive.returns(true);
window.dispatchEvent(
new CustomEvent(fakeAppWindowManager.EVENT_PREFIX + '-activated'));
assert.equal(subject.getTopMostUI(), fakeAppWindowManager);
stubAWMisActive.returns(false);
window.dispatchEvent(
new CustomEvent(fakeAppWindowManager.EVENT_PREFIX + '-deactivated'));
assert.isNull(subject.getTopMostUI());
var stubRBisActive = this.sinon.stub(fakeRocketbar, 'isActive');
stubRBisActive.returns(true);
window.dispatchEvent(
new CustomEvent(fakeRocketbar.EVENT_PREFIX + '-activated'));
assert.equal(subject.getTopMostUI(), fakeRocketbar);
stubAWMisActive.returns(true);
window.dispatchEvent(
new CustomEvent(fakeAppWindowManager.EVENT_PREFIX + '-activated'));
assert.equal(subject.getTopMostUI(), fakeRocketbar);
stubRBisActive.returns(false);
window.dispatchEvent(
new CustomEvent(fakeRocketbar.EVENT_PREFIX + '-deactivated'));
assert.equal(subject.getTopMostUI(), fakeAppWindowManager);
var stubAMisActive = this.sinon.stub(fakeActionMenu, 'isActive');
stubAMisActive.returns(true);
window.dispatchEvent(
new CustomEvent(fakeActionMenu.EVENT_PREFIX + '-activated'));
assert.equal(subject.getTopMostUI(), fakeActionMenu);
stubAMisActive.returns(false);
window.dispatchEvent(
new CustomEvent(fakeActionMenu.EVENT_PREFIX + '-deactivated'));
assert.equal(subject.getTopMostUI(), fakeAppWindowManager);
});
});
suite('setHierarchy and setFocus in updateHierarchy', function() {
setup(function() {
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(true);
this.sinon.stub(fakeAppWindowManager, 'setHierarchy');
this.sinon.stub(fakeAppWindowManager, 'setFocus').returns(true);
this.sinon.stub(fakeSystemDialogManager, 'isActive').returns(true);
this.sinon.stub(fakeSystemDialogManager, 'setHierarchy');
this.sinon.stub(fakeSystemDialogManager, 'setFocus');
subject.registerHierarchy(fakeAppWindowManager);
});
teardown(function() {
subject.unregisterHierarchy(fakeAppWindowManager);
subject.unregisterHierarchy(fakeSystemDialogManager);
});
test('should invoke "setHierarchy" of modules', function() {
assert.isTrue(fakeAppWindowManager.setHierarchy.calledWith(true));
fakeAppWindowManager.setHierarchy.reset();
subject.registerHierarchy(fakeSystemDialogManager);
assert.isTrue(fakeAppWindowManager.setHierarchy.calledWith(false));
assert.isTrue(fakeSystemDialogManager.setHierarchy.calledWith(true));
});
test('should invoke "setFocus" of modules', function() {
assert.isTrue(fakeAppWindowManager.setFocus.calledWith(true));
fakeAppWindowManager.setFocus.reset();
fakeSystemDialogManager.setFocus.returns(true);
subject.registerHierarchy(fakeSystemDialogManager);
assert.isTrue(fakeAppWindowManager.setFocus.calledWith(false));
assert.isTrue(fakeSystemDialogManager.setFocus.calledWith(true));
assert.isTrue(fakeSystemDialogManager.setFocus.calledTwice);
});
test('should not blur lower priority module when higher priority module ' +
'is not focused successfully', function() {
fakeAppWindowManager.setFocus.reset();
fakeSystemDialogManager.setFocus.returns(false);
subject.registerHierarchy(fakeSystemDialogManager);
assert.isTrue(fakeSystemDialogManager.setFocus.calledWith(true));
assert.isTrue(fakeSystemDialogManager.setFocus.calledOnce);
assert.isFalse(fakeAppWindowManager.setFocus.called);
});
});
suite('focus request', function() {
test('should not focus when lower priority module ' +
'requests to be focused', function() {
this.sinon.stub(fakeAppWindowManager, 'setHierarchy');
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(true);
this.sinon.stub(fakeSystemDialogManager, 'isActive').returns(true);
this.sinon.stub(fakeSystemDialogManager, 'setHierarchy').returns(true);
subject.registerHierarchy(fakeAppWindowManager);
subject.registerHierarchy(fakeSystemDialogManager);
subject.focus(fakeAppWindowManager);
assert.isTrue(fakeAppWindowManager.setHierarchy.calledWith(false));
});
test('should focus when higher priority module requests to be focused',
function() {
this.sinon.stub(fakeSystemDialogManager, 'setHierarchy');
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(true);
this.sinon.stub(fakeSystemDialogManager, 'isActive').returns(true);
subject.registerHierarchy(fakeAppWindowManager);
subject.registerHierarchy(fakeSystemDialogManager);
subject.focus(fakeSystemDialogManager);
assert.isTrue(fakeSystemDialogManager.setHierarchy.calledWith(true));
});
test('should focus top most without a module', function() {
this.sinon.stub(fakeAppWindowManager, 'setHierarchy');
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(true);
// use registerHierarchy to update top most
subject.registerHierarchy(fakeAppWindowManager);
subject.focus();
assert.isTrue(fakeAppWindowManager.setHierarchy.called);
});
});
suite('unregisterHierarchy', function() {
test('unwatch the hierarchy',
function() {
subject.registerHierarchy(fakeAppWindowManager);
subject.unregisterHierarchy(fakeAppWindowManager);
assert.equal(subject._ui_list.length, 0);
});
});
suite('registerHierarchy', function() {
test('Should update _ui_list and call updateHierarchy when registering',
function() {
this.sinon.stub(subject, 'updateHierarchy');
subject.registerHierarchy(fakeAppWindowManager);
assert.equal(subject._ui_list.length, 1);
assert.isTrue(subject.updateHierarchy.calledOnce);
subject.registerHierarchy(fakeSystemDialogManager);
assert.equal(subject._ui_list.length, 2);
assert.isTrue(subject.updateHierarchy.calledTwice);
subject.registerHierarchy(fakeRocketbar);
assert.equal(subject._ui_list.length, 3);
assert.isTrue(subject.updateHierarchy.calledThrice);
});
});
suite('respondToHierarchyEvent hierarchy events', function() {
setup(function() {
subject.registerHierarchy(fakeSystemDialogManager);
subject.registerHierarchy(fakeRocketbar);
subject.registerHierarchy(fakeActionMenu);
subject.registerHierarchy(fakeTaskManager);
subject.registerHierarchy(fakeAppWindowManager);
subject.registerHierarchy(fakeAttentionWindowManager);
});
teardown(function() {
subject.unregisterHierarchy(fakeSystemDialogManager);
subject.unregisterHierarchy(fakeRocketbar);
subject.unregisterHierarchy(fakeActionMenu);
subject.unregisterHierarchy(fakeTaskManager);
subject.unregisterHierarchy(fakeAppWindowManager);
subject.unregisterHierarchy(fakeAttentionWindowManager);
});
test('Should broadcast event from top to bottom until blocked', function() {
this.sinon.stub(fakeRocketbar, 'isActive').returns(true);
this.sinon.stub(fakeSystemDialogManager, 'isActive').returns(true);
this.sinon.stub(fakeActionMenu, 'isActive').returns(true);
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(true);
this.sinon.stub(fakeTaskManager, 'isActive').returns(true);
this.sinon.stub(fakeAttentionWindowManager, 'isActive').returns(true);
this.sinon.stub(fakeRocketbar,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeSystemDialogManager,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeActionMenu,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeAppWindowManager,
'respondToHierarchyEvent').returns(false);
this.sinon.stub(fakeTaskManager,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeAttentionWindowManager,
'respondToHierarchyEvent').returns(true);
var homeEvt = new CustomEvent('home');
window.dispatchEvent(homeEvt);
assert.isTrue(fakeAttentionWindowManager
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeRocketbar
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeSystemDialogManager
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeActionMenu
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeAppWindowManager
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isFalse(fakeTaskManager
.respondToHierarchyEvent.calledWith(homeEvt));
});
test('Should skip broadcasting if an module is inactive', function() {
this.sinon.stub(fakeRocketbar, 'isActive').returns(true);
this.sinon.stub(fakeSystemDialogManager, 'isActive').returns(true);
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(false);
this.sinon.stub(fakeActionMenu, 'isActive').returns(true);
this.sinon.stub(fakeTaskManager, 'isActive').returns(true);
this.sinon.stub(fakeAttentionWindowManager, 'isActive').returns(true);
this.sinon.stub(fakeRocketbar,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeSystemDialogManager,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeAppWindowManager,
'respondToHierarchyEvent').returns(false);
this.sinon.stub(fakeTaskManager,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeActionMenu,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeAttentionWindowManager,
'respondToHierarchyEvent').returns(true);
var homeEvt = new CustomEvent('home');
window.dispatchEvent(homeEvt);
assert.isTrue(fakeAttentionWindowManager
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeRocketbar
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeActionMenu
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeSystemDialogManager
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isFalse(fakeAppWindowManager
.respondToHierarchyEvent.calledWith(homeEvt));
assert.isTrue(fakeTaskManager
.respondToHierarchyEvent.calledWith(homeEvt));
});
test('Deliver to the last person in the list if not catched',
function() {
this.sinon.stub(fakeRocketbar, 'isActive').returns(false);
this.sinon.stub(fakeSystemDialogManager, 'isActive').returns(false);
this.sinon.stub(fakeAppWindowManager, 'isActive').returns(false);
this.sinon.stub(fakeTaskManager, 'isActive').returns(false);
this.sinon.stub(fakeActionMenu, 'isActive').returns(false);
this.sinon.stub(fakeAttentionWindowManager, 'isActive').returns(false);
this.sinon.stub(fakeRocketbar,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeSystemDialogManager,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeAppWindowManager,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeTaskManager,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeActionMenu,
'respondToHierarchyEvent').returns(true);
this.sinon.stub(fakeAttentionWindowManager,
'respondToHierarchyEvent').returns(true);
var holdhomeEvt = new CustomEvent('holdhome');
window.dispatchEvent(holdhomeEvt);
assert.isFalse(fakeAttentionWindowManager
.respondToHierarchyEvent.calledWith(holdhomeEvt));
assert.isFalse(fakeRocketbar
.respondToHierarchyEvent.calledWith(holdhomeEvt));
assert.isFalse(fakeSystemDialogManager
.respondToHierarchyEvent.calledWith(holdhomeEvt));
assert.isFalse(fakeActionMenu
.respondToHierarchyEvent.calledWith(holdhomeEvt));
assert.isFalse(fakeAppWindowManager
.respondToHierarchyEvent.calledWith(holdhomeEvt));
assert.isTrue(fakeTaskManager
.respondToHierarchyEvent.calledWith(holdhomeEvt));
});
});
});