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,245 @@
'use strict';
/* globals ContactsBTExport, MockContactToVcarBlob, MockgetDeviceStorage,
MockGetStorageIfAvailable, MockGetStorageIfAvailableError,
MockGetUnusedFilename, MocksHelper, MockMozActivity, MockMozL10n */
requireApp('communications/contacts/js/export/bt.js');
requireApp('communications/contacts/test/unit/mock_mozActivity.js');
requireApp('communications/contacts/test/unit/mock_get_device_storage.js');
requireApp('communications/contacts/test/unit/export/mock_export_utils.js');
requireApp('communications/contacts/test/unit/mock_l10n.js');
if (!window._) {
window._ = null;
}
if (!window.getStorageIfAvailable) {
window.getStorageIfAvailable = null;
}
if (!window.getUnusedFilename) {
window.getUnusedFilename = null;
}
if (!window.ContactToVcardBlob) {
window.ContactToVcardBlob = null;
}
var realUtils = null;
if (!window.utils) {
window.utils = null;
} else {
realUtils = window.utils;
}
var mocksHelperForExportBT = new MocksHelper([
'MozActivity'
]).init();
suite('BT export', function() {
var real_,
realMozL10n,
realDeviceStorage,
realgetUnusedFilename,
realContactToVcardBlob,
realgetStorageIfAvailable;
var mockContact1 = {
familyName: ['surname1'],
givenName: ['name1']
},
mockContact2 = {
familyName: ['surname2'],
givenName: ['name2']
};
var subject,
mockProgress,
mocksHelper = mocksHelperForExportBT;
suiteSetup(function() {
mocksHelper.suiteSetup();
// Device storage mock
realDeviceStorage = navigator.getDeviceStorage;
navigator.getDeviceStorage = MockgetDeviceStorage;
// L10n mock
realMozL10n = navigator.mozL10n;
navigator.mozL10n = MockMozL10n;
real_ = window._;
window._ = navigator.mozL10n.get;
//getStorageIfAvailable mock
realgetStorageIfAvailable = window.getStorageIfAvailable;
window.getStorageIfAvailable = MockGetStorageIfAvailable;
//getUnusedFilename mock
realgetUnusedFilename = window.getUnusedFilename;
window.getUnusedFilename = MockGetUnusedFilename;
//ContactToVcardBlob mock
realContactToVcardBlob = window.ContactToVcardBlob;
window.ContactToVcardBlob = MockContactToVcarBlob;
if (!window.utils) {
window.utils = {};
}
window.utils.overlay = {
hideMenu: function() {}
};
mockProgress = function() {};
});
suiteTeardown(function() {
mocksHelper.suiteTeardown();
navigator.getDeviceStorage = realDeviceStorage;
window._ = real_;
window.getStorageIfAvailable = realgetStorageIfAvailable;
window.getUnusedFilename = realgetUnusedFilename;
window.ContactToVcardBlob = realContactToVcardBlob;
window.utils = realUtils;
});
setup(function() {
mocksHelper.setup();
subject = new ContactsBTExport();
subject.setProgressStep(mockProgress);
});
teardown(function() {
mocksHelper.teardown();
});
test('Calling with 1 contact', function(done) {
subject.setContactsToExport([mockContact1]);
subject.doExport(function onFinish(error, exported, msg) {
assert.equal(false, subject.hasDeterminativeProgress());
assert.isNull(error);
assert.equal(1, exported);
done();
});
// Execute the onsuccess on demand
MockMozActivity.currentActivity.onsuccess();
});
test('Calling with several contacts', function(done) {
var contacts = [mockContact1, mockContact2];
subject.setContactsToExport(contacts);
subject.doExport(function onFinish(error, exported, msg) {
assert.isNull(error);
assert.equal(contacts.length, exported);
done();
});
// Execute the onsuccess on demand
MockMozActivity.currentActivity.onsuccess();
});
test('Calling with cancel flag activated', function(done) {
var contacts = [mockContact1, mockContact2];
subject.setContactsToExport(contacts);
subject.cancelExport();
subject.doExport(function onFinish(error, exported, isRecoverable) {
assert.isNull(error);
assert.equal(0, exported);
assert.equal(isRecoverable, false);
done();
});
});
});
suite('BT export_error', function() {
var real_,
realMozL10n,
realDeviceStorage,
realgetUnusedFilename,
realContactToVcardBlob,
realgetStorageIfAvailable;
var mockContact1 = {
familyName: ['surname1'],
givenName: ['name1']
},
mockContact2 = {
familyName: ['surname2'],
givenName: ['name2']
};
var subject,
mockProgress,
mocksHelper = mocksHelperForExportBT;
suiteSetup(function() {
mocksHelper.suiteSetup();
// Device storage mock
realDeviceStorage = navigator.getDeviceStorage;
navigator.getDeviceStorage = MockgetDeviceStorage;
// L10n mock
realMozL10n = navigator.mozL10n;
navigator.mozL10n = MockMozL10n;
real_ = window._;
window._ = navigator.mozL10n.get;
//getStorageIfAvailable mock
realgetStorageIfAvailable = window.getStorageIfAvailable;
window.getStorageIfAvailable = MockGetStorageIfAvailableError;
//getUnusedFilename mock
realgetUnusedFilename = window.getUnusedFilename;
window.getUnusedFilename = MockGetUnusedFilename;
//ContactToVcardBlob mock
realContactToVcardBlob = window.ContactToVcardBlob;
window.ContactToVcardBlob = MockContactToVcarBlob;
if (!window.utils) {
window.utils = {};
}
window.utils.overlay = {
hideMenu: function() {}
};
mockProgress = function() {};
});
suiteTeardown(function() {
mocksHelper.suiteTeardown();
navigator.getDeviceStorage = realDeviceStorage;
window._ = real_;
window.getStorageIfAvailable = realgetStorageIfAvailable;
window.getUnusedFilename = realgetUnusedFilename;
window.ContactToVcardBlob = realContactToVcardBlob;
window.utils = realUtils;
});
setup(function() {
mocksHelper.setup();
subject = new ContactsBTExport();
subject.setProgressStep(mockProgress);
});
teardown(function() {
mocksHelper.teardown();
});
test('Calling with error', function(done) {
var contacts = [mockContact1, mockContact2];
subject.setContactsToExport(contacts);
subject.doExport(function onFinish(error, exported, isRecoverable) {
assert.isNotNull(error);
assert.equal(error.reason, 'noSpace');
assert.equal(0, exported);
assert.equal(isRecoverable, false);
done();
});
});
});

