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

210 lines
6.3 KiB
JavaScript
Executable file

'use strict';
requireApp('system/js/utility_tray_motion.js');
requireApp('system/js/utility_tray.js');
/* global UtilityTray */
/**
* This unit test suite only sanity-checks the basic mechanics of the tray.
* Integration tests check tray motion and state more thoroughly, as well as
* proper event handling and dispatching.
*/
suite('UtilityTrayMotion', function() {
var SCROLL_TOP_MAX = 100;
var motion, el;
window.Service = {
locked: false,
isFtuRunning: false,
getTopMostWindow: null,
query(value) {
return this[value];
}
};
setup(() => {
el = document.createElement('div');
var child = document.createElement('div');
child.style.cssText = `height: ${SCROLL_TOP_MAX * 2}px;`;
el.appendChild(child);
el.style.cssText = `height: ${SCROLL_TOP_MAX}px; overflow-y: scroll`;
document.body.appendChild(el);
motion = new window.UtilityTrayMotion(el);
});
function openTray(done) {
motion.open();
var listener = () => {
assert.notEqual(motion.state, 'closing');
assert.notEqual(motion.state, 'closed');
if (motion.state === 'open') {
el.removeEventListener('tray-motion-state', listener);
assert.equal(el.scrollTop, 0);
done();
}
};
el.addEventListener('tray-motion-state', listener);
}
test('open', function(done) {
assert.equal(el.scrollTop, SCROLL_TOP_MAX);
openTray(done);
});
test('open and close: check state and motion events', function(done) {
openTray(() => {
assert.equal(el.scrollTop, 0);
motion.close();
var fn = () => {
assert.notEqual(motion.state, 'opening');
assert.notEqual(motion.state, 'open');
if (motion.state === 'closed') {
assert.equal(el.scrollTop, SCROLL_TOP_MAX);
el.removeEventListener('tray-motion-state', fn);
done();
}
};
el.addEventListener('tray-motion-state', fn);
});
});
test('handling timeout event received while open', function(done) {
// If the tray is already open, another 'timeout' event should leave
// the tray open as-is, not attempt to close it.
openTray(() => {
assert.equal(el.scrollTop, 0);
motion.markPosition('timeout');
assert.equal(motion.state, 'open');
done();
});
});
test('Closes in response to window resize when closed', function() {
var stub = sinon.stub(motion, 'markPosition');
window.dispatchEvent(new CustomEvent('resize'));
assert.isTrue(stub.called);
assert.equal(stub.firstCall.args[0], 'resize');
});
test('Opens in response to window resize when open', function(done) {
openTray(() => {
var stub = sinon.stub(motion, 'markPosition');
window.dispatchEvent(new CustomEvent('resize'));
assert.isTrue(stub.called);
assert.equal(stub.firstCall.args[0], 'resize');
done();
});
});
test('reliablyScrollTo', function() {
var stub = sinon.stub(motion.el, 'scrollTo');
motion.reliablyScrollTo(0);
motion.reliablyScrollTo(10);
motion.reliablyScrollTo(10);
assert.isTrue(stub.calledThrice);
assert.deepEqual(stub.firstCall.args[0].top, 0);
assert.deepEqual(stub.secondCall.args[0].top, 10);
assert.deepEqual(stub.thirdCall.args[0].top, 10);
assert.deepEqual(stub.firstCall.args[0].behavior, 'smooth');
assert.deepEqual(stub.secondCall.args[0].behavior, 'smooth');
assert.deepEqual(stub.thirdCall.args[0].behavior, 'auto');
});
});
suite('UtilityTray', function() {
test('Hides when responding to certain events', function() {
[
'emergencyalert',
'displayapp',
'keyboardchanged',
'keyboardchangecanceled',
'simlockshow',
'appopening',
'activityopening',
'sheets-gesture-begin',
'attentionopened',
'attentionwill-become-active',
'imemenushow'
].forEach(function(eventType) {
var hideFn = sinon.stub(window.UtilityTray, 'hide');
window.UtilityTray.handleEvent(new CustomEvent(eventType));
assert.isTrue(hideFn.calledOnce, eventType + ' causes hide');
hideFn.restore();
});
});
suite('Hiearchy events support', function() {
test('should have a name', function() {
assert.equal(UtilityTray.name, 'UtilityTray');
});
test('should expose |isActive|', function() {
UtilityTray.shown = true;
assert.isTrue(UtilityTray.isActive());
UtilityTray.shown = false;
assert.isFalse(UtilityTray.isActive());
});
test('should consume home to close when opened', function() {
UtilityTray.shown = true;
this.sinon.stub(UtilityTray, 'hide');
var result = UtilityTray.respondToHierarchyEvent(new CustomEvent('home'));
assert.isFalse(result);
sinon.assert.calledOnce(UtilityTray.hide);
});
test('should ignore home when closed', function() {
UtilityTray.shown = false;
this.sinon.stub(UtilityTray, 'hide');
var result = UtilityTray.respondToHierarchyEvent(new CustomEvent('home'));
assert.isTrue(result);
sinon.assert.notCalled(UtilityTray.hide);
});
});
});
suite('Notification Scroll Handling: ', function() {
var tray;
setup(function() {
tray = window.UtilityTray;
// Using fake elements here to make it easy to set `offsetTop`.
tray.notificationsContainer = {
style: document.createElement('div').style,
};
tray.footerContainer = {
style: document.createElement('div').style,
};
tray.nestedScrollInterceptor = document.createElement('div');
});
test('Notifications max-height adjusts to fit above footer', function() {
tray.notificationsContainer.offsetTop = 100;
tray.footerContainer.offsetTop = 400;
tray.recalculateNotificationsContainerHeight();
assert.equal(tray.notificationsContainer.style.maxHeight, '300px');
});
test('Scroll interceptor => overflow:scroll when notifications can scroll',
function() {
tray.notificationsContainer.scrollTopMax = 100;
tray.recalculateNotificationsContainerHeight();
assert.equal(tray.nestedScrollInterceptor.style.overflowY, 'scroll');
});
test('Scroll interceptor => overflow:hidden when notifications do not scroll',
function() {
tray.notificationsContainer.scrollTopMax = 0;
tray.recalculateNotificationsContainerHeight();
assert.equal(tray.nestedScrollInterceptor.style.overflowY, 'hidden');
});
});