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,86 @@
/* global LazyLoader, MatchingUI */
'use strict';
require('/shared/js/lazy_loader.js');
requireApp('communications/contacts/views/matching/js/boot.js');
suite('Matching Boot', function() {
var realMatchingUI;
setup(function() {
realMatchingUI = window.MatchingUI;
window.MatchingUI = {
init: function foo() {}
};
});
teardown(function() {
window.MatchingUI = realMatchingUI;
realMatchingUI = null;
});
suite('DOMContentLoaded', function() {
var stub;
setup(function() {
stub = this.sinon.stub(LazyLoader, 'load', function(files) {
return {
then: function(cb) {
cb();
}
};
});
window.dispatchEvent(new CustomEvent('DOMContentLoaded'));
});
teardown(function() {
LazyLoader.load.restore();
});
test(' > LazyLoader must be called once', function() {
// We must have 2 calls to LazyLoader
assert.isTrue(stub.calledOnce);
});
test(' > Call must ensure localization', function() {
// First of all we need to bring l10n library for localization
var call = stub.getCall(0);
assert.isTrue(Array.isArray(call.args[0]));
assert.equal(call.args[0][0], '/shared/js/l10n.js');
});
});
suite('Loaded', function() {
var realMozSetMessage;
suiteSetup(function() {
realMozSetMessage = navigator.mozSetMessageHandler;
navigator.mozSetMessageHandler = function foo() {};
});
suiteTeardown(function() {
navigator.mozSetMessageHandler = realMozSetMessage;
realMozSetMessage = null;
});
setup(function() {
this.sinon.stub(LazyLoader, 'load', function(files) {
return {
then: function(cb) {
cb();
}
};
});
});
test(' > UI is initialized', function() {
var MatchingUISpy = this.sinon.spy(MatchingUI, 'init');
window.dispatchEvent(new CustomEvent('load'));
assert.isTrue(MatchingUISpy.calledOnce);
});
});
});

View file

@ -0,0 +1,136 @@
'use strict';
/* global matchingDetailsData */
/* global MockMozL10n */
/* global MockCurtain */
/* global MockContactsService */
/* global LazyLoader */
/* global Curtain */
/* global Matcher */
/* global ContactsService */
/* global MergeHelper */
require('/shared/js/lazy_loader.js');
requireApp('communications/contacts/test/unit/mock_l10n.js');
requireApp('communications/contacts/test/unit/mock_matching_contacts.js.html');
requireApp('communications/contacts/test/unit/' +
'contacts_matching_ui_test_data.js');
requireApp('communications/contacts/test/unit/mock_contacts_service.js');
requireApp('communications/facebook/test/unit/mock_curtain.js');
requireApp('communications/contacts/views/matching/js/matching_controller.js');
suite('MatchingController', function() {
var realL10n, realCurtain, realContactsService, realMatcher, realMergeHelper,
realParentContactsService;
suiteSetup(function() {
realL10n = window.navigator.mozL10n;
window.navigator.mozL10n = MockMozL10n;
realCurtain = window.Curtain;
window.Curtain = MockCurtain;
realContactsService = window.ContactsService;
window.ContactsService = MockContactsService;
realMatcher = window.Matcher;
window.Matcher = {
match: function foo(){}
};
realMergeHelper = window.MergeHelper;
window.MergeHelper = {
merge: function foo() {
return {
then: function boo(cb) {
cb();
}
};
}
};
sinon.stub(LazyLoader, 'load', function(files, cb) {
cb();
});
realParentContactsService = parent.ContactsService;
parent.ContactsService = window.ContactsService;
});
suiteTeardown(function() {
window.navigator.mozL10n = realL10n;
realL10n = null;
window.Curtain = realCurtain;
realCurtain = null;
window.ContactsService = realContactsService;
realContactsService = null;
window.Matcher = realMatcher;
realMatcher = null;
window.MergeHelper = realMergeHelper;
realMergeHelper = null;
parent.ContactsService = realParentContactsService;
});
suite(' > On merge', function() {
var showSpy, hideMenuSpy, mergeSpy, hideSpy;
setup(function() {
showSpy = this.sinon.spy(Curtain, 'show');
hideMenuSpy = this.sinon.spy(Curtain, 'hideMenu');
hideSpy = this.sinon.spy(Curtain, 'hide');
mergeSpy = this.sinon.spy(MergeHelper, 'merge');
});
test('On merge event received', function() {
window.dispatchEvent(new CustomEvent('merge', {
'detail': {
'checkedContacts': {'1a': '1a'}
}
}));
assert.isTrue(showSpy.calledOnce);
assert.isTrue(hideMenuSpy.calledOnce);
assert.isTrue(mergeSpy.calledOnce);
assert.isTrue(hideSpy.calledOnce);
});
});
suite(' > On start', function() {
var showSpy, matchStub, getContactStub;
setup(function() {
showSpy = this.sinon.spy(Curtain, 'show');
getContactStub = this.sinon.stub(ContactsService, 'get',
function(contactID, successCb, errorCb) {
successCb(matchingDetailsData.user_id_1);
});
matchStub = this.sinon.stub(Matcher, 'match',
function(contact, type, callbacks) {
callbacks.onmatch();
});
});
test('Start method should call match', function(done) {
window.addEventListener('initUI', function fn() {
window.removeEventListener('initUI', fn);
done();
});
window.postMessage({
type: 'sync'
}, location.origin);
setTimeout(function() {
assert.isTrue(showSpy.calledOnce);
assert.isTrue(getContactStub.calledOnce);
assert.isTrue(matchStub.calledOnce);
// Add the extra time we add in matching_controller.js
// in the start function
}, 2000);
});
});
});