View file

@ -0,0 +1,271 @@
'use strict';
/* global ContactsService */
/* global MockContactsList */
/* global MockConfirmDialog */
/* global ContactsExporter */
/* global MockExportStrategy */
/* global MockMozContacts */
/* global MockMozL10n */
/* global MocksHelper */
/* global MockLoader */
requireApp('communications/contacts/services/contacts.js');
requireApp('communications/contacts/test/unit/mock_navigation.js');
requireApp('communications/contacts/test/unit/mock_contacts.js');
require('/shared/test/unit/mocks/mock_mozContacts.js');
requireApp('communications/contacts/test/unit/mock_export_strategy.js');
requireApp('communications/contacts/test/unit/mock_contacts_list.js');
requireApp('communications/contacts/test/unit/mock_l10n.js');
requireApp('communications/contacts/test/unit/mock_loader.js');
require('/shared/test/unit/mocks/mock_confirm_dialog.js');
require('/shared/js/fb/fb_reader_utils.js');
requireApp('communications/contacts/js/export/contacts_exporter.js');
var realUtils = null;
var realStatus = null;
var realLoader = null;
var real_ = null;
if (!window.utils) {
window.utils = null;
} else {
realUtils = window.utils;
}
if (!window.status) {
window.status = null;
} else {
realStatus = window.status;
}
if (!navigator.mozL10n) {
navigator.mozL10n = null;
}
if (!window._) {
window._ = null;
}
var mocksHelperForExporter = new MocksHelper([
'Contacts',
'ConfirmDialog',
'Loader'
]).init();
suite('Contacts Exporter', function() {
var subject;
var ids = ['1', '3'];
var realL10n;
var menuOverlay;
function getContactsForIds(ids) {
var contacts = MockContactsList();
var result = [];
ids.forEach(function onId(id) {
for (var i = 0; i < contacts.length; i++) {
if (contacts[i].id == id) {
result.push(contacts[i]);
return;
}
}
});
return result;
}
suiteSetup(function() {
realL10n = navigator.mozL10n;
navigator.mozL10n = MockMozL10n;
real_ = window._;
window._ = navigator.mozL10n.get;
realLoader = window.Loader;
window.Loader = MockLoader;
navigator.mozContacts = MockMozContacts;
sinon.spy(MockExportStrategy, 'shouldShowProgress');
sinon.spy(MockExportStrategy, 'doExport');
sinon.spy(MockExportStrategy, 'hasDeterminativeProgress');
sinon.spy(MockExportStrategy, 'setProgressStep');
if (!window.utils) {
window.utils = {};
}
window.utils.time = {
pretty: function(date) {
return date;
}
};
window.utils.overlay = {
show: function() {
return {
setTotal: function(l) {}
};
},
hide: function() {},
showMenu: function() {}
};
window.utils.status = {
show: function(msg) {},
hide: function() {}
};
sinon.spy(window.utils.status, 'show');
mocksHelperForExporter.suiteSetup();
});
suiteTeardown(function() {
window.navigator.mozL10n = realL10n;
window.Loader = realLoader;
MockExportStrategy.shouldShowProgress.restore();
MockExportStrategy.doExport.restore();
MockExportStrategy.hasDeterminativeProgress.restore();
MockExportStrategy.setProgressStep.restore();
mocksHelperForExporter.suiteTeardown();
});
setup(function() {
this.sinon.stub(ContactsService, 'getAll', function(cb) {
var contacts = MockContactsList();
setTimeout(function() {
cb(null, contacts);
});
});
menuOverlay = document.createElement('form');
menuOverlay.innerHTML = '<menu>' +
'<button data-l10n-id="cancel" id="cancel-overlay">Cancel</button>' +
'</menu>';
document.body.appendChild(menuOverlay);
subject = new ContactsExporter(MockExportStrategy);
MockExportStrategy.shouldShowProgress.reset();
MockExportStrategy.doExport.reset();
MockExportStrategy.hasDeterminativeProgress.reset();
MockExportStrategy.setProgressStep.reset();
});
teardown(function() {
menuOverlay.parentNode.removeChild(menuOverlay);
});
test('Correct initialization given an array of ids', function(done) {
subject.init(ids, function onInitDone(contacts) {
var expectedContacts = getContactsForIds(ids);
assert.lengthOf(contacts, 2);
assert.notStrictEqual(expectedContacts, contacts);
done();
});
});
suite('Strategy with deterministic progress >', function() {
setup(function(done) {
subject.init(ids, function onInitDone(contacts) {
subject.start();
done();
});
});
test('Progress bar is shown', function() {
assert.ok(MockExportStrategy.shouldShowProgress.calledOnce);
});
test('Export is attempted', function() {
assert.ok(MockExportStrategy.doExport.calledOnce);
});
test('The progress type is checked', function() {
assert.ok(MockExportStrategy.hasDeterminativeProgress.calledOnce);
});
test('Progress bar updates value', function() {
assert.ok(MockExportStrategy.setProgressStep.calledOnce);
});
test('Status shown', function() {
assert.isTrue(window.utils.status.show.called);
});
});
suite('Strategy with no deterministic progress >', function() {
setup(function(done) {
subject.init(ids, function onInitDone(contacts) {
MockExportStrategy.determinativeValue = false;
subject.start();
done();
});
});
teardown(function() {
MockExportStrategy.determinativeValue = true;
});
test('Progress bar is shown', function() {
assert.ok(MockExportStrategy.shouldShowProgress.calledOnce);
});
test('Export is attempted', function() {
assert.ok(MockExportStrategy.doExport.calledOnce);
});
test('The progress type is checked', function() {
assert.ok(MockExportStrategy.hasDeterminativeProgress.calledOnce);
});
test('Progress bar never updated', function() {
assert.ok(MockExportStrategy.setProgressStep.callCount === 0);
});
test('Status shown', function() {
assert.isTrue(window.utils.status.show.called);
});
});
suite('Error handling >', function() {
var error,
errorName;
setup(function(done) {
sinon.spy(MockConfirmDialog, 'show');
subject.init(ids, function onInitDone(contacts) {
error = {
'reason': 'BIGerror'
};
errorName = 'exportError-' +
MockExportStrategy.name + '-' +
error.reason;
MockExportStrategy.setError(error);
subject.start();
done();
});
});
teardown(function() {
MockConfirmDialog.show.restore();
});
test('Error dialog is called', function() {
assert.ok(MockConfirmDialog.show.calledOnce);
});
test('The proper error shows', function() {
// errors are called with the structure
// {title, error, retry, cancel}
assert.equal(MockConfirmDialog.show.args[0][1], errorName);
});
test('Status shown', function() {
assert.isTrue(window.utils.status.show.called);
});
});
});

