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:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,140 @@
/* global utils */
'use strict';
require('/shared/js/contacts/import/utilities/config.js');
suite('> Config Utilities', function() {
var subject, xhr;
var configObj = {
'id': 12,
'comment': 'Hey there'
};
var existingResource = 'file1.json', nonExistingResource = 'filen.json';
function requestHandler(request, url) {
switch(url) {
case 'file1.json':
setTimeout(function() {
request.response = configObj;
request.status = 200;
request.onload();
});
break;
case 'filen.json':
setTimeout(function() {
request.error = 'FileNotExists';
request.onerror();
});
break;
}
}
suiteSetup(function() {
subject = utils.config;
});
setup(function() {
xhr = sinon.useFakeXMLHttpRequest();
subject.reset();
});
test('Loading an existent configuration resource', function(done) {
xhr.onCreate = function(request) {
requestHandler(request, existingResource);
};
subject.load(existingResource).then(function ready(config1) {
assert.deepEqual(config1, configObj);
// Here we are testing the code patch when the file is already loaded
subject.load(existingResource).then(function ready(config2) {
assert.isTrue(config1 === config2);
}, function error() {
done(new Error('Promise should not be rejected'));
});
done();
}, function error() {
done(new Error('Promise should not be rejected'));
});
});
test('Loading a non existent configuration resource', function(done) {
xhr.onCreate = function(request) {
requestHandler(request, nonExistingResource);
};
subject.load(nonExistingResource).then(function ready(config) {
done(new Error('Promise should not be resolved'));
}, function error() {
xhr.restore();
done();
});
});
test('Same file loaded various times sequentially. Callbacks are called',
function(done) {
xhr.onCreate = function(request) {
requestHandler(request, existingResource);
};
var promise1Resolved = false, promise2Resolved = false, config1, config2;
subject.load(existingResource).then(function ready(config) {
config1 = config;
assert.deepEqual(config, configObj);
promise1Resolved = true;
if (promise2Resolved) {
assert.isTrue(config1 === config2);
xhr.restore();
done();
}
}, function error() {
done(new Error('Promise should not be rejected'));
});
subject.load(existingResource).then(function ready(config) {
config2 = config;
assert.deepEqual(config, configObj);
promise2Resolved = true;
if (promise1Resolved) {
assert.isTrue(config1 === config2);
xhr.restore();
done();
}
}, function error() {
done(new Error('Promise should not be rejected'));
});
});
test('Same file non-existent loaded various times sequentially.',
function(done) {
xhr.onCreate = function(request) {
requestHandler(request, nonExistingResource);
};
var promise1Rejected = false, promise2Rejected = false;
subject.load(nonExistingResource).then(function ready(config) {
done(new Error('Promise should not be resolved'));
}, function error() {
promise1Rejected = true;
if (promise2Rejected) {
xhr.restore();
done();
}
});
subject.load(nonExistingResource).then(function ready(config) {
done(new Error('Promise should not be resolved'));
}, function error() {
promise2Rejected = true;
if (promise1Rejected) {
xhr.restore();
done();
}
});
});
});

View file

