Skip to content

Commit

Permalink
Merge pull request mozilla-b2g#20423 from jmcanterafonseca/multi_cont…
Browse files Browse the repository at this point in the history
…acts

Bug 989927 - [Contacts][Refactor] Create a library that reads the Global...
  • Loading branch information
jmcanterafonseca committed Jun 16, 2014
2 parents 10ea2e1 + db59281 commit eac1340
Show file tree
Hide file tree
Showing 4 changed files with 396 additions and 32 deletions.
148 changes: 148 additions & 0 deletions apps/communications/contacts/test/unit/multi_contact_test.js
@@ -0,0 +1,148 @@
'use strict';

/* globals MockDatastoreObj, MockNavigatorDatastore, MockMozContactsObj */
/* globals MultiContact */

require('/shared/js/lazy_loader.js');
require('/shared/js/simple_phone_matcher.js');
require('/shared/js/contacts/multi_contact.js');
require('/shared/test/unit/mocks/mock_navigator_datastore.js');
requireApp('communications/contacts/test/unit/mock_mozContacts.js');

mocha.globals(['contacts']);


suite('Getting MultiContact Data', function() {

var datastore1, datastore2;

var EXAMPLE1_APP = 'app://example.a1.org';
var EXAMPLE2_APP = 'app://example.a2.org';

var CONTACTS_APP = 'app://communications.gaiamobile.org';

var globalEntryId = '9876';
var ds1Id = '1234', ds2Id = '4567';

// Global entry on the GCDS references two different datastores
var entry = {
id: globalEntryId,
entryData: [
{
origin: EXAMPLE1_APP,
uid: ds1Id
},
{
origin: EXAMPLE2_APP,
uid: ds2Id
}
]
};

var entryMozContacts = {
id: globalEntryId,
entryData: [
{
origin: EXAMPLE1_APP,
uid: ds1Id
},
{
origin: CONTACTS_APP,
uid: 'abcdef'
}
]
};

var ds1Records = Object.create(null);
ds1Records[ds1Id] = {
id: ds1Id,
givenName: ['Jose'],
familyName: null,
tel: [
{
type: ['work'],
value: '983367741'
}
]
};

var ds2Records = Object.create(null);
ds2Records[ds2Id] = {
id: ds2Id,
familyName: ['Cantera'],
email: [
{
type: ['personal'],
value: 'jj@jj.com'
}
]
};

var aMozTestContact = {
id: 'abcdef',
givenName: ['Carlos'],
familyName: ['Fernández'],
tel: [
{
type: ['home'],
value: '638883076'
}
]
};

var realDatastore, realMozContacts;

suiteSetup(function() {
datastore1 = new MockDatastoreObj('contacts', EXAMPLE1_APP, ds1Records);
datastore2 = new MockDatastoreObj('contacts', EXAMPLE2_APP, ds2Records);

MockNavigatorDatastore._datastores = [
datastore1,
datastore2
];

realDatastore = navigator.getDataStores;
realMozContacts = navigator.mozContacts;

navigator.getDataStores = MockNavigatorDatastore.getDataStores;
navigator.mozContacts = new MockMozContactsObj([aMozTestContact]);
});

suiteTeardown(function() {
navigator.getDataStores = realDatastore;
navigator.mozContacts = realMozContacts;
});

test('Getting data from two different datastores', function(done) {
MultiContact.getData(entry).then(function success(data) {
done(function() {
assert.equal(data.id, globalEntryId);

assert.equal(data.familyName[0], 'Cantera');
assert.equal(data.givenName[0], 'Jose');
assert.equal(data.tel.length, 1);
assert.equal(data.email.length, 1);
});
}, function error(err) {
done(function() {
assert.fail('Error while getting data');
});
});
});

test('Getting data from a datastore and mozContacts', function(done) {
MultiContact.getData(entryMozContacts).then(function success(data) {
done(function() {
assert.equal(data.id, globalEntryId);

assert.equal(data.familyName[0], 'Fernández');
assert.equal(data.givenName[0], 'Carlos');
assert.equal(data.tel.length, 2);
});
}, function error(err) {
done(function() {
assert.fail('Error while getting data');
});
});
});
});
76 changes: 48 additions & 28 deletions shared/js/contacts/contacts_merger.js
@@ -1,4 +1,4 @@
/* globals SimplePhoneMatcher, utils, ContactPhotoHelper */
/* globals Promise, SimplePhoneMatcher, utils, ContactPhotoHelper */