View file

@ -0,0 +1,24 @@
/* exported MockContactToVcarBlob, MockGetStorageIfAvailable,
MockGetUnusedFilename, MockGetStorageIfAvailableError */
'use strict';
var MockGetStorageIfAvailable = function(type, size, callback) {
callback(navigator.getDeviceStorage());
};
var MockGetStorageIfAvailableError = function(type, size, callback, cbErr) {
if (cbErr) {
cbErr(0); // Simulate no space error
} else {
callback(navigator.getDeviceStorage());
}
};
var MockGetUnusedFilename = function(storage, filename, callback) {
callback(filename);
};
var MockContactToVcarBlob = function(contacts, callback) {
callback({ size: contacts.length });
};

View file

@ -0,0 +1,223 @@
/* globals ContactsSDExport, MockgetDeviceStorage, MockGetStorageIfAvailable,
MockGetStorageIfAvailableError, MockGetUnusedFilename */
'use strict';
requireApp('communications/contacts/js/export/sd.js');
requireApp('communications/contacts/test/unit/mock_get_device_storage.js');
requireApp('communications/contacts/test/unit/export/mock_export_utils.js');
suite('Sd export', function() {
var subject;
var realDeviceStorage = null;
var c1 = {
familyName: ['foo'],
givenName: ['bar']
};
var c2 = { givenName: ['bar'] };
var c3 = { familyName: ['foo'] };
var c4 = {};
var updateSpy = null;
var progressMock = function dummy() {};
var realContactToVcard = null;
var real_ = null;
var realgetStorageIfAvailable = null;
var realgetUnusedFilename = null;
var menuOverlay = null;
suiteSetup(function() {
// Device storage mock
realDeviceStorage = navigator.getDeviceStorage;
navigator.getDeviceStorage = MockgetDeviceStorage;
// L10n mock
real_ = window._;
window._ = function() {};
// getStorageIfAvailable mock
realgetStorageIfAvailable = window.getStorageIfAvailable;
window.getStorageIfAvailable = MockGetStorageIfAvailable;
// getUnusedFilename mock
realgetUnusedFilename = window.getUnusedFilename;
window.getUnusedFilename = MockGetUnusedFilename;
});
suiteTeardown(function() {
navigator.getDeviceStorage = realDeviceStorage;
window._ = real_;
window.getStorageIfAvailable = realgetStorageIfAvailable;
window.getUnusedFilename = realgetUnusedFilename;
});
setup(function() {
menuOverlay = document.createElement('form');
menuOverlay.innerHTML = '<menu>' +
'<button data-l10n-id="cancel" id="cancel-overlay">Cancel</button>' +
'</menu>';
document.body.appendChild(menuOverlay);
subject = new ContactsSDExport();
subject.setProgressStep(progressMock);
realContactToVcard = window.ContactToVcard;
window.ContactToVcard = function() {};
updateSpy = this.sinon.stub(
window,
'ContactToVcard',
function(contacts, append, finish) {
finish();
append(' ', contacts.length);
}
);
});
teardown(function() {
window.ContactToVcard = realContactToVcard;
menuOverlay.parentNode.removeChild(menuOverlay);
});
test('Calling with 1 contact', function(done) {
subject.setContactsToExport([c1]);
subject.doExport(function onFinish(error, exported, msg) {
done(function() {
assert.equal(false, subject.hasDeterminativeProgress());
assert.equal(1, updateSpy.callCount);
assert.isNull(error);
assert.equal(1, exported);
});
});
});
test('Calling with 1 contact with no given name', function(done) {
subject.setContactsToExport([c2]);
subject.doExport(function onFinish(error, exported, msg) {
done(function() {
assert.equal(false, subject.hasDeterminativeProgress());
assert.equal(1, updateSpy.callCount);
assert.isNull(error);
assert.equal(1, exported);
});
});
});
test('Calling with 1 contact with no family name', function(done) {
subject.setContactsToExport([c3]);
subject.doExport(function onFinish(error, exported, msg) {
done(function() {
assert.equal(false, subject.hasDeterminativeProgress());
assert.equal(1, updateSpy.callCount);
assert.isNull(error);
assert.equal(1, exported);
});
});
});
test('Calling with several contacts', function(done) {
var contacts = [c1, c2, c3, c4];
subject.setContactsToExport(contacts);
subject.doExport(function onFinish(error, exported, msg) {
done(function() {
assert.equal(1, updateSpy.callCount);
assert.isNull(error);
assert.equal(contacts.length, exported);
});
});
});
test('Calling with cancel flag activated', function(done) {
subject.setContactsToExport([c1]);
subject.cancelExport();
subject.doExport(function onFinish(error, exported, msg) {
done(function() {
assert.equal(1, updateSpy.callCount);
assert.isNull(error);
assert.equal(exported, 0);
});
});
});
});
suite('Sd export error', function() {
var subject;
var realDeviceStorage = null;
var c1 = {
familyName: ['foo'],
givenName: ['bar']
};
var updateSpy = null;
var progressMock = function dummy() {};
var realContactToVcard = null;
var real_ = null;
var realgetStorageIfAvailable = null;
var realgetUnusedFilename = null;
var menuOverlay = null;
suiteSetup(function() {
// Device storage mock
realDeviceStorage = navigator.getDeviceStorage;
navigator.getDeviceStorage = MockgetDeviceStorage;
// L10n mock
real_ = window._;
window._ = function() {};
// getStorageIfAvailable mock
realgetStorageIfAvailable = window.getStorageIfAvailable;
window.getStorageIfAvailable = MockGetStorageIfAvailableError;
// getUnusedFilename mock
realgetUnusedFilename = window.getUnusedFilename;
window.getUnusedFilename = MockGetUnusedFilename;
});
suiteTeardown(function() {
navigator.getDeviceStorage = realDeviceStorage;
window._ = real_;
window.getStorageIfAvailable = realgetStorageIfAvailable;
window.getUnusedFilename = realgetUnusedFilename;
});
setup(function() {
menuOverlay = document.createElement('form');
menuOverlay.innerHTML = '<menu>' +
'<button data-l10n-id="cancel" id="cancel-overlay">Cancel</button>' +
'</menu>';
document.body.appendChild(menuOverlay);
subject = new ContactsSDExport();
subject.setProgressStep(progressMock);
realContactToVcard = window.ContactToVcard;
window.ContactToVcard = function() {};
updateSpy = this.sinon.stub(
window,
'ContactToVcard',
function(contacts, append, finish) {
finish();
append(' ', contacts.length);
}
);
});
teardown(function() {
window.ContactToVcard = realContactToVcard;
menuOverlay.parentNode.removeChild(menuOverlay);
});
test('Calling with error', function(done) {
subject.setContactsToExport([c1]);
subject.doExport(function onFinish(error, exported, isRecoverable) {
assert.isNotNull(error);
assert.equal(error.reason, 'noSpace');
assert.equal(0, exported);
assert.equal(isRecoverable, true);
done();
});
});
});