@ -0,0 +1,61 @@
<section id="section-group-magnifier-anchor"></section>
<section id="section-group-star-anchor"></section>
<section id="section-group-A"></section>
<section id="section-group-B"></section>
<section id="section-group-C"></section>
<section id="section-group-D"></section>
<section id="section-group-E"></section>
<section id="section-group-F"></section>
<section id="section-group-G"></section>
<section id="section-group-H"></section>
<section id="section-group-I"></section>
<section id="section-group-J"></section>
<section id="section-group-K"></section>
<section id="section-group-L"></section>
<section id="section-group-M"></section>
<section id="section-group-N"></section>
<section id="section-group-O"></section>
<section id="section-group-P"></section>
<section id="section-group-Q"></section>
<section id="section-group-R"></section>
<section id="section-group-S"></section>
<section id="section-group-T"></section>
<section id="section-group-U"></section>
<section id="section-group-V"></section>
<section id="section-group-W"></section>
<section id="section-group-X"></section>
<section id="section-group-Y"></section>
<section id="section-group-Z"></section>
<section id="section-group-#"></section>
<p id="overlay"></p>
<ol id="jumper">
<li data-anchor="group-magnifier-anchor" data-img="manfifier_icon_big.png"></li>
<li data-anchor="group-star-anchor" data-img="star_icon_big.png"></li>
<li data-anchor="group-A" data-letter="A"></li>
<li data-anchor="group-B" data-letter="B"></li>
<li data-anchor="group-C" data-letter="C"></li>
<li data-anchor="group-D" data-letter="D"></li>
<li data-anchor="group-E" data-letter="E"></li>
<li data-anchor="group-F" data-letter="F"></li>
<li data-anchor="group-G" data-letter="G"></li>
<li data-anchor="group-H" data-letter="H"></li>
<li data-anchor="group-I" data-letter="I"></li>
<li data-anchor="group-J" data-letter="J"></li>
<li data-anchor="group-K" data-letter="K"></li>
<li data-anchor="group-L" data-letter="L"></li>
<li data-anchor="group-M" data-letter="M"></li>
<li data-anchor="group-N" data-letter="N"></li>
<li data-anchor="group-O" data-letter="O"></li>
<li data-anchor="group-P" data-letter="P"></li>
<li data-anchor="group-Q" data-letter="Q"></li>
<li data-anchor="group-R" data-letter="R"></li>
<li data-anchor="group-S" data-letter="S"></li>
<li data-anchor="group-T" data-letter="T"></li>
<li data-anchor="group-U" data-letter="U"></li>
<li data-anchor="group-V" data-letter="V"></li>
<li data-anchor="group-W" data-letter="W"></li>
<li data-anchor="group-X" data-letter="X"></li>
<li data-anchor="group-Y" data-letter="Y"></li>
<li data-anchor="group-Z" data-letter="Z"></li>
<li data-anchor="group-#" data-letter="#"></li>
</ol>

View file

@ -0,0 +1,112 @@
/* global utils, loadBodyHTML */
'use strict';
var realOnTouchStart;
realOnTouchStart = window.ontouchstart;
delete window.ontouchstart;
require('/shared/js/contacts/contacts_shortcuts.js');
suite('contacts_shortcuts AKA Alpha Scroller', function() {
var subject;
var params;
var scrollSpy;
var eventsSpy;
// Fill the params object with the information
// needed to initialise the alpha scroller.
// Creates the necesary dom as well.
function createAlphaScrollParams() {
loadBodyHTML('/contacts/test/unit/utilities/contacts_shortcuts.html');
params = {
overlay: document.getElementById('overlay'),
jumper: document.getElementById('jumper'),
groupSelector: '#group-',
scrollToCb: function (domTarget, group) {},
desktop: true
};
}
// Given a letter returns the dom element to trigger
// events over it. Take into account the special cases.
function getLetterElement(letter) {
var anchor = 'group-' + letter;
if (letter.length > 1) {
anchor = letter;
}
return document.querySelector('li[data-anchor="' + anchor + '"]');
}
// Send events to start touching a letter.
// Despite of saying touch, we dispatch clicks events,
// to make the test case easier
function touchStartLetter(letter) {
var elem = getLetterElement(letter);
dispatchEvent('mousedown', elem);
}
function touchMoveLetter(letter) {
var elem = getLetterElement(letter);
dispatchEvent('mousemove', elem);
}
function touchEndLetter(letter) {
var elem = getLetterElement(letter);
dispatchEvent('mouseup', elem);
}
function dispatchEvent(type, elem) {
var event = new MouseEvent(type, {
'view': window,
'bubbles': true,
'cancelable': true
});
elem.dispatchEvent(event);
}
suiteSetup(function () {
subject = utils.alphaScroll;
});
suiteTeardown(function() {
window.ontouchstart = realOnTouchStart;
realOnTouchStart = null;
});
setup(function () {
createAlphaScrollParams();
scrollSpy = this.sinon.spy(params, 'scrollToCb');
eventsSpy = this.sinon.spy(params.jumper, 'addEventListener');
subject.init(params);
});
suite('> initialization', function () {
test('> listeners attached', function () {
sinon.assert.callCount(eventsSpy, 3);
});
});
suite('> scrolling', function () {
test('> scrolling from A to B', function () {
touchStartLetter('A');
touchMoveLetter('B');
touchEndLetter('B');
sinon.assert.calledTwice(scrollSpy);
assert.equal(scrollSpy.getCall(0).args[1], 'A');
assert.equal(scrollSpy.getCall(1).args[1], 'B');
});
test('> when scrolling out of #, hide overlay inmediately', function () {
touchStartLetter('#');
touchMoveLetter('#');
touchEndLetter('#');
assert.equal(params.overlay.style.MozTransitionDuration, '0s');
});
});
});

