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

483 lines
16 KiB
JavaScript
Executable file

'use strict';
/* global MocksHelper */
/* global MockStackManager */
/* global SheetsTransition */
requireApp('system/js/sheets_transition.js');
requireApp('system/shared/test/unit/mocks/mock_service.js');
requireApp('system/test/unit/mock_stack_manager.js');
requireApp('system/shared/test/unit/mocks/mock_settings_listener.js');
var mocksForSheetsTransition = new MocksHelper([
'Service',
'StackManager',
'SettingsListener'
]).init();
suite('system/SheetsTransition >', function() {
mocksForSheetsTransition.attachTestHelpers();
var dialer = {
origin: 'app://dialer.gaiamobile.org',
broadcast: function() {},
setNFCFocus: function() {}
};
var dialerFrame;
var settings = {
origin: 'app://settings.gaiamobile.org',
broadcast: function() {},
setNFCFocus: function() {}
};
var settingsFrame;
var contacts = {
origin: 'app://contacts.gaiamobile.org',
broadcast: function() {},
setNFCFocus: function() {}
};
var contactsFrame;
var getPrevStub, getNextStub;
setup(function() {
document.documentElement.dir = 'ltr';
getPrevStub = this.sinon.stub(MockStackManager, 'getPrev');
getPrevStub.returns(dialer);
dialerFrame = document.createElement('div');
dialer.element = dialerFrame;
this.sinon.stub(MockStackManager, 'getCurrent').returns(settings);
settingsFrame = document.createElement('div');
settings.element = settingsFrame;
getNextStub = this.sinon.stub(MockStackManager, 'getNext');
getNextStub.returns(contacts);
contactsFrame = document.createElement('div');
contacts.element = contactsFrame;
});
teardown(function() {
window.homescreenLauncher = undefined;
});
suite('Begining the transition', function() {
setup(function() {
this.sinon.spy(dialer, 'broadcast');
SheetsTransition.begin('ltr');
});
test('it should setNFCFocus(false) to current app', function() {
this.sinon.spy(contacts, 'setNFCFocus');
MockStackManager.getCurrent.returns(contacts);
SheetsTransition.begin('ltr');
assert.isTrue(contacts.setNFCFocus.calledWith(false));
});
test('it should cleanup previous sheet transitions', function() {
SheetsTransition.moveInDirection('ltr', 0.3);
MockStackManager.getCurrent.returns(contacts);
SheetsTransition.begin('ltr');
assert.isFalse(settingsFrame.classList.contains('inside-edges'));
assert.equal(settingsFrame.style.transform, '');
});
test('it should add the inside-edges class to the current sheet',
function() {
assert.isTrue(settingsFrame.classList.contains('inside-edges'));
});
test('it should set the transition property on the current sheet',
function() {
var transition = 'transform 0ms linear 0s';
assert.equal(settingsFrame.style.transition, transition);
});
test('it should add the outside-edges-left class to the new sheet',
function() {
assert.isTrue(dialerFrame.classList.contains('outside-edges-left'));
});
test('it should set the transition property on the new sheet',
function() {
var transition = 'transform 0ms linear 0s';
assert.equal(dialerFrame.style.transition, transition);
});
test('it should let the new sheet know that it\'s going to be displayed',
function() {
sinon.assert.calledWith(dialer.broadcast, 'sheetdisplayed');
});
test('it should set the transitioning flag', function() {
assert.isTrue(SheetsTransition.transitioning);
});
test('it should not fail when we\'re at the beginning of the stack',
function() {
getPrevStub.returns(null);
SheetsTransition.begin('ltr');
assert.isTrue(true, 'did not fail');
});
suite('if the direction is rtl', function() {
setup(function() {
SheetsTransition.begin('rtl');
});
test('it should add the outside-edges-right class to the new sheet',
function() {
assert.isTrue(contactsFrame.classList.contains('outside-edges-right'));
});
test('it should set the transition property on the new sheet',
function() {
var transition = 'transform 0ms linear 0s';
assert.equal(contactsFrame.style.transition, transition);
});
test('it should not fail when we\'re at the end of the stack',
function() {
getNextStub.returns(null);
SheetsTransition.begin('rtl');
assert.isTrue(true, 'did not fail');
});
});
});
test('it should dispatch a sheets-gesture-begin event', function(done) {
window.addEventListener('sheets-gesture-begin', function gotIt(evt) {
window.removeEventListener('sheets-gesture-begin', gotIt);
assert.isTrue(true, 'got it');
done();
});
SheetsTransition.begin('ltr');
});
suite('Moving the sheets', function() {
setup(function() {
SheetsTransition.begin('ltr');
SheetsTransition.moveInDirection('ltr', 0.3);
});
test('it should set the transform property on the current sheet',
function() {
assert.equal(settingsFrame.style.transform, 'translateX(30%)');
});
test('it should set the transform property on the new sheet',
function() {
assert.equal(dialerFrame.style.transform,
'translateX(calc(-70% - 2rem))');
});
suite('if the direction is rtl', function() {
setup(function() {
SheetsTransition.begin('rtl');
SheetsTransition.moveInDirection('rtl', 0.3);
});
test('it should set the transform property on the current sheet',
function() {
assert.equal(settingsFrame.style.transform, 'translateX(-30%)');
});
test('it should set the transform property on the new sheet',
function() {
assert.equal(contactsFrame.style.transform,
'translateX(calc(70% + 2rem))');
});
});
suite('if we\'re overflowing', function() {
setup(function() {
getPrevStub.returns(null);
SheetsTransition.begin('ltr');
});
test('it should set the transform normally at first',
function() {
SheetsTransition.moveInDirection('ltr', 0.2);
assert.equal(settingsFrame.style.transform, 'translateX(20%)');
});
test('it should resist after 20% of progress',
function() {
SheetsTransition.moveInDirection('ltr', 0.3);
var transform = settingsFrame.style.transform;
var percentage = parseFloat(transform.split('(')[1].replace('%)', ''));
assert.isTrue(percentage > 24);
assert.isTrue(percentage < 24.5);
});
});
});
suite('Snaping in place', function() {
setup(function() {
SheetsTransition.begin('ltr');
SheetsTransition.moveInDirection('ltr', 0.35);
SheetsTransition.snapInPlace();
});
test('it should set the transition duration on the sheets', function() {
var transition = 'transform 90ms linear 0s';
assert.equal(settingsFrame.style.transition, transition);
assert.equal(dialerFrame.style.transition, transition);
});
suite('if the sheet barely moved', function() {
setup(function() {
SheetsTransition.begin('ltr');
SheetsTransition.moveInDirection('ltr', 0.1);
SheetsTransition.snapInPlace();
});
test('it should have a minimum duration', function() {
var transition = 'transform 90ms linear 0s';
assert.equal(settingsFrame.style.transition, transition);
assert.equal(dialerFrame.style.transition, transition);
});
});
});
suite('Snaping back', function() {
setup(function() {
SheetsTransition.begin('ltr');
SheetsTransition.moveInDirection('ltr', 0.7);
SheetsTransition.snapLeft(0.005);
});
test('it should set the transition duration on the sheets', function() {
var transition = 'transform 50ms linear 0s';
assert.equal(settingsFrame.style.transition, transition);
assert.equal(dialerFrame.style.transition, transition);
});
test('it should remove the initial css classes on the sheets', function() {
assert.isFalse(settingsFrame.classList.contains('inside-edges'));
assert.isFalse(dialerFrame.classList.contains('outside-edges-left'));
});
test('it should add the final css classes on the sheets', function() {
assert.isTrue(settingsFrame.classList.contains('outside-edges-right'));
assert.isTrue(dialerFrame.classList.contains('inside-edges'));
});
test('but it should have a maximum duration when velocity is too low',
function() {
SheetsTransition.begin('ltr');
SheetsTransition.moveInDirection('ltr', 0.7);
SheetsTransition.snapLeft(0.0001);
var transition = 'transform 60ms linear 0s';
assert.equal(settingsFrame.style.transition, transition);
assert.equal(dialerFrame.style.transition, transition);
});
suite('when we\'re at the beginning of the stack', function() {
var snapSpy;
setup(function() {
snapSpy = this.sinon.spy(SheetsTransition, 'snapInPlace');
getPrevStub.returns(null);
SheetsTransition.begin('ltr');
SheetsTransition.moveInDirection('ltr', 0.7);
SheetsTransition.snapLeft(0.005);
});
test('it should just snapInPlace instead', function() {
assert.isTrue(snapSpy.calledOnce);
});
test('it should not change the current sheet class', function() {
assert.isTrue(settingsFrame.classList.contains('inside-edges'));
});
});
});
suite('Snaping forward', function() {
setup(function() {
SheetsTransition.begin('rtl');
SheetsTransition.moveInDirection('rtl', 0.7);
SheetsTransition.snapRight(0.005);
});
test('it should set the transition duration on the sheets', function() {
var transition = 'transform 50ms linear 0s';
assert.equal(settingsFrame.style.transition, transition);
assert.equal(contactsFrame.style.transition, transition);
});
test('it should remove the initial css classes on the sheets', function() {
assert.isFalse(settingsFrame.classList.contains('inside-edges'));
assert.isFalse(contactsFrame.classList.contains('outside-edges-right'));
});
test('it should add the final css classes on the sheets', function() {
assert.isTrue(settingsFrame.classList.contains('outside-edges-left'));
assert.isTrue(contactsFrame.classList.contains('inside-edges'));
});
test('but it should have a maximum duration when velocity is too low',
function() {
SheetsTransition.begin('rtl');
SheetsTransition.moveInDirection('rtl', 0.7);
SheetsTransition.snapLeft(0.0001);
var transition = 'transform 60ms linear 0s';
assert.equal(settingsFrame.style.transition, transition);
assert.equal(contactsFrame.style.transition, transition);
});
suite('when we\'re at the end of the stack', function() {
var snapSpy;
setup(function() {
snapSpy = this.sinon.spy(SheetsTransition, 'snapInPlace');
getNextStub.returns(null);
SheetsTransition.begin('rtl');
SheetsTransition.moveInDirection('rtl', 0.7);
SheetsTransition.snapRight(0.005);
});
test('it should just snapInPlace instead', function() {
assert.isTrue(snapSpy.calledOnce);
});
test('it should not change the current sheet class', function() {
assert.isTrue(settingsFrame.classList.contains('inside-edges'));
});
});
});
suite('Ending the transition', function() {
var currentTrSpy, prevTrSpy;
setup(function() {
currentTrSpy = this.sinon.spy(settingsFrame, 'addEventListener');
prevTrSpy = this.sinon.spy(dialerFrame, 'addEventListener');
SheetsTransition.begin('ltr');
SheetsTransition.moveInDirection('ltr', 0.2);
SheetsTransition.snapInPlace();
});
test('it should clear the transform property on the current sheet',
function() {
assert.equal(settingsFrame.style.transform, '');
});
test('it should ignore opasity transitionend', function() {
assert.isTrue(settingsFrame.classList.contains('inside-edges'));
currentTrSpy.yield({propertyName: 'opacity'});
assert.isTrue(settingsFrame.classList.contains('inside-edges'));
});
test('it should clean the current sheet css classes after the transition',
function() {
assert.isTrue(settingsFrame.classList.contains('inside-edges'));
currentTrSpy.yield({propertyName: 'transform'});
assert.isFalse(settingsFrame.classList.contains('inside-edges'));
});
test('it should clear the current transition property after the transition',
function() {
assert.ok(settingsFrame.style.transition);
currentTrSpy.yield({propertyName: 'transform'});
assert.equal(settingsFrame.style.transition, '');
});
test('it should clear the transform property on the new sheet',
function() {
assert.equal(dialerFrame.style.transform, '');
});
test('it should clean the new sheet css classes after the transition',
function() {
assert.isTrue(dialerFrame.classList.contains('outside-edges-left'));
prevTrSpy.yield({propertyName: 'transform'});
assert.isFalse(dialerFrame.classList.contains('outside-edges-left'));
});
test('it should clear the new transition property after the transition',
function() {
assert.ok(dialerFrame.style.transition);
prevTrSpy.yield({propertyName: 'transform'});
assert.equal(dialerFrame.style.transition, '');
});
test('it should not fail when we\'re at the beginning of the stack',
function() {
getPrevStub.returns(null);
SheetsTransition.begin('ltr');
SheetsTransition.end();
assert.isTrue(true, 'did not fail');
});
test('it should update the transitioning flag', function() {
assert.isFalse(SheetsTransition.transitioning);
});
suite('if the sheets didn\'t move', function() {
setup(function() {
SheetsTransition.begin('ltr');
SheetsTransition.snapInPlace();
SheetsTransition.end();
});
test('it should cleanup without waiting',
function() {
assert.isFalse(settingsFrame.classList.contains('outside-edges-left'));
assert.equal(settingsFrame.style.transition, '');
assert.isFalse(dialerFrame.classList.contains('outside-edges-left'));
assert.equal(dialerFrame.style.transition, '');
});
});
suite('if the direction is rtl', function() {
var nextTrSpy;
setup(function() {
nextTrSpy = this.sinon.spy(contactsFrame, 'addEventListener');
SheetsTransition.begin('rtl');
SheetsTransition.moveInDirection('rtl', 0.2);
SheetsTransition.snapInPlace();
SheetsTransition.end();
});
test('it should clear the transform property on the new sheet',
function() {
assert.equal(contactsFrame.style.transform, '');
});
test('it should clean the new sheet css classes after the transition',
function() {
assert.isTrue(contactsFrame.classList.contains('outside-edges-right'));
nextTrSpy.yield({propertyName: 'transform'});
assert.isFalse(contactsFrame.classList.contains('outside-edges-right'));
});
test('it should clear the new transition property after the transition',
function() {
assert.ok(contactsFrame.style.transition);
nextTrSpy.yield({propertyName: 'transform'});
assert.equal(contactsFrame.style.transition, '');
});
test('it should not fail when we\'re at the end of the stack',
function() {
getNextStub.returns(null);
SheetsTransition.begin('rtl');
assert.isTrue(true, 'did not fail');
});
});
});
});