View file

@ -0,0 +1,224 @@
'use strict';
/* global ContactsSIMExport */
/* global MockMozContacts */
requireApp('communications/contacts/services/contacts.js');
requireApp('communications/contacts/js/export/sim.js');
require('/shared/test/unit/mocks/mock_mozContacts.js');
suite('Sim export', function() {
var realMozContacts = null;
var c1 = {}, c2 = {};
var progressMock = function dummy() {};
var iccContactId = '1234567';
var iccid = '999999999';
function getIccContactUrl(iccid, iccContactId) {
return 'urn:uuid:' + iccid + '-' + iccContactId;
}
function setupManagerAndSubject(toExport) {
var iccManager = new IccManager();
var updateSpy = sinon.spy(iccManager, 'updateContact');
var subject = new ContactsSIMExport(iccManager);
subject.setProgressStep(progressMock);
subject.setContactsToExport(toExport);
return {
subject: subject,
manager: iccManager,
updateSpy: updateSpy
};
}
function IccManager() {
this.calledCount = 0,
this.faulty = false,
this.simFull = false,
this.updateContact = function(type, contact) {
var self = this;
return {
result: {
id: iccContactId
},
set onsuccess(cb) {
self.calledCount++;
if ((!self.faulty && !self.simFull) || self.calledCount % 2 !== 0) {
window.setTimeout(cb);
}
},
set onerror(cb) {
if (self.faulty && self.calledCount % 2 === 0) {
this.error = {
name: 'ContactTypeNotSupported'
};
window.setTimeout(function() {
cb({
target: this
});
}.bind(this));
return;
}
if (self.simFull && self.calledCount % 2 === 0) {
this.error = {
name: 'NoFreeRecordFound'
};
window.setTimeout(function() {
cb({
target: this
});
}.bind(this));
}
}
};
};
this.iccInfo = {
iccid: iccid
};
}
var iccContactIdUrl = {
type: ['source', 'sim'],
value: getIccContactUrl(iccid, iccContactId)
};
suiteSetup(function() {
realMozContacts = navigator.mozContacts;
navigator.mozContacts = MockMozContacts;
});
suiteTeardown(function() {
navigator.mozContacts = realMozContacts;
});
test('Calling with 1 contact', function(done) {
var obj = setupManagerAndSubject([c1]);
obj.subject.doExport(function onFinish(error, exported) {
assert.equal(false, obj.subject.hasDeterminativeProgress());
assert.ok(obj.updateSpy.calledOnce);
assert.isNull(error);
assert.equal(1, exported);
done();
});
});
test('Calling with several contacts', function(done) {
var contacts = [c1, c2];
var obj = setupManagerAndSubject(contacts);
obj.subject.doExport(function onFinish(error, exported) {
assert.ok(obj.subject.hasDeterminativeProgress());
assert.equal(contacts.length, obj.updateSpy.callCount);
assert.isNull(error);
assert.equal(contacts.length, exported);
done();
});
});
test('If SIM Card is full the error is reported properly', function(done) {
var contacts = [c1, c2];
var obj = setupManagerAndSubject(contacts);
obj.manager.simFull = true;
obj.subject.doExport(function onFinish(error, exported, recoverable) {
assert.ok(obj.subject.hasDeterminativeProgress());
assert.equal(error.reason, 'NoFreeRecordFound');
assert.equal(recoverable, false);
assert.equal(1, exported);
done();
});
});
test('Recovering from error updating in IccManager', function(done) {
var contacts = [c1, c2, c1, c2];
var obj = setupManagerAndSubject(contacts);
obj.manager.faulty = true;
obj.subject.doExport(function onFinish(error, exported) {
assert.ok(obj.subject.hasDeterminativeProgress());
assert.equal(contacts.length, obj.updateSpy.callCount);
// We do not have an error
assert.isNull(error);
// The number of exported contacts is not the total
assert.equal(contacts.length / 2, exported);
done();
});
});
test('Updating a Contact that has not a previous iccContactId. URL created',
function(done) {
var obj = setupManagerAndSubject([c1]);
obj.subject.doExport(function onFinish(error, exported) {
assert.deepEqual(c1.url[0], iccContactIdUrl);
done();
});
});
test('Updating a Contact that has a previous iccContactId. URL kept as it is',
function(done) {
var contactToExport = {
url: [
iccContactIdUrl
]
};
var obj = setupManagerAndSubject([contactToExport]);
obj.subject.doExport(function onFinish(error, exported) {
assert.equal(contactToExport.url.length, 1);
assert.deepEqual(contactToExport.url[0], iccContactIdUrl);
done();
});
});
test(
'Updating a Contact that has a previous iccContactId from a different SIM',
function(done) {
var contactToExport = {
url: [{
type: ['source', 'sim']
}]
};
contactToExport.url[0].value = getIccContactUrl('98765', '77777');
var contactToExportOriginalUrl = contactToExport.url[0];
var obj = setupManagerAndSubject([contactToExport]);
obj.subject.doExport(function onFinish(error, exported) {
assert.equal(contactToExport.url.length, 2);
assert.deepEqual(contactToExport.url[0], contactToExportOriginalUrl);
assert.deepEqual(contactToExport.url[1], iccContactIdUrl);
done();
});
});
test('Calling with cancel flag activated', function(done) {
var contacts = [c1, c2, c1, c2, c1];
var exportedContacts = 2;
var callNum = 0;
// Replacing the progress function to allow simulating the click of the
// cancel button on the nth call
var progressMockForCancel = function() {
callNum++;
if (callNum === exportedContacts) {
obj.subject.cancelExport();
}
};
var obj = setupManagerAndSubject(contacts);
obj.subject.setProgressStep(progressMockForCancel);
obj.subject.doExport(function onFinish(error, exported) {
assert.equal(exportedContacts, obj.updateSpy.callCount);
assert.isNull(error);
assert.equal(exportedContacts, exported);
done();
});
});
});