VulpesOS/gaia/apps/system/test/unit/rocketbar_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

1077 lines
35 KiB
JavaScript
Executable file

'use strict';
/* global Rocketbar, MocksHelper, MockIACPort, MockSearchWindow,
MockService, MockPromise, MockAppWindow, MockUtilityTray */
require('/js/browser.js');
require('/js/browser_config_helper.js');
require('/shared/js/event_safety.js');
requireApp('system/test/unit/mock_app_window.js');
requireApp('system/test/unit/mock_search_window.js');
requireApp('system/shared/test/unit/mocks/mock_settings_listener.js');
requireApp('system/shared/test/unit/mocks/mock_settings_url.js');
requireApp('system/shared/test/unit/mocks/mock_service.js');
requireApp('system/shared/test/unit/mocks/mock_promise.js');
requireApp('system/test/unit/mock_iac_handler.js');
requireApp('system/test/unit/mock_utility_tray.js');
var mocksForRocketbar = new MocksHelper([
'AppWindow',
'SearchWindow',
'SettingsListener',
'SettingsURL',
'Service',
'IACPort',
'UtilityTray'
]).init();
suite('system/Rocketbar', function() {
mocksForRocketbar.attachTestHelpers();
var stubById;
var subject;
setup(function(done) {
this.sinon.useFakeTimers();
stubById = this.sinon.stub(document, 'getElementById', function(id) {
if (id == 'rocketbar-input') {
return document.createElement('input');
} else {
return document.createElement('div');
}
});
requireApp('system/js/rocketbar.js', function() {
subject = new Rocketbar();
subject.start();
subject._port = MockIACPort;
done();
});
});
teardown(function() {
stubById.restore();
MockIACPort.mTearDown();
subject._port = null;
});
suite('Hierarchy functions', function() {
test('setHierarchy', function() {
var searchWindow = new MockSearchWindow();
subject.searchWindow = searchWindow;
this.sinon.stub(searchWindow, 'setVisibleForScreenReader');
subject.setHierarchy(false);
assert.isTrue(searchWindow.setVisibleForScreenReader.calledWith(false));
searchWindow.setVisibleForScreenReader.reset();
subject.setHierarchy(true);
assert.isTrue(searchWindow.setVisibleForScreenReader.calledWith(true));
});
test('setFocus', function() {
var searchWindow = new MockSearchWindow();
subject.searchWindow = searchWindow;
this.sinon.stub(subject, 'focus');
subject.setFocus(true);
assert.isTrue(subject.focus.called);
});
test('Should register hierarchy on start', function() {
this.sinon.stub(MockService, 'request');
subject.start();
assert.isTrue(
MockService.request.calledWith('registerHierarchy', subject));
});
test('isActive', function() {
subject.start();
assert.isFalse(subject.isActive());
subject.activate();
assert.isTrue(subject.isActive());
});
test('Should publish activated when search is loaded and transitioned',
function() {
subject.start();
var fakePromise = new MockPromise();
this.sinon.stub(subject, 'loadSearchApp').returns(fakePromise);
subject.activate();
this.sinon.stub(subject, 'publish');
subject.backdrop.dispatchEvent(new CustomEvent('transitionend'));
fakePromise.mFulfillToValue();
assert.isTrue(subject.publish.calledWith('-activated'));
});
test('Should publish deactivated when closing transition ends',
function() {
subject.start();
subject.activate();
subject.deactivate();
this.sinon.stub(subject, 'publish');
subject.backdrop.dispatchEvent(new CustomEvent('transitionend'));
assert.isTrue(subject.publish.calledWith('-deactivated'));
});
test('Should publish activating when activate is called', function() {
subject.start();
this.sinon.stub(subject, 'publish');
subject.activate();
assert.isTrue(subject.publish.calledWith('-activating'));
});
test('Should publish deactivating when deactivate is called', function() {
subject.start();
this.sinon.stub(subject, 'publish');
subject.activate();
subject.deactivate();
assert.isTrue(subject.publish.calledWith('-deactivating'));
});
test('Should get search window instance if we are active', function() {
var searchWindow = new MockSearchWindow();
subject.searchWindow = searchWindow;
subject.activate();
assert.equal(subject.getActiveWindow(), searchWindow);
});
test('Should get search window instance if we are inactive', function() {
subject.deactivate();
assert.isNull(subject.getActiveWindow());
});
});
test('start()', function() {
var addEventListenersStub = this.sinon.stub(subject,
'addEventListeners');
subject.start();
assert.ok(addEventListenersStub.calledOnce);
assert.ok(subject.enabled);
addEventListenersStub.restore();
});
test('addEventListeners()', function() {
var windowAddEventListenerStub = this.sinon.stub(window,
'addEventListener');
var rocketbarAddEventListenerStub = this.sinon.stub(subject.rocketbar,
'addEventListener');
var inputAddEventListenerStub = this.sinon.stub(subject.input,
'addEventListener');
var formAddEventListenerStub = this.sinon.stub(subject.form,
'addEventListener');
subject.addEventListeners();
assert.ok(windowAddEventListenerStub.calledWith('apploading'));
assert.ok(windowAddEventListenerStub.calledWith('apptitlechange'));
assert.ok(windowAddEventListenerStub.calledWith('appopened'));
var trayOpenedEvent = 'utilitytray-overlayopening';
assert.ok(windowAddEventListenerStub.calledWith(trayOpenedEvent));
assert.ok(inputAddEventListenerStub.calledWith('blur'));
assert.ok(inputAddEventListenerStub.calledWith('input'));
assert.ok(formAddEventListenerStub.calledWith('submit'));
assert.ok(windowAddEventListenerStub.calledWith('iac-search-results'));
windowAddEventListenerStub.restore();
rocketbarAddEventListenerStub.restore();
inputAddEventListenerStub.restore();
formAddEventListenerStub.restore();
});
test('showResults()', function() {
subject.results.classList.add('hidden');
subject.showResults();
assert.equal(subject.results.classList.contains('hidden'), false);
});
test('hideResults()', function() {
subject.activate();
var stub = this.sinon.stub(subject.searchWindow, 'hideContextMenu');
subject.hideResults();
assert.ok(subject.results.classList.contains('hidden'));
assert.ok(MockIACPort.mNumberOfMessages() == 1);
sinon.assert.calledOnce(stub);
});
test('selectAll()', function() {
var stub = this.sinon.stub(subject.input, 'setSelectionRange');
subject.selectAll();
sinon.assert.calledOnce(stub);
stub.restore();
});
test('focus()', function() {
var loadSearchAppStub = this.sinon.stub(subject, 'loadSearchApp')
.returns(Promise.resolve());
subject.form.classList.add('hidden');
subject.activate();
subject.focus();
assert.ok(subject.rocketbar.classList.contains('active'));
assert.equal(subject.form.classList.contains('hidden'), false);
assert.ok(subject.screen.classList.contains('rocketbar-focused'));
assert.ok(subject.active);
assert.ok(loadSearchAppStub.calledOnce);
loadSearchAppStub.restore();
});
test('activate() - when isClosing is true', function(done) {
subject.isClosing = true;
// We should reject the promise when trying to activate during a close.
subject.activate().then(function(){}, done);
});
test('activate() - when isClosing is false', function(done) {
subject.isClosing = false;
// Set the rocketbar to active so we have an immediate promise resolution.
subject.active = true;
subject.activate().then(done);
});
test('blur() - results hidden', function() {
subject.results.classList.add('hidden');
subject.active = true;
subject.deactivate();
assert.ok(subject.form.classList.contains('hidden'));
assert.ok(!subject.screen.classList.contains('rocketbar-focused'));
assert.equal(subject.active, false);
assert.ok(!subject.rocketbar.classList.contains('active'));
});
test('blur() - results shown', function() {
subject.deactivate();
assert.equal(subject.form.classList.contains('hidden'), false);
});
test('handleEvent() - attentionopening', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'attentionopening'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - attentionopened', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'attentionopened'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - simlockrequestfocus', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'simlockrequestfocus'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - apploading', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
// Bug 1071953 - Not called when stayBackground is true.
var event1 = {type: 'apploading', detail: {
stayBackground: true
}};
subject.handleEvent(event1);
assert.ok(hideResultsStub.notCalled);
assert.ok(deactivateStub.notCalled);
var event2 = {type: 'apploading'};
subject.handleEvent(event2);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - appforeground', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'appforeground'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - appopened', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'appopened'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - activityrequesting', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'activityrequesting'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - utilitytray-overlayopening', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'utilitytray-overlayopening'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - cardviewbeforeshow', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'cardviewbeforeshow'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - launchapp', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'launchapp'};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - launchapp /w background', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'launchapp', detail: {
stayBackground: true
}};
subject.handleEvent(event);
assert.ok(hideResultsStub.notCalled);
assert.ok(deactivateStub.notCalled);
});
test('handleEvent() - lockscreen-appopened', function() {
var handleLockStub = this.sinon.stub(subject, 'handleLock');
var event = {type: 'lockscreen-appopened'};
subject.handleEvent(event);
assert.ok(handleLockStub.calledOnce);
});
test('handleEvent() - focus', function() {
var handleFocusStub = this.sinon.stub(subject, 'handleFocus');
var event = {type: 'focus'};
subject.handleEvent(event);
assert.ok(handleFocusStub.calledOnce);
});
test('handleEvent() - home', function() {
var handleHomeStub = this.sinon.stub(subject, '_handle_home');
var event = {type: 'home'};
this.sinon.stub(subject, 'isActive').returns(true);
subject.respondToHierarchyEvent(event);
assert.ok(handleHomeStub.calledOnce);
});
test('handleEvent() - blur', function() {
var handleBlurStub = this.sinon.stub(subject, 'handleBlur');
var event = {type: 'blur'};
subject.handleEvent(event);
assert.ok(handleBlurStub.calledOnce);
});
test('handleEvent() - input', function() {
var handleInputStub = this.sinon.stub(subject, 'handleInput');
var event = {type: 'input'};
subject.handleEvent(event);
assert.ok(handleInputStub.calledOnce);
});
test('handleEvent() - click cancel button', function() {
var handleCancelStub = this.sinon.stub(subject, 'handleCancel');
var event = {type: 'click', target: subject.cancel};
subject.handleEvent(event);
assert.ok(handleCancelStub.calledOnce);
});
test('handleEvent() - click clear button', function() {
var setInputStub = this.sinon.stub(subject, 'setInput');
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var focusStub = this.sinon.stub(subject, 'focus');
var event = {type: 'click', target: subject.clearBtn};
subject.handleEvent(event);
assert.ok(setInputStub.calledWith(''));
assert.ok(hideResultsStub.calledOnce);
assert.ok(focusStub.calledOnce);
});
test('handleEvent() - click backdrop', function() {
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var event = {type: 'click', target: subject.backdrop};
subject.handleEvent(event);
assert.ok(hideResultsStub.calledOnce);
assert.ok(deactivateStub.calledOnce);
});
test('handleEvent() - launchactivity', function() {
var handleActivityStub = this.sinon.stub(subject, '_handle_launchactivity');
var event = {type: 'launchactivity'};
subject.respondToHierarchyEvent(event);
assert.ok(handleActivityStub.calledOnce);
});
test('handleEvent() - searchterminated', function() {
var handleSearchTerminatedStub =
this.sinon.stub(subject, 'handleSearchTerminated');
var event = {type: 'searchterminated'};
subject.handleEvent(event);
assert.ok(handleSearchTerminatedStub.calledOnce);
});
test('handleEvent() - submit', function() {
var handleSubmitStub = this.sinon.stub(subject, 'handleSubmit');
var event = {type: 'submit'};
subject.handleEvent(event);
assert.ok(handleSubmitStub.calledOnce);
});
test('handleEvent() - iac-search-results', function() {
var handleSearchMessageStub =
this.sinon.stub(subject, 'handleSearchMessage');
var event = {type: 'iac-search-results'};
subject.handleEvent(event);
assert.ok(handleSearchMessageStub.calledOnce);
});
test('handleEvent() - open-app', function() {
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
// Does not hide with frontWindow
subject.searchWindow = {
frontWindow: {}
};
window.dispatchEvent(new CustomEvent('open-app'));
assert.ok(deactivateStub.notCalled);
assert.ok(hideResultsStub.notCalled);
subject.searchWindow = null;
// Bug 1071953 - Not called when showApp is false.
window.dispatchEvent(new CustomEvent('open-app', {
detail: {
showApp: false
}
}));
assert.ok(deactivateStub.notCalled);
assert.ok(hideResultsStub.notCalled);
// Does not hide if the search window is not open.
window.dispatchEvent(new CustomEvent('searchclosed'));
window.dispatchEvent(new CustomEvent('open-app'));
assert.ok(deactivateStub.notCalled);
assert.ok(hideResultsStub.notCalled);
// Hides if the search window is open.
window.dispatchEvent(new CustomEvent('searchopened'));
window.dispatchEvent(new CustomEvent('open-app'));
assert.ok(deactivateStub.calledOnce);
assert.ok(hideResultsStub.calledOnce);
});
test('handleEvent() - permissiondialoghide: active', function() {
var focusStub = this.sinon.stub(subject, 'focus');
var event = {type: 'permissiondialoghide'};
subject.active = true;
subject.handleEvent(event);
assert.ok(focusStub.calledOnce);
});
test('handleEvent() - permissiondialoghide: inactive', function() {
var focusStub = this.sinon.stub(subject, 'focus');
var event = {type: 'permissiondialoghide'};
subject.active = false;
subject.handleEvent(event);
assert.isFalse(focusStub.called);
});
test('handleEvent() - global-search-request: is app', function() {
var activeApp = {
config: {url: 'app.url'},
isBrowser: function() {},
isActive: function() { return true; }
};
MockService.mockQueryWith('AppWindowManager.getActiveWindow', activeApp);
this.sinon.stub(activeApp, 'isBrowser').returns(true);
var setInputStub = this.sinon.stub(subject, 'setInput');
var activateStub = this.sinon.stub(subject, 'activate')
.returns(Promise.resolve());
var event = {type: 'global-search-request'};
subject.handleEvent(event);
assert.ok(setInputStub.calledWith('app.url'));
assert.ok(activateStub.calledOnce);
});
test('handleEvent() - global-search-request: inactive app', function() {
var activeApp = {
config: {url: 'app.url'},
isBrowser: function() {},
isActive: function() { return false; }
};
MockService.mockQueryWith('AppWindowManager.getActiveWindow', activeApp);
this.sinon.stub(activeApp, 'isBrowser').returns(true);
var setInputStub = this.sinon.stub(subject, 'setInput');
var activateStub = this.sinon.stub(subject, 'activate');
var event = {type: 'global-search-request'};
subject.handleEvent(event);
assert.ok(setInputStub.notCalled);
assert.ok(activateStub.notCalled);
});
test('handleEvent() - global-search-request: non app', function(done) {
var fakeTimer = this.sinon.useFakeTimers();
var activeApp = {
config: {url: 'app.url'},
isBrowser: function() {
return true;
},
appChrome: {
maximize: function() {},
isMaximized: function() {}
},
isActive: function() { return true; }
};
MockService.mockQueryWith('AppWindowManager.getActiveWindow', activeApp);
var maximize = this.sinon.spy(activeApp.appChrome, 'maximize');
var resolved = Promise.resolve();
this.sinon.stub(subject, 'activate', function() {
return resolved;
});
this.sinon.spy(subject, 'hideResults');
this.sinon.spy(subject, 'focus');
this.sinon.spy(subject, 'selectAll');
this.sinon.spy(subject, 'setInput');
var event = {type: 'global-search-request'};
subject.handleEvent(event);
maximize.getCall(0).args[0]();
resolved.then(function() {
this.sinon.clock.tick();
sinon.assert.callOrder(
subject.setInput,
activeApp.appChrome.maximize,
subject.activate,
subject.hideResults,
subject.focus,
subject.selectAll);
fakeTimer.restore();
done();
}.bind(this));
});
test('handleEvent() - global-search-request: ' +
'appChrome.maximize is called for apps', function(done) {
var activeApp = {
config: {url: 'app.url'},
isBrowser: function() {
return false;
},
appChrome: {
maximize: function() {},
isMaximized: function() {}
},
isActive: function() { return true; }
};
MockService.mockQueryWith('AppWindowManager.getActiveWindow', activeApp);
var maximize = this.sinon.spy(activeApp.appChrome, 'maximize');
var resolved = Promise.resolve();
this.sinon.stub(subject, 'activate', function() {
return resolved;
});
this.sinon.spy(subject, 'focus');
var event = {type: 'global-search-request'};
subject.handleEvent(event);
maximize.getCall(0).args[0]();
resolved.then(function() {
sinon.assert.callOrder(
activeApp.appChrome.maximize,
subject.activate,
subject.focus);
done();
});
});
suite('handle hierarchy event - value selector', function() {
test('Value selector event with front window',
function() {
var searchWindow = new MockSearchWindow();
subject.searchWindow = searchWindow;
var app1 = new MockAppWindow();
this.sinon.stub(searchWindow, 'getTopMostWindow').returns(app1);
this.sinon.stub(app1, 'broadcast');
var respond =
subject.respondToHierarchyEvent({
type: 'inputfocus',
detail: {
type: 'input',
inputType: 'text'
}
});
assert.isFalse(respond);
assert.isTrue(app1.broadcast.calledWith('inputfocus'));
});
test('Value selector event without front window',
function() {
var searchWindow = new MockSearchWindow();
subject.searchWindow = searchWindow;
this.sinon.stub(searchWindow, 'broadcast');
var respond =
subject.respondToHierarchyEvent({
type: 'inputfocus',
detail: {
type: 'input',
inputType: 'text'
}
});
assert.isFalse(respond);
assert.isTrue(
searchWindow.broadcast.calledWith('inputfocus'));
});
test('Value selector event without search window',
function() {
subject.searchWindow = null;
var respond =
subject.respondToHierarchyEvent({
type: 'inputfocus',
detail: {
type: 'input',
inputType: 'text'
}
});
assert.isTrue(respond);
});
});
suite('handle hierarchy event - system-resize', function() {
setup(function() {
subject.activate();
});
teardown(function() {
subject.searchWindow.frontWindow = undefined;
});
test('Search window with front window', function() {
subject.searchWindow.frontWindow = {
resize: function() {}
};
var stub = this.sinon.stub(subject.searchWindow.frontWindow, 'resize')
.returns({ stub: 'promise'});
var stubWaitUntil = this.sinon.stub();
var evt = new CustomEvent('system-resize', {
detail: {
waitUntil: stubWaitUntil
}
});
var stopsPropagation = subject.respondToHierarchyEvent(evt);
assert.ok(stub.calledOnce);
assert.ok(stubWaitUntil.calledWith({ stub: 'promise' }));
assert.isFalse(stopsPropagation);
stub.restore();
});
test('Search window without front window', function() {
var stopsPropagation =
subject.respondToHierarchyEvent(new CustomEvent('system-resize'));
assert.isFalse(stopsPropagation);
});
test('Rocketbar is inactive', function() {
subject.deactivate();
var stopsPropagation =
subject.respondToHierarchyEvent(new CustomEvent('system-resize'));
assert.isTrue(stopsPropagation);
});
});
test('_handle_home', function() {
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
this.sinon.stub(subject, 'isActive').returns(true);
subject._handle_home();
assert.ok(deactivateStub.calledOnce);
assert.ok(hideResultsStub.calledOnce);
});
test('_handle_home - during activate', function() {
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
this.sinon.stub(subject, 'isActive').returns(true);
var fakePromise = new MockPromise();
subject._activateCall = fakePromise;
subject._handle_home();
fakePromise.mFulfillToValue();
assert.ok(deactivateStub.calledOnce);
assert.ok(hideResultsStub.calledOnce);
});
suite('handleInput()', function() {
var showResultsStub, hideResultsStub, closeSearchStub;
setup(function() {
MockService.mockQueryWith('AppWindowManager.getActiveWindow', {
isPrivateBrowser: function() {
return false;
}
});
showResultsStub = this.sinon.stub(subject, 'showResults');
hideResultsStub = this.sinon.stub(subject, 'hideResults');
closeSearchStub = this.sinon.stub(subject, '_closeSearch');
});
test('With input', function() {
subject.input.value = 'abc';
subject.results.classList.add('hidden');
subject.handleInput();
assert.ok(showResultsStub.calledOnce);
assert.ok(MockIACPort.mNumberOfMessages() == 1);
});
test('With no input', function() {
subject.input.value = '';
subject.results.classList.remove('hidden');
subject.handleInput();
assert.ok(hideResultsStub.calledOnce);
assert.isFalse(closeSearchStub.calledOnce);
});
test('With utility tray shown', function() {
MockUtilityTray.shown = true;
subject.input.value = 'abc';
subject.results.classList.remove('hidden');
subject.handleInput();
assert.ok(closeSearchStub.calledOnce);
MockUtilityTray.shown = false;
});
});
test('handleSubmit()', function(done) {
MockService.mockQueryWith('AppWindowManager.getActiveWindow', {
isPrivateBrowser: function() {
return false;
}
});
var event = {
'preventDefault': function() {
done();
}
};
var stubBlur = this.sinon.stub(subject.input, 'blur');
subject.handleSubmit(event);
assert.ok(MockIACPort.mNumberOfMessages() == 1);
assert.ok(stubBlur.calledOnce);
});
test('handleCancel()', function() {
var deactivateStub = this.sinon.stub(subject, 'deactivate');
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
subject.handleCancel();
assert.ok(deactivateStub.calledOnce);
assert.ok(hideResultsStub.calledOnce);
});
test('loadSearchApp()', function() {
var initSearchConnectionStub = this.sinon.stub(subject,
'initSearchConnection');
subject._searchAppURL = 'http://search.example.com/';
subject._searchManifestURL = 'http://search.example.com/manifest.webapp';
// searchFrame DOM
subject.loadSearchApp();
assert.ok(initSearchConnectionStub.calledOnce);
initSearchConnectionStub.restore();
});
test('initSearchConnection()', function(done) {
var handleSearchMessageStub = this.sinon.stub(subject,
'handleSearchMessage');
subject._pendingMessage = 'hi';
var realMozApps = navigator.mozApps;
navigator.mozApps = {};
var app = { result: {
'connect': function() {
return {
'then': function(success, failure) {
var ports = ['abc'];
success(ports);
}
};
}
}};
subject._port = null;
navigator.mozApps.getSelf = function() { return app; };
subject.initSearchConnection().then(() => {
assert.equal(subject._port, 'abc');
assert.equal(subject._pendingMessage, null);
assert.ok(handleSearchMessageStub.calledOnce);
navigator.mozApps = realMozApps;
handleSearchMessageStub.restore();
done();
});
app.onsuccess({target: app});
});
test('handleSearchMessage()', function() {
MockService.mockQueryWith('AppWindowManager.getActiveWindow', {
isPrivateBrowser: function() {
return false;
}
});
var initSearchConnectionStub = this.sinon.stub(subject,
'initSearchConnection');
var hideResultsStub = this.sinon.stub(subject, 'hideResults');
// Input message
var event = {
type: 'iac-search-results',
detail: {
action: 'input',
input: 'http://example.com'
}
};
var spy = sinon.spy(subject, 'focus');
subject.handleSearchMessage(event);
assert.equal(subject.input.value, 'http://example.com');
assert.isTrue(spy.called);
spy.restore();
// Hide message
event = {
type: 'iac-search-results',
detail: {
action: 'hide'
}
};
subject.handleSearchMessage(event);
assert.ok(hideResultsStub.calledOnce);
// private-window message
var eventStub = sinon.spy(window, 'dispatchEvent');
subject.handleSearchMessage({
type: 'iac-search-results',
detail: {
action: 'private-window'
}
});
assert.equal(eventStub.getCall(0).args[0].type, 'new-private-window');
// No _port
subject._port = null;
subject.handleSearchMessage(event);
assert.equal(subject._pendingMessage, event);
assert.ok(initSearchConnectionStub.calledOnce);
initSearchConnectionStub.restore();
hideResultsStub.restore();
eventStub.restore();
});
test('updateSearchIndex()', function() {
var postMessageStub = this.sinon.stub(subject._port, 'postMessage');
subject.updateSearchIndex();
assert.ok(postMessageStub.calledOnce);
postMessageStub.restore();
});
test('handleActivity()', function() {
subject.loadSearchApp();
var stubDispatchEvent = this.sinon.stub(subject.searchWindow,
'broadcast');
subject.respondToHierarchyEvent({
type: 'launchactivity',
detail: {
isActivity: true,
inline: true,
parentApp: subject.searchWindow.manifestURL
},
stopImmediatePropagation: function() {}
});
assert.isTrue(stubDispatchEvent.called);
assert.equal(stubDispatchEvent.getCall(0).args[0], 'launchactivity');
assert.equal(stubDispatchEvent.getCall(0).args[1].isActivity, true);
});
test('handleSearchTerminated() - calls render after crash', function() {
subject.start();
subject._searchAppURL = 'http://search.example.com/';
subject._searchManifestURL = 'http://search.example.com/manifest.webapp';
subject.searchWindow = null;
var spy = this.sinon.spy(window, 'MockSearchWindow');
subject.loadSearchApp();
assert.ok(spy.calledWithNew);
spy.restore();
// Dispatch a crash event.
window.dispatchEvent(new CustomEvent('searchterminated'));
assert.equal(subject.searchWindow, null);
assert.equal(subject._port, null);
subject.loadSearchApp();
assert.ok(spy.calledWithNew);
assert.ok(subject.searchWindow instanceof MockSearchWindow);
assert.equal(subject._port, null);
});
test('open', function() {
subject.activate();
var openStub = this.sinon.stub(subject.searchWindow, 'open');
var closeStub = this.sinon.stub(subject.searchWindow, 'close');
subject.showResults();
assert.isTrue(openStub.called);
subject.hideResults();
assert.isTrue(closeStub.called);
});
test('search window should not be opened again if it is dead', function() {
subject.activate();
this.sinon.stub(subject.searchWindow, 'isDead').returns(true);
var openStub = this.sinon.stub(subject.searchWindow, 'open');
subject.showResults();
assert.isFalse(openStub.called);
});
test('focus after geolocation hidden', function() {
var focusStub = this.sinon.stub(subject, 'focus');
subject.activate();
subject.active = true;
subject.handleEvent({type: 'permissiondialoghide'});
assert.ok(focusStub.calledOnce);
focusStub.restore();
});
test('Dont clear input when search app crashes', function() {
subject.input.value = 'value to not clear';
window.dispatchEvent(new CustomEvent('searchterminated'));
assert.equal(subject.input.value, 'value to not clear');
});
test('focus on render after a tick', function(done) {
var focusStub = this.sinon.stub(subject, 'focus');
// Set the rocketbar to active to trigger an immediate promise resolution.
subject.active = true;
var activation = subject.activate();
subject.handleSearchMessage({detail: {action: 'render'}});
sinon.assert.notCalled(focusStub);
activation.then(function() {
sinon.assert.calledOnce(focusStub);
done();
});
});
test('calls _closeSearch if the utility tray is active', function(done) {
subject.active = true;
MockUtilityTray.shown = true;
var stub = this.sinon.stub(subject, '_closeSearch');
subject.activate().then(() => {
assert.ok(stub.calledOnce);
MockUtilityTray.shown = false;
done();
});
});
suite('activate with a transition', function() {
test('done after transition and search app load', function(done) {
this.sinon.stub(subject, 'loadSearchApp').returns(Promise.resolve());
subject.activate().then(done);
subject.backdrop.dispatchEvent(new CustomEvent('transitionend'));
});
test('done after safety timeout and search app load', function(done) {
this.sinon.stub(subject, 'loadSearchApp').returns(Promise.resolve());
subject.activate().then(done);
this.sinon.clock.tick(500);
});
});
suite('deactivate with a transition', function() {
setup(function() {
subject.active = true;
subject.form.classList.remove('hidden');
subject.rocketbar.classList.add('active');
subject.focused = false;
});
test('should update the css classed properly', function() {
subject.deactivate();
assert.isTrue(subject.form.classList.contains('hidden'));
assert.isFalse(subject.rocketbar.classList.contains('active'));
});
test('should publish rocketbar-overlayclosed after the transition',
function(done) {
var published = false;
window.addEventListener('rocketbar-overlayclosed', function gotIt() {
published = true;
window.removeEventListener('rocketbar-overlayclosed', gotIt);
assert.ok(published);
done();
});
subject.deactivate();
assert.isFalse(published);
subject.backdrop.dispatchEvent(new CustomEvent('transitionend'));
});
suite('when the keyboard is displayed', function() {
setup(function() {
subject.screen.classList.add('rocketbar-focused');
subject.focused = true;
this.sinon.spy(subject, 'blur');
});
test('should blur, wait for the keyboard to leave, then exit',
function(done) {
window.addEventListener('rocketbar-overlayclosed', function gotIt() {
window.removeEventListener('rocketbar-overlayclosed', gotIt);
done();
});
subject.deactivate();
sinon.assert.calledOnce(subject.blur);
assert.isTrue(subject.screen.classList.contains('rocketbar-focused'));
window.dispatchEvent(new CustomEvent('keyboardhidden'));
assert.isFalse(subject.screen.classList.contains('rocketbar-focused'));
subject.backdrop.dispatchEvent(new CustomEvent('transitionend'));
});
});
});
});