'use strict';

Expand Down Expand Up @@ -41,16 +41,33 @@ contacts.Merger = (function() {
// from an external source not related with the matching algorithm.
function doMerge(pmasterContact, pmatchingContacts, callbacks) {
window.setTimeout(function contactsMerge() {
mergeAll(pmasterContact, pmatchingContacts, callbacks);
mergeAll(pmasterContact, pmatchingContacts, filled, callbacks);
}, 0);
}

function doInMemoryMerge(pmasterContact, pmatchingContacts) {
return new Promise(function (resolve, reject) {
mergeAll(pmasterContact, pmatchingContacts, inMemoryMergeDone, {
success: function(masterContact) {
resolve(masterContact);
},
error: function(err) {
reject(err);
}
});
});
}

function inMemoryMergeDone(callbacks, matchingContacts, masterContact) {
callbacks.success(masterContact);
}

function isSimContact(contact) {
return Array.isArray(contact.category) &&
contact.category.indexOf('sim') !== -1;
}

function mergeAll(masterContact, matchingContacts, callbacks) {
function mergeAll(masterContact, matchingContacts, onFilled, callbacks) {
var emailsHash;
var categoriesHash;
var telsHash;
Expand Down Expand Up @@ -228,32 +245,34 @@ contacts.Merger = (function() {
mergedContact.familyName[0] : '')).trim()];

fillMasterContact(masterContact, mergedContact, mergedPhoto,
function filled(masterContact) {
// Updating the master contact
var req = navigator.mozContacts.save(
utils.misc.toMozContact(masterContact));

req.onsuccess = function() {
// Now for all the matchingContacts they have to be removed
matchingContacts.forEach(function(aMatchingContact) {
// Only remove those contacts which are already in the DB
if (aMatchingContact.matchingContact.id) {
var contact = aMatchingContact.matchingContact;
navigator.mozContacts.remove(utils.misc.toMozContact(contact));
}
});

if (typeof callbacks.success === 'function') {
callbacks.success(masterContact);
onFilled.bind(null, callbacks, matchingContacts));
}

function filled(callbacks, matchingContacts, masterContact) {
// Updating the master contact
var req = navigator.mozContacts.save(
utils.misc.toMozContact(masterContact));

req.onsuccess = function() {
// Now for all the matchingContacts they have to be removed
matchingContacts.forEach(function(aMatchingContact) {
// Only remove those contacts which are already in the DB
if (aMatchingContact.matchingContact.id) {
var contact = aMatchingContact.matchingContact;
navigator.mozContacts.remove(utils.misc.toMozContact(contact));
}
};
});

req.onerror = function() {
window.console.error('Error while saving merged Contact: ',
req.error.name);
typeof callbacks.error === 'function' && callbacks.error(req.error);
};
});
if (typeof callbacks.success === 'function') {
callbacks.success(masterContact);
}
};

req.onerror = function() {
window.console.error('Error while saving merged Contact: ',
req.error.name);
typeof callbacks.error === 'function' && callbacks.error(req.error);
};
}

function isDefined(field) {
Expand Down Expand Up @@ -352,7 +371,8 @@ contacts.Merger = (function() {
}

return {
merge: doMerge
merge: doMerge,
inMemoryMerge: doInMemoryMerge
};

})();

0 comments on commit eac1340

Please sign in to comment.