View file

@ -0,0 +1,198 @@
'use strict';
/* global CORRECT_MATCHED_VALUE */
/* global dataImage */
/* global dupContacts */
/* global MockMatchingContactsHtml */
/* global MocksHelper */
/* global MockMozL10n */
/* global MatchingUI */
/* eslint-disable */
require('/shared/js/lazy_loader.js');
require('/shared/js/sanitizer.js');
require('/shared/test/unit/mocks/mock_contact_photo_helper.js');
requireApp('communications/contacts/test/unit/mock_matching_contacts.js.html');
requireApp('communications/contacts/test/unit/mock_l10n.js');
requireApp('communications/contacts/test/unit/mock_utils.js');
requireApp('communications/contacts/test/unit/' +
'contacts_matching_ui_test_data.js');
requireApp('communications/contacts/views/matching/js/matching_ui.js');
var mocksHelperForContactMatchingUI = new MocksHelper([
'ContactPhotoHelper',
'ImageLoader',
'URL'
]).init();
suite('MatchingUI', function() {
mocksHelperForContactMatchingUI.attachTestHelpers();
var wrapper = null,
list, mergeAction, realL10n;
var masterContact = {
givenName: ['Manolo<>'],
familyName: ['García']
};
function checkItem(item, contact) {
var bdiNodes = item.querySelectorAll('bdi');
// Given and family names are displayed fine
assert.equal(
bdiNodes[0].textContent,
contact.givenName[0] + ' ' + contact.familyName[0]
);
// The second bdi node is the main reason for matching
// The current preference is tel, email and name
// Check in selectMainReason() of contacts_matching_ui.js
assert.equal(bdiNodes[1].textContent, CORRECT_MATCHED_VALUE);
// The image is ready for the image loader
assert.isTrue(item.querySelector('img').dataset.src == dataImage);
// At the beginning the contact is checked by default
assert.isTrue(item.querySelector('input[type="checkbox"]').checked);
}
suiteSetup(function() {
realL10n = window.navigator.mozL10n;
window.navigator.mozL10n = MockMozL10n;
});
suiteTeardown(function() {
window.navigator.mozL10n = realL10n;
});
function onUIReady(done) {
window.addEventListener('UIReady', function fn() {
window.removeEventListener('UIReady', fn);
done();
});
}
setup(function() {
wrapper = document.createElement('section');
wrapper.innerHTML = MockMatchingContactsHtml;
document.body.appendChild(wrapper);
list = wrapper.querySelector('#contacts-list-container ol');
mergeAction = wrapper.querySelector('#merge-action');
MatchingUI.init();
});
teardown(function() {
wrapper.remove();
});
test('Listens to the initUI event', function() {
// We can't always use dispatchEvent, because the listener is registered
// each time we call init. So we try it once here, and in the reste of the
// test we call directly the `load` method.
this.sinon.stub(MatchingUI, 'load');
window.dispatchEvent(
new CustomEvent('initUI', {
detail: {
type: 'matching',
contact: masterContact,
results: dupContacts
}
})
);
sinon.assert.calledWith(
MatchingUI.load,
'matching', masterContact, dupContacts
);
});
var runs = [
{
type: 'matching',
messageL10nId: 'suggestedDuplicatesMessage',
titleL10nId: null
}, {
type: 'listing',
messageL10nId: 'foundDuplicatesMessage',
titleL10nId: 'duplicatesFoundTitle'
}
];
runs.forEach(function(run) {
suite(run.type + ', ', function() {
setup(function(done) {
onUIReady(done);
MatchingUI.load(run.type, masterContact, dupContacts);
});
test('The UI is initialized correctly ', function() {
// The merge button is initially enabled because there are some
// duplicate contacts.
assert.isFalse(mergeAction.disabled);
var message = wrapper.querySelector('#duplicate-msg > p');
// The message is displayed correctly
var l10nAttrs = navigator.mozL10n.getAttributes(message);
assert.equal(l10nAttrs.args.name, 'Manolo&lt;&gt; García');
assert.equal(l10nAttrs.id, run.messageL10nId);
// The title is correct as well
var title = document.querySelector('title');
assert.equal(title.dataset.l10nId, run.titleL10nId);
// Duplicate contacts list is displayed correctly
var dupContactsKeys = Object.keys(dupContacts);
console.log(list.innerHTML);
assert.equal(list.children.length, dupContactsKeys.length);
dupContactsKeys.forEach(function(id) {
checkItem(list.querySelector('li[data-uuid="' + id + '"]'),
dupContacts[id].matchingContact);
});
});
test('Users are able to un-select and select contacts ', function(done) {
var firstItem = list.querySelector('li[data-uuid="1a"] label');
var checkbox = firstItem.querySelector('input[type="checkbox"]');
assert.isTrue(checkbox.checked);
firstItem.click();
setTimeout(function() {
assert.isFalse(checkbox.checked);
// After un-selecting a contact the merge button is enabled because
// there are two selected
assert.isFalse(mergeAction.disabled);
firstItem.click();
setTimeout(function() {
assert.isTrue(checkbox.checked);
// After selecting this contact the merge button is enabled because
// there are three selected
assert.isFalse(mergeAction.disabled);
done();
});
});
});
test('Merge button throws an event ', function(done) {
// We are un-selecting the two first ones
list.querySelector('li[data-uuid="1a"] label').click();
list.querySelector('li[data-uuid="2b"] label').click();
window.addEventListener('merge', function handle(evt) {
window.removeEventListener('merge', handle);
assert.equal(Object.keys(evt.detail.checkedContacts).length, 1);
done();
});
mergeAction.click();
});
});
});
});