View file

@ -0,0 +1,76 @@
'use strict';
requireApp('communications/contacts/js/utilities/cookie.js');
suite('Contacts Cookies', function() {
var COOKIE_NAME = 'preferences';
var COOKIE_PROPS = null;
var subject = null;
suiteSetup(function() {
COOKIE_PROPS = Object.keys(window.utils.cookie.COOKIE_DEFAULTS);
subject = window.utils.cookie;
});
function deleteCookie() {
document.cookie = COOKIE_NAME + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
function saveCookie(value) {
document.cookie = COOKIE_NAME + '= ' + value;
}
function checkDefaultCookie(cookie) {
assert.equal(cookie.version, subject.COOKIE_VERSION);
COOKIE_PROPS.forEach(function(prop) {
assert.equal(cookie[prop], subject.getDefault(prop));
});
}
setup(function() {
deleteCookie();
});
suite('Bad cookie', function() {
test('No cookie returns null;', function() {
var cookie = subject.load();
assert.isNull(cookie);
});
test('Invalid cookie should return default cookie value', function() {
saveCookie('invalid value');
var cookie = subject.load();
assert.isNotNull(cookie);
checkDefaultCookie(cookie);
});
});
suite('Update cookie', function() {
test('Updating empty cookie with invalid property', function() {
subject.update({test: 1});
var cookie = subject.load();
assert.isNotNull(cookie);
assert.equal(cookie.version, subject.COOKIE_VERSION);
assert.equal(cookie.test, null);
});
test('Updating empty cookie', function() {
subject.update({order: true});
var cookie = subject.load();
assert.isNotNull(cookie);
assert.equal(cookie.version, subject.COOKIE_VERSION);
assert.isTrue(cookie.order);
});
test('Update invalid cookie', function() {
saveCookie('invalid value');
subject.update({order: true});
var cookie = subject.load();
assert.isNotNull(cookie);
assert.equal(cookie.version, subject.COOKIE_VERSION);
assert.isTrue(cookie.order);
});
});
});

View file

@ -0,0 +1,44 @@
/* global Rest */
'use strict';
require('/shared/js/contacts/utilities/http_rest.js');
suite('> Rest utility class', function() {
var restRequest, subject, xhr;
var callbacks = {
errorCallback: function() {},
timeoutCallback: function() {},
successCallback: function() {}
};
setup(function() {
xhr = sinon.useFakeXMLHttpRequest();
xhr.onCreate = function(x) {
subject = x;
};
this.sinon.spy(callbacks, 'errorCallback');
this.sinon.spy(callbacks, 'timeoutCallback');
this.sinon.spy(callbacks, 'successCallback');
restRequest = Rest.get('uri', callbacks);
this.sinon.useFakeTimers();
});
teardown(function() {
xhr.restore();
this.sinon.clock.restore();
});
test('> Canceling a request doesnt trigger a retry (via error callback)',
function() {
this.sinon.spy(subject, 'abort');
restRequest.cancel();
this.sinon.clock.tick(50);
sinon.assert.called(subject.abort);
sinon.assert.callCount(callbacks.errorCallback, 0);
sinon.assert.pass(restRequest.isCancelled());
});
});

View file

@ -0,0 +1,223 @@
'use strict';
/* global MocksHelper */
/* global ICEData */
requireApp('communications/contacts/test/unit/mock_asyncstorage.js');
requireApp('communications/contacts/test/unit/mock_cache.js');
requireApp('communications/contacts/js/utilities/ice_data.js');
require('/shared/test/unit/mocks/mock_ice_store.js');
var mocksHelper = new MocksHelper([
'asyncStorage',
'Cache',
'ICEStore'
]);
mocksHelper.init();
suite('ICE Data', function() {
var subject;
suiteSetup(function() {
subject = ICEData;
mocksHelper.suiteSetup();
});
setup(function() {
window.asyncStorage.keys = {
'ice-contacts': [{ id: 1, active: true}]
};
});
suite('> Load data', function() {
test('> Check data from async storage', function(done) {
subject.load().then(done(function() {
var iceContacts = subject.iceContacts;
assert.lengthOf(iceContacts, 2);
assert.isTrue(iceContacts[0].active);
assert.equal(iceContacts[0].id, 1);
assert.isFalse(iceContacts[1].active);
}), done);
});
test('> With no ice local async data', function(done) {
window.asyncStorage.keys = {};
subject.load().then(done(function() {
var iceContacts = subject.iceContacts;
assert.isFalse(iceContacts[0].active);
assert.isFalse(iceContacts[1].active);
}), done);
});
});
suite('> Set ice contact', function() {
test('> Adding a new contact', function(done) {
subject.setICEContact(2, 1, true).then(done(function() {
var iceContacts = subject.iceContacts;
assert.equal(iceContacts[1].id, 2);
assert.isTrue(iceContacts[1].active);
}), done);
});
test('> Change an existing ice contact', function(done) {
subject.setICEContact(1, 0, false).then(done(function() {
var iceContacts = subject.iceContacts;
assert.isFalse(iceContacts[0].active);
}),done);
});
test('> Data sent to DS is valid', function(done) {
subject.load().then(function() {
subject.setICEContact(2, 1, true).then(function(data) {
done(function() {
assert.lengthOf(data, 2);
});
});
}, done);
});
test('> Setting ICE Contacts', function(done) {
var newIceContacts = ['aaa'];
subject.setICEContacts(newIceContacts).then(done(function() {
var iceContacts = subject.iceContacts;
assert.equal(iceContacts[0].id, 'aaa');
assert.isTrue(iceContacts[0].active);
assert.isUndefined(iceContacts[1].id);
}), done);
});
});
suite('> Listen for changes', function() {
setup(function() {
subject.stopListenForChanges();
});
test('> Several listening attach one contact change', function(done) {
sinon.spy(document, 'addEventListener');
subject.listenForChanges(function() {}).then(function() {
return subject.listenForChanges(function() {});
}).then(function() {
sinon.assert.calledOnce(document.addEventListener);
document.addEventListener.restore();
done();
});
});
test('> A change in a non ice contact will not trigger', function(done) {
var changeCallback;
var stub = sinon.stub(document, 'addEventListener', function(name, cb) {
changeCallback = cb;
});
subject.listenForChanges(function() {
throw new Error();
}).then(function() {
changeCallback({
detail: {
contactID: 5,
reason: 'update'
}
});
stub.restore();
done();
});
});
test('> A change in a ice contact will trigger', function(done) {
var changeCallback;
var stub = sinon.stub(document, 'addEventListener', function(name, cb) {
changeCallback = cb;
});
subject.listenForChanges(function() {
stub.restore();
done(function() {
assert.ok('ok');
});
}).then(function() {
changeCallback({
detail: {
contactID: 1,
reason: 'update'
}
});
});
});
test('> ICE contact removed', function(done) {
var changeCallback;
var stub = sinon.stub(document, 'addEventListener', function(name, cb) {
changeCallback = cb;
});
subject.listenForChanges(function() {
done(function() {
assert.isFalse(subject.iceContacts[0].id === 1);
assert.isFalse(subject.iceContacts[0].active);
stub.restore();
});
}).then(function() {
changeCallback({
detail: {
contactID: 1,
reason: 'remove'
}
});
});
});
test('> Several contacts removed', function(done) {
var changeCallback;
window.asyncStorage.keys = {
'ice-contacts': [{ id: 1, active: true}, {id: 2, active: true}]
};
var stub = sinon.stub(document, 'addEventListener', function(name, cb) {
changeCallback = cb;
});
var listenerCalled = 0;
subject.listenForChanges(function() {
listenerCalled++;
assert.isFalse(subject.iceContacts[(listenerCalled-1)].id ===
listenerCalled);
assert.isFalse(subject.iceContacts[(listenerCalled-1)].active);
if (listenerCalled === 2) {
done(function() {
stub.restore();
});
}
}).then(function() {
// Perform several changes, but we will receive just 2 changes
// in the callback above as we defined 2 ICE contacts and we
// removed those
changeCallback({
detail: {
contactID: 1,
reason: 'remove'
}
});
changeCallback({
detail: {
contactID: 2,
reason: 'remove'
}
});
changeCallback({
detail: {
contactID: 3,
reason: 'remove'
}
});
});
});
});
});

View file

@ -0,0 +1,111 @@
'use strict';
/* global utils, MockLazyLoader */
require('/shared/js/contacts/utilities/image_thumbnail.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
suite('Contacts/utilities/thumbnailImage >', function() {
var imageData = {
'gaia.png': null,
'tiny-gaia.png': null,
'sadpanda.png': null
};
var realLazyLoader, realImageUtils, realConfig, mockUtilsConfig;
var spy;
suiteSetup(function(done) {
realLazyLoader = window.LazyLoader;
realImageUtils = window.ImageUtils;
window.LazyLoader = MockLazyLoader;
window.ImageUtils = {
resizeAndCropToCover: function(inputImageBlob,
outputWidth, outputHeight,
outputType, encoderOptions) {
return Promise.resolve(new Blob(['x'], {type: 'image/jpeg'}));
}
};
spy = sinon.spy(window.ImageUtils, 'resizeAndCropToCover');
realConfig = utils.config;
mockUtilsConfig = {
load: function() {
return Promise.resolve({
thumbnail: {
'quality': 0.95
}
});
}
};
var assetsNeeded = 0;
function loadBlob(filename) {
/*jshint validthis: true */
assetsNeeded++;
var req = new XMLHttpRequest();
var testData = this;
req.open('GET', '/test/unit/media/' + filename, true);
req.responseType = 'blob';
req.onload = function() {
testData[filename] = req.response;
if (--assetsNeeded === 0) {
done();
}
};
req.send();
}
// load the images
Object.keys(imageData).forEach(loadBlob, imageData);
});
suiteTeardown(function() {
window.LazyLoader = realLazyLoader;
window.ImageUtils = realImageUtils;
utils.config = realConfig;
});
setup(function() {
spy.reset();
utils.config = mockUtilsConfig;
});
test('should draw the image smaller. Default configuration', function(done) {
utils.config = {
load: function() {
return Promise.reject();
}
};
utils.thumbnailImage(imageData['gaia.png'], function(thumbnail) {
done(function() {
assert.isTrue(spy.calledOnce);
var call = spy.getCall(0);
assert.equal(call.args[1], 65);
assert.equal(call.args[2], 65);
assert.equal(call.args[3], 'image/jpeg');
assert.equal(call.args[4], 1.0);
});
});
});
test('should take into account a custom configuration', function(done) {
utils.thumbnailImage(imageData['gaia.png'], function(thumbnail) {
done(function() {
var call = spy.getCall(0);
assert.equal(call.args[1], 65);
assert.equal(call.args[2], 65);
assert.equal(call.args[3], 'image/jpeg');
assert.equal(call.args[4], 0.95);
});
});
});
});

View file

@ -0,0 +1,156 @@
'use strict';
/* global utils */
require('/shared/js/contacts/import/utilities/misc.js');
suite('Contacts/utilities/parseName >', function() {
var subject;
suiteSetup(function() {
subject = utils.misc.parseName;
});
function assertNames(out, gn, fn) {
assert.equal(out.givenName, gn);
assert.equal(out.familyName, fn);
}
test('Empty string', function() {
var out = subject('');
assertNames(out, '', '');
});
test('Blank string', function() {
var out = subject(' ');
assertNames(out, '', '');
});
test('Null string', function() {
var out = subject(null);
assertNames(out, '', '');
});
test('Only a component', function() {
var out = subject('Jose');
assertNames(out, 'Jose', '');
});
test('Two Components', function() {
var out = subject('Jose Cantera');
assertNames(out, 'Jose', 'Cantera');
});
test('Two Components. Pathological case (I)', function() {
var out = subject('J. C.');
assertNames(out, 'J.', 'C.');
});
test('Two Components. Pathological case without dots', function() {
var out = subject('J C.');
assertNames(out, 'J', 'C.');
});
test('Two Components. Pathological case (II)', function() {
var out = subject('Jose C.');
assertNames(out, 'Jose', 'C.');
});
test('Two Components. Pathological case (III)', function() {
var out = subject('J. Cantera');
assertNames(out, 'J.', 'Cantera');
});
test('Three Components', function() {
var out = subject('Jose Manuel Cantera');
assertNames(out, 'Jose Manuel', 'Cantera');
});
test('Three Components. Only two are significative', function() {
var out = subject('Gunilla von Bismarck');
assertNames(out, 'Gunilla', 'von Bismarck');
});
test('Three Components. Abbreviation', function() {
var out = subject('Jose M. Cantera');
assertNames(out, 'Jose M.', 'Cantera');
});
test('Four Components', function() {
var out = subject('Jose Manuel Cantera Fonseca');
assertNames(out, 'Jose Manuel', 'Cantera Fonseca');
});
test('Four Components. Three are given Name', function() {
var out = subject('María del Mar González');
assertNames(out, 'María del Mar', 'González');
});
test('Four Components.', function() {
var out = subject('María de la O Álvarez');
assertNames(out, 'María de la O', 'Álvarez');
});
test('Four Components. Three are family Name', function() {
var out = subject('Carlos de la Fuente');
assertNames(out, 'Carlos', 'de la Fuente');
});
test('Five Components. Three are family Name', function() {
var out = subject('Carlos de la Fuente González');
assertNames(out, 'Carlos de la Fuente', 'González');
});
test('Five Components', function() {
var out = subject('Cristina Federica Leonor Ávila Álvarez');
assertNames(out, 'Cristina Federica Leonor', 'Ávila Álvarez');
});
test('Six Components', function() {
var out = subject('Cristina Federica Leonor Juana Ávila Álvarez');
assertNames(out, 'Cristina Federica Leonor Juana', 'Ávila Álvarez');
});
test('German name', function() {
var out = subject('Niklas Boehm');
assertNames(out, 'Niklas', 'Boehm');
});
test('French name', function() {
var out = subject('Madelene Pirouet');
assertNames(out, 'Madelene', 'Pirouet');
});
test('North American name', function() {
var out = subject('Arthur J. McNitt');
assertNames(out, 'Arthur J.', 'McNitt');
});
test('Brazilian name', function() {
var out = subject('Ronaldo Luís Nazário de Lima');
assertNames(out, 'Ronaldo Luís', 'Nazário de Lima');
});
});

View file

@ -0,0 +1,16 @@
/* global utils */
'use strict';
requireApp('communications/contacts/test/unit/mock_l10n.js');
requireApp('communications/contacts/js/utilities/normalizer.js');
suite('> Normalizer Utilities', function() {
test('Correctly identify if date is yesterday if less than 24 hours' +
' from yesterday.', function() {
var fakeNow = 1406362980000; // July 26 2014, 10:23am.
var testDate = 1406307060000; // July 25 2014, 6:51pm.
var subject = utils.time.pretty(testDate, fakeNow);
assert.isTrue(subject.indexOf('yesterday') >= 0);
});
});

View file

@ -0,0 +1,75 @@
/* global utils, MocksHelper, MockL10n */
'use strict';
require('/shared/test/unit/mocks/mock_l10n.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
var mocksHelperForActivities = new MocksHelper([
'LazyLoader'
]).init();
function loadHTML() {
document.body.innerHTML = '<div id="statusMsg" class="hidden">' +
' <p class="statusMsg">Test</p>' +
'</div>';
}
suite('> System Banner Utilities', function() {
var statusDOM,
subject;
var realL10n;
mocksHelperForActivities.attachTestHelpers();
suiteSetup(function() {
realL10n = navigator.mozL10n;
navigator.mozL10n = MockL10n;
});
setup(function(done) {
this.sinon.useFakeTimers();
loadHTML();
// calling it here to be able to reload the HTML on setup, as status.js
// assigns the #statusMsg on load
require('/shared/js/contacts/import/utilities/status.js', function () {
subject = utils.status;
statusDOM = document.querySelector('#statusMsg');
done();
});
});
suiteTeardown(function() {
navigator.mozL10n = realL10n;
subject = null;
document.body.innerHTML = '';
});
test('Status msg shown when passing proper parameter', function() {
var parameter = {
id: 'some_id',
args: {'optional_args': 'args value'}
};
utils.status.show(parameter);
assert.isFalse(statusDOM.classList.contains('hidden'));
});
test('Status not shown when passing wrong parameter', function() {
var parameter = 'some string';
var errorSpy = this.sinon.spy(console, 'error');
utils.status.show(parameter);
assert.isTrue(statusDOM.classList.contains('hidden'));
assert.isTrue(errorSpy.calledWith('Status arguments must be objects'));
});
test('Status msg hidden on time after shown', function(done) {
var testhide = sinon.spy(subject, 'hide');
utils.status.show({id: 'system_banner_shown'});
this.sinon.clock.tick(5000);
assert.isTrue(testhide.called);
done();
});
});

View file

@ -0,0 +1,60 @@
'use strict';
/* global MainNavigation */
/* global ContactsTag */
/* global TagSelector */
/* global MockMainNavigation */
/* global MocksHelper */
/* global MockFormDom */
/* global MockSelectionDom */
/* global MockMozL10n */
/* global MockContactsTag */
requireApp('communications/contacts/test/unit/mock_form_dom.js.html');
requireApp('communications/contacts/test/unit/mock_selection_dom.js.html');
requireApp('communications/contacts/test/unit/mock_l10n.js');
requireApp('communications/contacts/test/unit/mock_contacts_tag.js');
requireApp('communications/contacts/test/unit/mock_navigation.js');
requireApp('communications/contacts/test/unit/mock_main_navigation.js');
requireApp('communications/contacts/js/utilities/tagSelector.js');
requireApp('communications/contacts/js/tag_options.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
var mocksHelper = new MocksHelper([
'LazyLoader'
]);
mocksHelper.init();
suite('TagSelector', function() {
var subject;
suiteSetup(function() {
subject = TagSelector;
mocksHelper.suiteSetup();
document.body.innerHTML = MockFormDom + MockSelectionDom;
navigator.mozL10n = MockMozL10n;
window.ContactsTag = MockContactsTag;
window.MainNavigation = MockMainNavigation;
document.body.dataset.taglist = 'phone-type';
});
setup(function() {
this.sinon.spy(ContactsTag, 'filterTags');
this.sinon.spy(ContactsTag, 'setCustomTag');
this.sinon.spy(ContactsTag, 'setCustomTagVisibility');
this.sinon.spy(ContactsTag, 'fillTagOptions');
this.sinon.spy(MainNavigation, 'go');
});
suite('> Show', function() {
test('Test show function calls', function() {
TagSelector.show(document.body);
sinon.assert.calledOnce(ContactsTag.filterTags);
sinon.assert.calledOnce(ContactsTag.setCustomTag);
sinon.assert.calledOnce(ContactsTag.setCustomTagVisibility);
sinon.assert.calledOnce(ContactsTag.fillTagOptions);
sinon.assert.calledOnce(MainNavigation.go);
});
});
});