Backed out changeset 56aa054d4cc0 (bug 1399367) for browser/extensions/formautofill/test/unit/test_activeStatus.js failures. CLOSED TREE

This commit is contained in:
Csoregi Natalia 2018-09-05 05:47:21 +03:00
parent 6e8f3beb98
commit 0ee540d6b5
27 changed files with 548 additions and 520 deletions

View File

@ -63,16 +63,16 @@ class TempCollection {
return this._data[guid];
}
async update(guid, record, preserveOldProperties) {
update(guid, record, preserveOldProperties) {
let recordToSave = Object.assign(preserveOldProperties ? this._data[guid] : {}, record);
await this._formAutofillCollection.computeFields(recordToSave);
this._formAutofillCollection.computeFields(recordToSave);
return (this._data[guid] = recordToSave);
}
async add(record) {
add(record) {
let guid = "temp-" + Math.abs(Math.random() * 0xffffffff|0);
let recordToSave = Object.assign({guid}, record);
await this._formAutofillCollection.computeFields(recordToSave);
this._formAutofillCollection.computeFields(recordToSave);
this._data[guid] = recordToSave;
return guid;
}
@ -95,12 +95,14 @@ var paymentDialogWrapper = {
]),
/**
* Note: This method is async because formAutofillStorage plans to become async.
*
* @param {string} guid
* @returns {object} containing only the requested payer values.
*/
async _convertProfileAddressToPayerData(guid) {
let addressData = this.temporaryStore.addresses.get(guid) ||
await formAutofillStorage.addresses.get(guid);
formAutofillStorage.addresses.get(guid);
if (!addressData) {
throw new Error(`Payer address not found: ${guid}`);
}
@ -121,12 +123,14 @@ var paymentDialogWrapper = {
},
/**
* Note: This method is async because formAutofillStorage plans to become async.
*
* @param {string} guid
* @returns {nsIPaymentAddress}
*/
async _convertProfileAddressToPaymentAddress(guid) {
let addressData = this.temporaryStore.addresses.get(guid) ||
await formAutofillStorage.addresses.get(guid);
formAutofillStorage.addresses.get(guid);
if (!addressData) {
throw new Error(`Shipping address not found: ${guid}`);
}
@ -154,7 +158,7 @@ var paymentDialogWrapper = {
*/
async _convertProfileBasicCardToPaymentMethodData(guid, cardSecurityCode) {
let cardData = this.temporaryStore.creditCards.get(guid) ||
await formAutofillStorage.creditCards.get(guid);
formAutofillStorage.creditCards.get(guid);
if (!cardData) {
throw new Error(`Basic card not found in storage: ${guid}`);
}
@ -317,17 +321,17 @@ var paymentDialogWrapper = {
return component.createInstance(componentInterface);
},
async fetchSavedAddresses() {
fetchSavedAddresses() {
let savedAddresses = {};
for (let address of await formAutofillStorage.addresses.getAll()) {
for (let address of formAutofillStorage.addresses.getAll()) {
savedAddresses[address.guid] = address;
}
return savedAddresses;
},
async fetchSavedPaymentCards() {
fetchSavedPaymentCards() {
let savedBasicCards = {};
for (let card of await formAutofillStorage.creditCards.getAll()) {
for (let card of formAutofillStorage.creditCards.getAll()) {
savedBasicCards[card.guid] = card;
// Filter out the encrypted card number since the dialog content is
// considered untrusted and runs in a content process.
@ -341,13 +345,10 @@ var paymentDialogWrapper = {
return savedBasicCards;
},
async onAutofillStorageChange() {
let [savedAddresses, savedBasicCards] =
await Promise.all([this.fetchSavedAddresses(), this.fetchSavedPaymentCards()]);
onAutofillStorageChange() {
this.sendMessageToContent("updateState", {
savedAddresses,
savedBasicCards,
savedAddresses: this.fetchSavedAddresses(),
savedBasicCards: this.fetchSavedPaymentCards(),
});
},
@ -445,24 +446,21 @@ var paymentDialogWrapper = {
return obj;
},
async initializeFrame() {
Services.obs.addObserver(this, "formautofill-storage-changed", true);
initializeFrame() {
let requestSerialized = this._serializeRequest(this.request);
let chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
let isPrivate = PrivateBrowsingUtils.isWindowPrivate(chromeWindow);
let [savedAddresses, savedBasicCards] =
await Promise.all([this.fetchSavedAddresses(), this.fetchSavedPaymentCards()]);
this.sendMessageToContent("showPaymentRequest", {
request: requestSerialized,
savedAddresses,
savedAddresses: this.fetchSavedAddresses(),
tempAddresses: this.temporaryStore.addresses.getAll(),
savedBasicCards,
savedBasicCards: this.fetchSavedPaymentCards(),
tempBasicCards: this.temporaryStore.creditCards.getAll(),
isPrivate,
});
Services.obs.addObserver(this, "formautofill-storage-changed", true);
},
debugFrame() {
@ -567,6 +565,16 @@ var paymentDialogWrapper = {
stateChange: {},
};
try {
if (collectionName == "creditCards" && !guid && !record.isTemporary) {
// We need to be logged in so we can encrypt the credit card number and
// that's only supported when we're adding a new record.
// TODO: "MasterPassword.ensureLoggedIn" can be removed after the storage
// APIs are refactored to be async functions (bug 1399367).
if (!await MasterPassword.ensureLoggedIn()) {
throw new Error("User canceled master password entry");
}
}
let isTemporary = record.isTemporary;
let collection = isTemporary ? this.temporaryStore[collectionName] :
formAutofillStorage[collectionName];

View File

@ -10,7 +10,7 @@ async function setup() {
[PTU.Addresses.TimBL], [PTU.BasicCards.JohnDoe]);
info("associating the card with the billing address");
await formAutofillStorage.creditCards.update(prefilledGuids.card1GUID, {
formAutofillStorage.creditCards.update(prefilledGuids.card1GUID, {
billingAddressGUID: prefilledGuids.address1GUID,
}, true);

View File

@ -5,7 +5,7 @@ async function setup() {
let prefilledGuids = await addSampleAddressesAndBasicCard();
info("associating the card with the billing address");
await formAutofillStorage.creditCards.update(prefilledGuids.card1GUID, {
formAutofillStorage.creditCards.update(prefilledGuids.card1GUID, {
billingAddressGUID: prefilledGuids.address1GUID,
}, true);
}
@ -321,7 +321,7 @@ add_task(async function test_address_edit() {
info("initial addressOptions: " + JSON.stringify(addressOptions));
selectedIndex = addressOptions.selectedOptionIndex;
let selectedAddressGuid = addressOptions.options[selectedIndex].guid;
let selectedAddress = await formAutofillStorage.addresses.get(selectedAddressGuid);
let selectedAddress = formAutofillStorage.addresses.get(selectedAddressGuid);
is(selectedIndex, 0, "First address should be selected");
ok(selectedAddress, "Selected address does exist in the address collection");
@ -339,7 +339,7 @@ add_task(async function test_address_edit() {
let newSelectedAddressGuid = addressOptions.options[selectedIndex].guid;
is(newSelectedAddressGuid, selectedAddressGuid, "Selected guid hasnt changed");
selectedAddress = await formAutofillStorage.addresses.get(selectedAddressGuid);
selectedAddress = formAutofillStorage.addresses.get(selectedAddressGuid);
is(selectedIndex, 0, "First address should be selected");
is(selectedAddress.country, "CA", "Expected changed country value");

View File

@ -8,12 +8,12 @@ const details = PTU.Details.total60USD;
add_task(async function test_initial_state() {
let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "add");
let address1GUID = await formAutofillStorage.addresses.add(PTU.Addresses.TimBL);
let address1GUID = formAutofillStorage.addresses.add(PTU.Addresses.TimBL);
await onChanged;
onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "add");
let card1GUID = await formAutofillStorage.creditCards.add(PTU.BasicCards.JohnDoe);
let card1GUID = formAutofillStorage.creditCards.add(PTU.BasicCards.JohnDoe);
await onChanged;
await BrowserTestUtils.withNewTab({
@ -56,7 +56,7 @@ add_task(async function test_initial_state() {
let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "add");
info("adding an address");
let address2GUID = await formAutofillStorage.addresses.add(PTU.Addresses.TimBL2);
let address2GUID = formAutofillStorage.addresses.add(PTU.Addresses.TimBL2);
await onChanged;
await spawnPaymentDialogTask(frame, async function checkAdd({
@ -65,17 +65,11 @@ add_task(async function test_initial_state() {
card1GUID,
}) {
info("checkAdd");
let {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
let contentWin = Cu.waiveXrays(content);
let {
savedAddresses,
savedBasicCards,
} = await PTU.DialogContentUtils.waitForState(
content,
state => !!state.savedAddresses[address2GUID]
);
} = contentWin.document.querySelector("payment-dialog").requestStore.getState();
let addressGUIDs = Object.keys(savedAddresses);
is(addressGUIDs.length, 2, "Now two savedAddresses");
@ -97,7 +91,7 @@ add_task(async function test_initial_state() {
onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "update");
info("updating the credit expiration");
await formAutofillStorage.creditCards.update(card1GUID, {
formAutofillStorage.creditCards.update(card1GUID, {
"cc-exp-month": 6,
"cc-exp-year": 2029,
}, true);
@ -109,17 +103,11 @@ add_task(async function test_initial_state() {
card1GUID,
}) {
info("checkUpdate");
let {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
let contentWin = Cu.waiveXrays(content);
let {
savedAddresses,
savedBasicCards,
} = await PTU.DialogContentUtils.waitForState(
content,
state => !!state.savedAddresses[address2GUID]
);
} = contentWin.document.querySelector("payment-dialog").requestStore.getState();
let addressGUIDs = Object.keys(savedAddresses);
is(addressGUIDs.length, 2, "Still two savedAddresses");
@ -151,17 +139,11 @@ add_task(async function test_initial_state() {
card1GUID,
}) {
info("checkRemove");
let {
PaymentTestUtils: PTU,
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
let contentWin = Cu.waiveXrays(content);
let {
savedAddresses,
savedBasicCards,
} = await PTU.DialogContentUtils.waitForState(
content,
state => !!state.savedAddresses[address2GUID]
);
} = contentWin.document.querySelector("payment-dialog").requestStore.getState();
is(Object.keys(savedAddresses).length, 1, "Now one savedAddresses");
is(savedAddresses[address2GUID].name, "Timothy Johann Berners-Lee", "Check full name");

View File

@ -46,7 +46,7 @@ add_task(async function test_show_completePayment() {
let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "update");
info("associating the card with the billing address");
await formAutofillStorage.creditCards.update(card1GUID, {
formAutofillStorage.creditCards.update(card1GUID, {
billingAddressGUID: address1GUID,
}, true);
await onChanged;

View File

@ -142,7 +142,7 @@ function spawnTaskInNewDialog(requestId, contentTaskFn, args = null) {
async function addAddressRecord(address) {
let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "add");
let guid = await formAutofillStorage.addresses.add(address);
let guid = formAutofillStorage.addresses.add(address);
await onChanged;
return guid;
}
@ -150,7 +150,7 @@ async function addAddressRecord(address) {
async function addCardRecord(card) {
let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "add");
let guid = await formAutofillStorage.creditCards.add(card);
let guid = formAutofillStorage.creditCards.add(card);
await onChanged;
return guid;
}

View File

@ -31,7 +31,7 @@ XPCOMUtils.defineLazyPreferenceGetter(this, "logLevel", "extensions.formautofill
// This helper avoids both of those problems by never touching the
// console object unless debug logging is enabled.
function debug() {
if (logLevel.toLowerCase() == "debug") {
if (logLevel == "debug") {
this.log.debug(...arguments);
}
}

View File

@ -191,7 +191,6 @@ FormAutofillParent.prototype = {
* Update the status and trigger _onStatusChanged, if necessary.
*/
_updateStatus() {
log.debug("_updateStatus");
let wasActive = this._active;
this._active = this._computeStatus();
if (this._active !== wasActive) {
@ -209,27 +208,29 @@ FormAutofillParent.prototype = {
async receiveMessage({name, data, target}) {
switch (name) {
case "FormAutofill:InitStorage": {
await this.formAutofillStorage.initialize();
this.formAutofillStorage.initialize();
break;
}
case "FormAutofill:GetRecords": {
await this._getRecords(data, target);
this._getRecords(data, target);
break;
}
case "FormAutofill:SaveAddress": {
if (data.guid) {
await this.formAutofillStorage.addresses.update(data.guid, data.address);
this.formAutofillStorage.addresses.update(data.guid, data.address);
} else {
await this.formAutofillStorage.addresses.add(data.address);
this.formAutofillStorage.addresses.add(data.address);
}
break;
}
case "FormAutofill:SaveCreditCard": {
// TODO: "MasterPassword.ensureLoggedIn" can be removed after the storage
// APIs are refactored to be async functions (bug 1399367).
if (!await MasterPassword.ensureLoggedIn()) {
log.warn("User canceled master password entry");
return;
}
await this.formAutofillStorage.creditCards.add(data.creditcard);
this.formAutofillStorage.creditCards.add(data.creditcard);
break;
}
case "FormAutofill:RemoveAddresses": {
@ -241,7 +242,7 @@ FormAutofillParent.prototype = {
break;
}
case "FormAutofill:OnFormSubmit": {
await this._onFormSubmit(data, target);
this._onFormSubmit(data, target);
break;
}
case "FormAutofill:OpenPreferences": {
@ -311,7 +312,7 @@ FormAutofillParent.prototype = {
return;
}
let recordsInCollection = await collection.getAll();
let recordsInCollection = collection.getAll();
if (!info || !info.fieldName || !recordsInCollection.length) {
target.sendAsyncMessage("FormAutofill:Records", recordsInCollection);
return;
@ -355,43 +356,60 @@ FormAutofillParent.prototype = {
_updateSavedFieldNames() {
log.debug("_updateSavedFieldNames");
if (!Services.ppmm.initialProcessData.autofillSavedFieldNames) {
Services.ppmm.initialProcessData.autofillSavedFieldNames = new Set();
} else {
Services.ppmm.initialProcessData.autofillSavedFieldNames.clear();
}
Services.ppmm.initialProcessData.autofillSavedFieldNames =
new Set([...this.formAutofillStorage.addresses.getSavedFieldNames(),
...this.formAutofillStorage.creditCards.getSavedFieldNames()]);
["addresses", "creditCards"].forEach(c => {
this.formAutofillStorage[c].getAll().forEach((record) => {
Object.keys(record).forEach((fieldName) => {
if (!record[fieldName]) {
return;
}
Services.ppmm.initialProcessData.autofillSavedFieldNames.add(fieldName);
});
});
});
// Remove the internal guid and metadata fields.
this.formAutofillStorage.INTERNAL_FIELDS.forEach((fieldName) => {
Services.ppmm.initialProcessData.autofillSavedFieldNames.delete(fieldName);
});
Services.ppmm.broadcastAsyncMessage("FormAutofill:savedFieldNames",
Services.ppmm.initialProcessData.autofillSavedFieldNames);
this._updateStatus();
},
async _onAddressSubmit(address, target, timeStartedFillingMS) {
_onAddressSubmit(address, target, timeStartedFillingMS) {
let showDoorhanger = null;
if (address.guid) {
// Avoid updating the fields that users don't modify.
let originalAddress = await this.formAutofillStorage.addresses.get(address.guid);
let originalAddress = this.formAutofillStorage.addresses.get(address.guid);
for (let field in address.record) {
if (address.untouchedFields.includes(field) && originalAddress[field]) {
address.record[field] = originalAddress[field];
}
}
if (!await this.formAutofillStorage.addresses.mergeIfPossible(address.guid, address.record, true)) {
if (!this.formAutofillStorage.addresses.mergeIfPossible(address.guid, address.record, true)) {
this._recordFormFillingTime("address", "autofill-update", timeStartedFillingMS);
showDoorhanger = async () => {
const description = FormAutofillUtils.getAddressLabel(address.record);
const state = await FormAutofillDoorhanger.show(target, "updateAddress", description);
let changedGUIDs = await this.formAutofillStorage.addresses.mergeToStorage(address.record, true);
let changedGUIDs = this.formAutofillStorage.addresses.mergeToStorage(address.record, true);
switch (state) {
case "create":
if (!changedGUIDs.length) {
changedGUIDs.push(await this.formAutofillStorage.addresses.add(address.record));
changedGUIDs.push(this.formAutofillStorage.addresses.add(address.record));
}
break;
case "update":
if (!changedGUIDs.length) {
await this.formAutofillStorage.addresses.update(address.guid, address.record, true);
this.formAutofillStorage.addresses.update(address.guid, address.record, true);
changedGUIDs.push(address.guid);
} else {
this.formAutofillStorage.addresses.remove(address.guid);
@ -409,9 +427,9 @@ FormAutofillParent.prototype = {
Services.telemetry.scalarAdd("formautofill.addresses.fill_type_autofill", 1);
}
} else {
let changedGUIDs = await this.formAutofillStorage.addresses.mergeToStorage(address.record);
let changedGUIDs = this.formAutofillStorage.addresses.mergeToStorage(address.record);
if (!changedGUIDs.length) {
changedGUIDs.push(await this.formAutofillStorage.addresses.add(address.record));
changedGUIDs.push(this.formAutofillStorage.addresses.add(address.record));
}
changedGUIDs.forEach(guid => this.formAutofillStorage.addresses.notifyUsed(guid));
this._recordFormFillingTime("address", "manual", timeStartedFillingMS);
@ -437,7 +455,7 @@ FormAutofillParent.prototype = {
return showDoorhanger;
},
async _onCreditCardSubmit(creditCard, target, timeStartedFillingMS) {
_onCreditCardSubmit(creditCard, target, timeStartedFillingMS) {
// Updates the used status for shield/heartbeat to recognize users who have
// used Credit Card Autofill.
let setUsedStatus = status => {
@ -458,7 +476,7 @@ FormAutofillParent.prototype = {
// Indicate that the user has used Credit Card Autofill to fill in a form.
setUsedStatus(3);
let originalCCData = await this.formAutofillStorage.creditCards.get(creditCard.guid);
let originalCCData = this.formAutofillStorage.creditCards.get(creditCard.guid);
let recordUnchanged = true;
for (let field in creditCard.record) {
if (creditCard.record[field] === "" && !originalCCData[field]) {
@ -496,7 +514,7 @@ FormAutofillParent.prototype = {
}
// Early return if it's a duplicate data
let dupGuid = await this.formAutofillStorage.creditCards.getDuplicateGuid(creditCard.record);
let dupGuid = this.formAutofillStorage.creditCards.getDuplicateGuid(creditCard.record);
if (dupGuid) {
this.formAutofillStorage.creditCards.notifyUsed(dupGuid);
return false;
@ -530,6 +548,8 @@ FormAutofillParent.prototype = {
return;
}
// TODO: "MasterPassword.ensureLoggedIn" can be removed after the storage
// APIs are refactored to be async functions (bug 1399367).
if (!await MasterPassword.ensureLoggedIn()) {
log.warn("User canceled master password entry");
return;
@ -538,15 +558,15 @@ FormAutofillParent.prototype = {
let changedGUIDs = [];
if (creditCard.guid) {
if (state == "update") {
await this.formAutofillStorage.creditCards.update(creditCard.guid, creditCard.record, true);
this.formAutofillStorage.creditCards.update(creditCard.guid, creditCard.record, true);
changedGUIDs.push(creditCard.guid);
} else if ("create") {
changedGUIDs.push(await this.formAutofillStorage.creditCards.add(creditCard.record));
changedGUIDs.push(this.formAutofillStorage.creditCards.add(creditCard.record));
}
} else {
changedGUIDs.push(...await this.formAutofillStorage.creditCards.mergeToStorage(creditCard.record));
changedGUIDs.push(...this.formAutofillStorage.creditCards.mergeToStorage(creditCard.record));
if (!changedGUIDs.length) {
changedGUIDs.push(await this.formAutofillStorage.creditCards.add(creditCard.record));
changedGUIDs.push(this.formAutofillStorage.creditCards.add(creditCard.record));
}
}
changedGUIDs.forEach(guid => this.formAutofillStorage.creditCards.notifyUsed(guid));
@ -568,8 +588,8 @@ FormAutofillParent.prototype = {
// Transmit the telemetry immediately in the meantime form submitted, and handle these pending
// doorhangers at a later.
await Promise.all([
await Promise.all(address.map(addrRecord => this._onAddressSubmit(addrRecord, target, timeStartedFillingMS))),
await Promise.all(creditCard.map(ccRecord => this._onCreditCardSubmit(ccRecord, target, timeStartedFillingMS))),
address.map(addrRecord => this._onAddressSubmit(addrRecord, target, timeStartedFillingMS)),
creditCard.map(ccRecord => this._onCreditCardSubmit(ccRecord, target, timeStartedFillingMS)),
].map(pendingDoorhangers => {
return pendingDoorhangers.filter(pendingDoorhanger => !!pendingDoorhanger &&
typeof pendingDoorhanger == "function");

View File

@ -262,13 +262,10 @@ class AutofillRecords {
this._collectionName = collectionName;
this._schemaVersion = schemaVersion;
Promise.all(this._data.map(record => this._migrateRecord(record)))
.then(hasChangesArr => {
let dataHasChanges = hasChangesArr.find(hasChanges => hasChanges);
if (dataHasChanges) {
this._store.saveSoon();
}
});
let hasChanges = (result, record) => this._migrateRecord(record) || result;
if (this._data.reduce(hasChanges, false)) {
this._store.saveSoon();
}
}
/**
@ -308,10 +305,10 @@ class AutofillRecords {
* The new record for saving.
* @param {boolean} [options.sourceSync = false]
* Did sync generate this addition?
* @returns {Promise<string>}
* @returns {string}
* The GUID of the newly added item..
*/
async add(record, {sourceSync = false} = {}) {
add(record, {sourceSync = false} = {}) {
this.log.debug("add:", record);
let recordToSave = this._clone(record);
@ -351,7 +348,7 @@ class AutofillRecords {
return this._saveRecord(recordToSave, {sourceSync});
}
async _saveRecord(record, {sourceSync = false} = {}) {
_saveRecord(record, {sourceSync = false} = {}) {
if (!record.guid) {
throw new Error("Record missing GUID");
}
@ -369,7 +366,7 @@ class AutofillRecords {
} else {
this._ensureMatchingVersion(record);
recordToSave = record;
await this.computeFields(recordToSave);
this.computeFields(recordToSave);
}
if (sourceSync) {
@ -405,10 +402,10 @@ class AutofillRecords {
* Indicates which record to update.
* @param {Object} record
* The new record used to overwrite the old one.
* @param {Promise<boolean>} [preserveOldProperties = false]
* @param {boolean} [preserveOldProperties = false]
* Preserve old record's properties if they don't exist in new record.
*/
async update(guid, record, preserveOldProperties = false) {
update(guid, record, preserveOldProperties = false) {
this.log.debug("update:", guid, record);
let recordFoundIndex = this._findIndexByGUID(guid);
@ -418,7 +415,7 @@ class AutofillRecords {
// Clone the record before modifying it to avoid exposing incomplete changes.
let recordFound = this._clone(this._data[recordFoundIndex]);
await this._stripComputedFields(recordFound);
this._stripComputedFields(recordFound);
let recordToUpdate = this._clone(record);
this._normalizeRecord(recordToUpdate, true);
@ -460,7 +457,7 @@ class AutofillRecords {
syncMetadata.changeCounter += 1;
}
await this.computeFields(recordFound);
this.computeFields(recordFound);
this._data[recordFoundIndex] = recordFound;
this._store.saveSoon();
@ -554,10 +551,10 @@ class AutofillRecords {
* @param {boolean} [options.rawData = false]
* Returns a raw record without modifications and the computed fields
* (this includes private fields)
* @returns {Promise<Object>}
* @returns {Object}
* A clone of the record.
*/
async get(guid, {rawData = false} = {}) {
get(guid, {rawData = false} = {}) {
this.log.debug("get:", guid, rawData);
let recordFound = this._findByGUID(guid);
@ -568,7 +565,7 @@ class AutofillRecords {
// The record is cloned to avoid accidental modifications from outside.
let clonedRecord = this._cloneAndCleanUp(recordFound);
if (rawData) {
await this._stripComputedFields(clonedRecord);
this._stripComputedFields(clonedRecord);
} else {
this._recordReadProcessor(clonedRecord);
}
@ -582,53 +579,25 @@ class AutofillRecords {
* Returns raw records without modifications and the computed fields.
* @param {boolean} [options.includeDeleted = false]
* Also return any tombstone records.
* @returns {Promise<Array.<Object>>}
* @returns {Array.<Object>}
* An array containing clones of all records.
*/
async getAll({rawData = false, includeDeleted = false} = {}) {
getAll({rawData = false, includeDeleted = false} = {}) {
this.log.debug("getAll", rawData, includeDeleted);
let records = this._data.filter(r => !r.deleted || includeDeleted);
// Records are cloned to avoid accidental modifications from outside.
let clonedRecords = records.map(r => this._cloneAndCleanUp(r));
await Promise.all(clonedRecords.map(async record => {
clonedRecords.forEach(record => {
if (rawData) {
await this._stripComputedFields(record);
this._stripComputedFields(record);
} else {
this._recordReadProcessor(record);
}
}));
});
return clonedRecords;
}
/**
* Return all saved field names in the collection. This method
* has to be sync because its caller _updateSavedFieldNames() needs
* to dispatch content message synchronously.
*
* @returns {Set} Set containing saved field names.
*/
getSavedFieldNames() {
this.log.debug("getSavedFieldNames");
let records = this._data.filter(r => !r.deleted);
records
.map(record => this._cloneAndCleanUp(record))
.forEach(record => this._recordReadProcessor(record));
let fieldNames = new Set();
for (let record of records) {
for (let fieldName of Object.keys(record)) {
if (INTERNAL_FIELDS.includes(fieldName) || !record[fieldName]) {
continue;
}
fieldNames.add(fieldName);
}
}
return fieldNames;
}
/**
* Functions intended to be used in the support of Sync.
*/
@ -755,7 +724,7 @@ class AutofillRecords {
*
* @param {number} index
* @param {Object} remoteRecord
* @param {Promise<boolean>} [options.keepSyncMetadata = false]
* @param {boolean} [options.keepSyncMetadata = false]
* Should we copy Sync metadata? This is true if `remoteRecord` is a
* merged record with local changes that we need to upload. Passing
* `keepSyncMetadata` retains the record's change counter and
@ -763,11 +732,11 @@ class AutofillRecords {
* the sync is interrupted after the record is merged, but before
* it's uploaded.
*/
async _replaceRecordAt(index, remoteRecord, {keepSyncMetadata = false} = {}) {
_replaceRecordAt(index, remoteRecord, {keepSyncMetadata = false} = {}) {
let localRecord = this._data[index];
let newRecord = this._clone(remoteRecord);
await this._stripComputedFields(newRecord);
this._stripComputedFields(newRecord);
this._data[index] = newRecord;
@ -801,7 +770,7 @@ class AutofillRecords {
}
}
await this.computeFields(newRecord);
this.computeFields(newRecord);
}
/**
@ -813,7 +782,7 @@ class AutofillRecords {
* @returns {string}
* A clone of the local record with a new GUID.
*/
async _forkLocalRecord(strippedLocalRecord) {
_forkLocalRecord(strippedLocalRecord) {
let forkedLocalRecord = this._cloneAndCleanUp(strippedLocalRecord);
forkedLocalRecord.guid = this._generateGUID();
@ -823,7 +792,7 @@ class AutofillRecords {
// uploaded.
this._getSyncMetaData(forkedLocalRecord, true);
await this.computeFields(forkedLocalRecord);
this.computeFields(forkedLocalRecord);
this._data.push(forkedLocalRecord);
return forkedLocalRecord;
@ -838,13 +807,13 @@ class AutofillRecords {
* must have a matching local record with the same GUID. Use
* `add` to insert remote records that don't exist locally, and
* `remove` to apply remote tombstones.
* @returns {Promise<Object>}
* @returns {Object}
* A `{forkedGUID}` tuple. `forkedGUID` is `null` if the merge
* succeeded without conflicts, or a new GUID referencing the
* existing locally modified record if the conflicts could not be
* resolved.
*/
async reconcile(remoteRecord) {
reconcile(remoteRecord) {
this._ensureMatchingVersion(remoteRecord);
if (remoteRecord.deleted) {
throw new Error(`Can't reconcile tombstone ${remoteRecord.guid}`);
@ -862,26 +831,26 @@ class AutofillRecords {
if (sync.changeCounter === 0) {
// Local not modified. Replace local with remote.
await this._replaceRecordAt(localIndex, remoteRecord, {
this._replaceRecordAt(localIndex, remoteRecord, {
keepSyncMetadata: false,
});
} else {
let strippedLocalRecord = this._clone(localRecord);
await this._stripComputedFields(strippedLocalRecord);
this._stripComputedFields(strippedLocalRecord);
let mergedRecord = this._mergeSyncedRecords(strippedLocalRecord, remoteRecord);
if (mergedRecord) {
// Local and remote modified, but we were able to merge. Replace the
// local record with the merged record.
await this._replaceRecordAt(localIndex, mergedRecord, {
this._replaceRecordAt(localIndex, mergedRecord, {
keepSyncMetadata: true,
});
} else {
// Merge conflict. Fork the local record, then replace the original
// with the merged record.
let forkedLocalRecord = await this._forkLocalRecord(strippedLocalRecord);
let forkedLocalRecord = this._forkLocalRecord(strippedLocalRecord);
forkedGUID = forkedLocalRecord.guid;
await this._replaceRecordAt(localIndex, remoteRecord, {
this._replaceRecordAt(localIndex, remoteRecord, {
keepSyncMetadata: false,
});
}
@ -1078,11 +1047,11 @@ class AutofillRecords {
*
* @param {Object} remoteRecord
* The remote record.
* @returns {Promise<string|null>}
* @returns {string|null}
* The GUID of the matching local record, or `null` if no records
* match.
*/
async findDuplicateGUID(remoteRecord) {
findDuplicateGUID(remoteRecord) {
if (!remoteRecord.guid) {
throw new Error("Record missing GUID");
}
@ -1108,7 +1077,7 @@ class AutofillRecords {
// Ignore computed fields when matching records as they aren't synced at all.
let strippedLocalRecord = this._clone(localRecord);
await this._stripComputedFields(strippedLocalRecord);
this._stripComputedFields(strippedLocalRecord);
let keys = new Set(Object.keys(remoteRecord));
for (let key of Object.keys(strippedLocalRecord)) {
@ -1174,7 +1143,7 @@ class AutofillRecords {
});
}
async _migrateRecord(record) {
_migrateRecord(record) {
let hasChanges = false;
if (record.deleted) {
@ -1193,10 +1162,10 @@ class AutofillRecords {
record.version = this.version;
// Force to recompute fields if we upgrade the schema.
await this._stripComputedFields(record);
this._stripComputedFields(record);
}
hasChanges |= await this.computeFields(record);
hasChanges |= this.computeFields(record);
return hasChanges;
}
@ -1231,10 +1200,10 @@ class AutofillRecords {
* @returns {Array.<string>}
* Return an array of the merged GUID string.
*/
async mergeToStorage(targetRecord, strict = false) {
mergeToStorage(targetRecord, strict = false) {
let mergedGUIDs = [];
for (let record of this._data) {
if (!record.deleted && await this.mergeIfPossible(record.guid, targetRecord, strict)) {
if (!record.deleted && this.mergeIfPossible(record.guid, targetRecord, strict)) {
mergedGUIDs.push(record.guid);
}
}
@ -1254,7 +1223,7 @@ class AutofillRecords {
}}, "formautofill-storage-changed", "removeAll");
}
async _stripComputedFields(record) {
_stripComputedFields(record) {
this.VALID_COMPUTED_FIELDS.forEach(field => delete record[field]);
}
@ -1262,7 +1231,7 @@ class AutofillRecords {
_recordReadProcessor(record) {}
// An interface to be inherited.
async computeFields(record) {}
computeFields(record) {}
/**
* An interface to be inherited to mutate the argument to normalize it.
@ -1288,7 +1257,7 @@ class AutofillRecords {
_validateFields(record) {}
// An interface to be inherited.
async mergeIfPossible(guid, record, strict) {}
mergeIfPossible(guid, record, strict) {}
}
class Addresses extends AutofillRecords {
@ -1303,7 +1272,7 @@ class Addresses extends AutofillRecords {
}
}
async computeFields(address) {
computeFields(address) {
// NOTE: Remember to bump the schema version number if any of the existing
// computing algorithm changes. (No need to bump when just adding new
// computed fields.)
@ -1491,10 +1460,10 @@ class Addresses extends AutofillRecords {
* @param {boolean} strict
* In strict merge mode, we'll treat the subset record with empty field
* as unable to be merged, but mergeable if in non-strict mode.
* @returns {Promise<boolean>}
* @returns {boolean}
* Return true if address is merged into target with specific guid or false if not.
*/
async mergeIfPossible(guid, address, strict) {
mergeIfPossible(guid, address, strict) {
this.log.debug("mergeIfPossible:", guid, address);
let addressFound = this._findByGUID(guid);
@ -1554,7 +1523,7 @@ class Addresses extends AutofillRecords {
return true;
}
await this.update(guid, addressToMerge, true);
this.update(guid, addressToMerge, true);
return true;
}
}
@ -1564,7 +1533,7 @@ class CreditCards extends AutofillRecords {
super(store, "creditCards", VALID_CREDIT_CARD_FIELDS, VALID_CREDIT_CARD_COMPUTED_FIELDS, CREDIT_CARD_SCHEMA_VERSION);
}
async computeFields(creditCard) {
computeFields(creditCard) {
// NOTE: Remember to bump the schema version number if any of the existing
// computing algorithm changes. (No need to bump when just adding new
// computed fields.)
@ -1602,7 +1571,7 @@ class CreditCards extends AutofillRecords {
if ("cc-number" in creditCard) {
let ccNumber = creditCard["cc-number"];
creditCard["cc-number"] = CreditCard.getLongMaskedNumber(ccNumber);
creditCard["cc-number-encrypted"] = await MasterPassword.encrypt(ccNumber);
creditCard["cc-number-encrypted"] = MasterPassword.encryptSync(ccNumber);
} else {
creditCard["cc-number-encrypted"] = "";
}
@ -1611,11 +1580,11 @@ class CreditCards extends AutofillRecords {
return hasNewComputedFields;
}
async _stripComputedFields(creditCard) {
_stripComputedFields(creditCard) {
if (creditCard["cc-number-encrypted"]) {
creditCard["cc-number"] = await MasterPassword.decrypt(creditCard["cc-number-encrypted"]);
creditCard["cc-number"] = MasterPassword.decryptSync(creditCard["cc-number-encrypted"]);
}
await super._stripComputedFields(creditCard);
super._stripComputedFields(creditCard);
}
_normalizeFields(creditCard) {
@ -1678,14 +1647,14 @@ class CreditCards extends AutofillRecords {
* Normalize the given record and return the first matched guid if storage has the same record.
* @param {Object} targetCreditCard
* The credit card for duplication checking.
* @returns {Promise<string|null>}
* @returns {string|null}
* Return the first guid if storage has the same credit card and null otherwise.
*/
async getDuplicateGuid(targetCreditCard) {
getDuplicateGuid(targetCreditCard) {
let clonedTargetCreditCard = this._clone(targetCreditCard);
this._normalizeRecord(clonedTargetCreditCard);
for (let creditCard of this._data) {
let isDuplicate = await Promise.all(this.VALID_FIELDS.map(async field => {
let isDuplicate = this.VALID_FIELDS.every(field => {
if (!clonedTargetCreditCard[field]) {
return !creditCard[field];
}
@ -1695,10 +1664,10 @@ class CreditCards extends AutofillRecords {
// enabled because we don't want to leak the credit card number.
return CreditCard.getLongMaskedNumber(clonedTargetCreditCard[field]) == creditCard[field];
}
return (clonedTargetCreditCard[field] == await MasterPassword.decrypt(creditCard["cc-number-encrypted"]));
return clonedTargetCreditCard[field] == MasterPassword.decryptSync(creditCard["cc-number-encrypted"]);
}
return clonedTargetCreditCard[field] == creditCard[field];
})).then(fieldResults => fieldResults.every(result => result));
});
if (isDuplicate) {
return creditCard.guid;
}
@ -1717,11 +1686,11 @@ class CreditCards extends AutofillRecords {
* @returns {boolean}
* Return true if credit card is merged into target with specific guid or false if not.
*/
async mergeIfPossible(guid, creditCard) {
mergeIfPossible(guid, creditCard) {
this.log.debug("mergeIfPossible:", guid, creditCard);
// Query raw data for comparing the decrypted credit card number
let creditCardFound = await this.get(guid, {rawData: true});
let creditCardFound = this.get(guid, {rawData: true});
if (!creditCardFound) {
throw new Error("No matching credit card.");
}
@ -1758,7 +1727,7 @@ class CreditCards extends AutofillRecords {
return true;
}
await this.update(guid, creditCardToMerge, true);
this.update(guid, creditCardToMerge, true);
return true;
}
}

View File

@ -90,7 +90,7 @@ FormAutofillStore.prototype = {
async getAllIDs() {
let result = {};
for (let {guid} of await this.storage.getAll({includeDeleted: true})) {
for (let {guid} of this.storage.getAll({includeDeleted: true})) {
result[guid] = true;
}
return result;
@ -103,7 +103,7 @@ FormAutofillStore.prototype = {
// Note: this function intentionally returns false in cases where we only have
// a (local) tombstone - and formAutofillStorage.get() filters them for us.
async itemExists(id) {
return Boolean(await this.storage.get(id));
return Boolean(this.storage.get(id));
},
async applyIncoming(remoteRecord) {
@ -120,7 +120,7 @@ FormAutofillStore.prototype = {
}
// No matching local record. Try to dedupe a NEW local record.
let localDupeID = await this.storage.findDuplicateGUID(remoteRecord.toEntry());
let localDupeID = this.storage.findDuplicateGUID(remoteRecord.toEntry());
if (localDupeID) {
this._log.trace(`Deduping local record ${localDupeID} to remote`, remoteRecord);
// Change the local GUID to match the incoming record, then apply the
@ -135,13 +135,13 @@ FormAutofillStore.prototype = {
// handles for us.)
this._log.trace("Add record", remoteRecord);
let entry = remoteRecord.toEntry();
await this.storage.add(entry, {sourceSync: true});
this.storage.add(entry, {sourceSync: true});
},
async createRecord(id, collection) {
this._log.trace("Create record", id);
let record = new AutofillRecord(collection, id);
let entry = await this.storage.get(id, {
let entry = this.storage.get(id, {
rawData: true,
});
if (entry) {
@ -158,10 +158,10 @@ FormAutofillStore.prototype = {
this._log.trace("Updating record", record);
let entry = record.toEntry();
let {forkedGUID} = await this.storage.reconcile(entry);
let {forkedGUID} = this.storage.reconcile(entry);
if (this._log.level <= Log.Level.Debug) {
let forkedRecord = forkedGUID ? await this.storage.get(forkedGUID) : null;
let reconciledRecord = await this.storage.get(record.id);
let forkedRecord = forkedGUID ? this.storage.get(forkedGUID) : null;
let reconciledRecord = this.storage.get(record.id);
this._log.debug("Updated local record", {
forked: sanitizeStorageObject(forkedRecord),
updated: sanitizeStorageObject(reconciledRecord),

View File

@ -108,6 +108,25 @@ var MasterPassword = {
return cryptoSDR.decrypt(cipherText);
},
/**
* Decrypts cipherText synchronously. "ensureLoggedIn()" needs to be called
* outside in case another dialog is showing.
*
* NOTE: This method will be removed soon once the FormAutofillStorage APIs are
* refactored to be async functions (bug 1399367). Please use async
* version instead.
*
* @deprecated
* @param {string} cipherText Encrypted string including the algorithm details.
* @returns {string} The decrypted string.
*/
decryptSync(cipherText) {
if (this.isUIBusy) {
throw Components.Exception("\"ensureLoggedIn()\" should be called first", Cr.NS_ERROR_UNEXPECTED);
}
return cryptoSDR.decrypt(cipherText);
},
/**
* Encrypts a string and returns cipher text containing algorithm information used for decryption.
*
@ -122,6 +141,25 @@ var MasterPassword = {
return cryptoSDR.encrypt(plainText);
},
/**
* Encrypts plainText synchronously. "ensureLoggedIn()" needs to be called
* outside in case another dialog is showing.
*
* NOTE: This method will be removed soon once the FormAutofillStorage APIs are
* refactored to be async functions (bug 1399367). Please use async
* version instead.
*
* @deprecated
* @param {string} plainText A plain string to be encrypted.
* @returns {string} The encrypted cipher string.
*/
encryptSync(plainText) {
if (this.isUIBusy) {
throw Components.Exception("\"ensureLoggedIn()\" should be called first", Cr.NS_ERROR_UNEXPECTED);
}
return cryptoSDR.encrypt(plainText);
},
/**
* Resolve when master password dialogs are closed, immediately if none are open.
*

View File

@ -73,37 +73,35 @@
<script type="application/javascript"><![CDATA[
"use strict";
(async () => {
let {
getAddressLabel,
isCCNumber,
getCreditCardNetworks,
} = FormAutofillUtils;
let record = window.arguments && window.arguments[0];
let addresses = {};
for (let address of await formAutofillStorage.addresses.getAll()) {
addresses[address.guid] = address;
}
let {
getAddressLabel,
isCCNumber,
getCreditCardNetworks,
} = FormAutofillUtils;
let record = window.arguments && window.arguments[0];
let addresses = {};
for (let address of formAutofillStorage.addresses.getAll()) {
addresses[address.guid] = address;
}
/* import-globals-from autofillEditForms.js */
let fieldContainer = new EditCreditCard({
form: document.getElementById("form"),
}, record, addresses,
{
getAddressLabel: getAddressLabel.bind(FormAutofillUtils),
isCCNumber: isCCNumber.bind(FormAutofillUtils),
getSupportedNetworks: getCreditCardNetworks.bind(FormAutofillUtils),
});
/* import-globals-from autofillEditForms.js */
let fieldContainer = new EditCreditCard({
form: document.getElementById("form"),
}, record, addresses,
{
getAddressLabel: getAddressLabel.bind(FormAutofillUtils),
isCCNumber: isCCNumber.bind(FormAutofillUtils),
getSupportedNetworks: getCreditCardNetworks.bind(FormAutofillUtils),
});
/* import-globals-from editDialog.js */
new EditCreditCardDialog({
title: document.querySelector("title"),
fieldContainer,
controlsContainer: document.getElementById("controls-container"),
cancel: document.getElementById("cancel"),
save: document.getElementById("save"),
}, record);
})();
/* import-globals-from editDialog.js */
new EditCreditCardDialog({
title: document.querySelector("title"),
fieldContainer,
controlsContainer: document.getElementById("controls-container"),
cancel: document.getElementById("cancel"),
save: document.getElementById("save"),
}, record);
]]></script>
</body>
</html>

View File

@ -13,6 +13,8 @@ ChromeUtils.import("resource://formautofill/FormAutofillUtils.jsm");
ChromeUtils.defineModuleGetter(this, "formAutofillStorage",
"resource://formautofill/FormAutofillStorage.jsm");
ChromeUtils.defineModuleGetter(this, "MasterPassword",
"resource://formautofill/MasterPassword.jsm");
class AutofillEditDialog {
constructor(subStorageName, elements, record) {
@ -49,9 +51,9 @@ class AutofillEditDialog {
async saveRecord(record, guid) {
let storage = await this.getStorage();
if (guid) {
await storage.update(guid, record);
storage.update(guid, record);
} else {
await storage.add(record);
storage.add(record);
}
}
@ -176,11 +178,15 @@ class EditCreditCardDialog extends AutofillEditDialog {
return;
}
try {
await this.saveRecord(creditCard, this._record ? this._record.guid : null);
window.close();
} catch (ex) {
Cu.reportError(ex);
// TODO: "MasterPassword.ensureLoggedIn" can be removed after the storage
// APIs are refactored to be async functions (bug 1399367).
if (await MasterPassword.ensureLoggedIn()) {
try {
await this.saveRecord(creditCard, this._record ? this._record.guid : null);
window.close();
} catch (ex) {
Cu.reportError(ex);
}
}
}
}

View File

@ -102,7 +102,7 @@ class ManageRecords {
async _loadRecords() {
let storage = await this.getStorage();
let records = await storage.getAll();
let records = storage.getAll();
// Sort by last modified time starting with most recent
records.sort((a, b) => b.timeLastModified - a.timeLastModified);
await this.renderRecordElements(records);

View File

@ -53,17 +53,17 @@ add_task(async function test_activeStatus_observe() {
Assert.equal(formAutofillParent._onStatusChanged.called, true);
// profile changed => Need to trigger _onStatusChanged
await Promise.all(["add", "update", "remove", "reconcile"].map(async event => {
["add", "update", "remove", "reconcile"].forEach(event => {
formAutofillParent._computeStatus.returns(!formAutofillParent._active);
formAutofillParent._onStatusChanged.reset();
await formAutofillParent.observe(null, "formautofill-storage-changed", event);
formAutofillParent.observe(null, "formautofill-storage-changed", event);
Assert.equal(formAutofillParent._onStatusChanged.called, true);
}));
});
// profile metadata updated => No need to trigger _onStatusChanged
formAutofillParent._computeStatus.returns(!formAutofillParent._active);
formAutofillParent._onStatusChanged.reset();
await formAutofillParent.observe(null, "formautofill-storage-changed", "notifyUsed");
formAutofillParent.observe(null, "formautofill-storage-changed", "notifyUsed");
Assert.equal(formAutofillParent._onStatusChanged.called, false);
});
@ -75,7 +75,7 @@ add_task(async function test_activeStatus_computeStatus() {
});
sinon.stub(formAutofillParent.formAutofillStorage.addresses, "getAll");
formAutofillParent.formAutofillStorage.addresses.getAll.returns(Promise.all([]));
formAutofillParent.formAutofillStorage.addresses.getAll.returns([]);
// pref is enabled and profile is empty.
Services.prefs.setBoolPref("extensions.formautofill.addresses.enabled", true);
@ -87,8 +87,8 @@ add_task(async function test_activeStatus_computeStatus() {
Services.prefs.setBoolPref("extensions.formautofill.creditCards.enabled", false);
Assert.equal(formAutofillParent._computeStatus(), false);
formAutofillParent.formAutofillStorage.addresses.getAll.returns(Promise.all([{"given-name": "John"}]));
await formAutofillParent.observe(null, "formautofill-storage-changed", "add");
formAutofillParent.formAutofillStorage.addresses.getAll.returns([{"given-name": "John"}]);
formAutofillParent.observe(null, "formautofill-storage-changed", "add");
// pref is enabled and profile is not empty.
Services.prefs.setBoolPref("extensions.formautofill.addresses.enabled", true);
Services.prefs.setBoolPref("extensions.formautofill.addresses.enabled", true);

View File

@ -287,7 +287,7 @@ add_task(async function test_getAll() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
Assert.equal(addresses.length, 2);
do_check_record_matches(addresses[0], TEST_ADDRESS_1);
@ -299,44 +299,44 @@ add_task(async function test_getAll() {
Assert.equal(addresses[0]["address-line2"], "MIT Room 32-G524");
// Test with rawData set.
addresses = await profileStorage.addresses.getAll({rawData: true});
addresses = profileStorage.addresses.getAll({rawData: true});
Assert.equal(addresses[0].name, undefined);
Assert.equal(addresses[0]["address-line1"], undefined);
Assert.equal(addresses[0]["address-line2"], undefined);
// Modifying output shouldn't affect the storage.
addresses[0].organization = "test";
do_check_record_matches((await profileStorage.addresses.getAll())[0], TEST_ADDRESS_1);
do_check_record_matches(profileStorage.addresses.getAll()[0], TEST_ADDRESS_1);
});
add_task(async function test_get() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
let guid = addresses[0].guid;
let address = await profileStorage.addresses.get(guid);
let address = profileStorage.addresses.get(guid);
do_check_record_matches(address, TEST_ADDRESS_1);
// Test with rawData set.
address = await profileStorage.addresses.get(guid, {rawData: true});
address = profileStorage.addresses.get(guid, {rawData: true});
Assert.equal(address.name, undefined);
Assert.equal(address["address-line1"], undefined);
Assert.equal(address["address-line2"], undefined);
// Modifying output shouldn't affect the storage.
address.organization = "test";
do_check_record_matches(await profileStorage.addresses.get(guid), TEST_ADDRESS_1);
do_check_record_matches(profileStorage.addresses.get(guid), TEST_ADDRESS_1);
Assert.equal(await profileStorage.addresses.get("INVALID_GUID"), null);
Assert.equal(profileStorage.addresses.get("INVALID_GUID"), null);
});
add_task(async function test_add() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
Assert.equal(addresses.length, 2);
@ -351,23 +351,23 @@ add_task(async function test_add() {
Assert.equal(addresses[0].timesUsed, 0);
// Empty string should be deleted before saving.
await profileStorage.addresses.add(TEST_ADDRESS_WITH_EMPTY_FIELD);
profileStorage.addresses.add(TEST_ADDRESS_WITH_EMPTY_FIELD);
let address = profileStorage.addresses._data[2];
Assert.equal(address.name, TEST_ADDRESS_WITH_EMPTY_FIELD.name);
Assert.equal(address["street-address"], undefined);
// Empty computed fields shouldn't cause any problem.
await profileStorage.addresses.add(TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD);
profileStorage.addresses.add(TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD);
address = profileStorage.addresses._data[3];
Assert.equal(address.email, TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD.email);
await Assert.rejects(profileStorage.addresses.add(TEST_ADDRESS_WITH_INVALID_FIELD),
Assert.throws(() => profileStorage.addresses.add(TEST_ADDRESS_WITH_INVALID_FIELD),
/"invalidField" is not a valid field\./);
await Assert.rejects(profileStorage.addresses.add({}),
Assert.throws(() => profileStorage.addresses.add({}),
/Record contains no valid field\./);
await Assert.rejects(profileStorage.addresses.add(TEST_ADDRESS_EMPTY_AFTER_NORMALIZE),
Assert.throws(() => profileStorage.addresses.add(TEST_ADDRESS_EMPTY_AFTER_NORMALIZE),
/Record contains no valid field\./);
});
@ -385,7 +385,7 @@ add_task(async function test_update() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
let guid = addresses[1].guid;
let timeLastModified = addresses[1].timeLastModified;
@ -399,13 +399,13 @@ add_task(async function test_update() {
Assert.notEqual(addresses[1].country, undefined);
await profileStorage.addresses.update(guid, TEST_ADDRESS_3);
profileStorage.addresses.update(guid, TEST_ADDRESS_3);
await onChanged;
await profileStorage._saveImmediately();
profileStorage.addresses.pullSyncChanges(); // force sync metadata, which we check below.
let address = await profileStorage.addresses.get(guid, {rawData: true});
let address = profileStorage.addresses.get(guid, {rawData: true});
Assert.equal(address.country, undefined);
Assert.notEqual(address.timeLastModified, timeLastModified);
@ -413,13 +413,13 @@ add_task(async function test_update() {
Assert.equal(getSyncChangeCounter(profileStorage.addresses, guid), 1);
// Test preserveOldProperties parameter and field with empty string.
await profileStorage.addresses.update(guid, TEST_ADDRESS_WITH_EMPTY_FIELD, true);
profileStorage.addresses.update(guid, TEST_ADDRESS_WITH_EMPTY_FIELD, true);
await onChanged;
await profileStorage._saveImmediately();
profileStorage.addresses.pullSyncChanges(); // force sync metadata, which we check below.
address = await profileStorage.addresses.get(guid, {rawData: true});
address = profileStorage.addresses.get(guid, {rawData: true});
Assert.equal(address["given-name"], "Tim");
Assert.equal(address["family-name"], "Berners");
@ -429,37 +429,42 @@ add_task(async function test_update() {
Assert.equal(getSyncChangeCounter(profileStorage.addresses, guid), 2);
// Empty string should be deleted while updating.
await profileStorage.addresses.update(profileStorage.addresses._data[0].guid, TEST_ADDRESS_WITH_EMPTY_FIELD);
profileStorage.addresses.update(profileStorage.addresses._data[0].guid, TEST_ADDRESS_WITH_EMPTY_FIELD);
address = profileStorage.addresses._data[0];
Assert.equal(address.name, TEST_ADDRESS_WITH_EMPTY_FIELD.name);
Assert.equal(address["street-address"], undefined);
// Empty computed fields shouldn't cause any problem.
await profileStorage.addresses.update(profileStorage.addresses._data[0].guid, TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD, false);
profileStorage.addresses.update(profileStorage.addresses._data[0].guid, TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD, false);
address = profileStorage.addresses._data[0];
Assert.equal(address.email, TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD.email);
await profileStorage.addresses.update(profileStorage.addresses._data[1].guid, TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD, true);
profileStorage.addresses.update(profileStorage.addresses._data[1].guid, TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD, true);
address = profileStorage.addresses._data[1];
Assert.equal(address.email, TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD.email);
await Assert.rejects(profileStorage.addresses.update("INVALID_GUID", TEST_ADDRESS_3),
Assert.throws(
() => profileStorage.addresses.update("INVALID_GUID", TEST_ADDRESS_3),
/No matching record\./
);
await Assert.rejects(profileStorage.addresses.update(guid, TEST_ADDRESS_WITH_INVALID_FIELD),
Assert.throws(
() => profileStorage.addresses.update(guid, TEST_ADDRESS_WITH_INVALID_FIELD),
/"invalidField" is not a valid field\./
);
await Assert.rejects(profileStorage.addresses.update(guid, {}),
Assert.throws(
() => profileStorage.addresses.update(guid, {}),
/Record contains no valid field\./
);
await Assert.rejects(profileStorage.addresses.update(guid, TEST_ADDRESS_EMPTY_AFTER_NORMALIZE),
Assert.throws(
() => profileStorage.addresses.update(guid, TEST_ADDRESS_EMPTY_AFTER_NORMALIZE),
/Record contains no valid field\./
);
profileStorage.addresses.update(guid, TEST_ADDRESS_2);
await Assert.rejects(profileStorage.addresses.update(guid, TEST_ADDRESS_EMPTY_AFTER_UPDATE_ADDRESS_2),
Assert.throws(
() => profileStorage.addresses.update(guid, TEST_ADDRESS_EMPTY_AFTER_UPDATE_ADDRESS_2),
/Record contains no valid field\./
);
});
@ -468,7 +473,7 @@ add_task(async function test_notifyUsed() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
let guid = addresses[1].guid;
let timeLastUsed = addresses[1].timeLastUsed;
let timesUsed = addresses[1].timesUsed;
@ -486,7 +491,7 @@ add_task(async function test_notifyUsed() {
profileStorage.addresses.notifyUsed(guid);
await onChanged;
let address = await profileStorage.addresses.get(guid);
let address = profileStorage.addresses.get(guid);
Assert.equal(address.timesUsed, timesUsed + 1);
Assert.notEqual(address.timeLastUsed, timeLastUsed);
@ -503,7 +508,7 @@ add_task(async function test_remove() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
let guid = addresses[1].guid;
let onChanged = TestUtils.topicObserved(
@ -519,11 +524,11 @@ add_task(async function test_remove() {
profileStorage.addresses.remove(guid);
await onChanged;
addresses = await profileStorage.addresses.getAll();
addresses = profileStorage.addresses.getAll();
Assert.equal(addresses.length, 1);
Assert.equal(await profileStorage.addresses.get(guid), null);
Assert.equal(profileStorage.addresses.get(guid), null);
});
MERGE_TESTCASES.forEach((testcase) => {
@ -531,7 +536,7 @@ MERGE_TESTCASES.forEach((testcase) => {
info("Starting testcase: " + testcase.description);
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[testcase.addressInStorage]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
let guid = addresses[0].guid;
let timeLastModified = addresses[0].timeLastModified;
@ -555,7 +560,7 @@ MERGE_TESTCASES.forEach((testcase) => {
await onMerged;
}
addresses = await profileStorage.addresses.getAll();
addresses = profileStorage.addresses.getAll();
Assert.equal(addresses.length, 1);
do_check_record_matches(addresses[0], testcase.expectedAddress);
if (testcase.noNeedToUpdate) {
@ -574,7 +579,7 @@ MERGE_TESTCASES.forEach((testcase) => {
add_task(async function test_merge_same_address() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME, [TEST_ADDRESS_1]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
let guid = addresses[0].guid;
let timeLastModified = addresses[0].timeLastModified;
@ -594,7 +599,7 @@ add_task(async function test_merge_unable_merge() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
let guid = addresses[1].guid;
// Force to create sync metadata.
@ -602,15 +607,15 @@ add_task(async function test_merge_unable_merge() {
Assert.equal(getSyncChangeCounter(profileStorage.addresses, guid), 1);
// Unable to merge because of conflict
Assert.equal(await profileStorage.addresses.mergeIfPossible(guid, TEST_ADDRESS_3), false);
Assert.equal(profileStorage.addresses.mergeIfPossible(guid, TEST_ADDRESS_3), false);
// Unable to merge because no overlap
Assert.equal(await profileStorage.addresses.mergeIfPossible(guid, TEST_ADDRESS_4), false);
Assert.equal(profileStorage.addresses.mergeIfPossible(guid, TEST_ADDRESS_4), false);
// Unable to strict merge because subset with empty string
let subset = Object.assign({}, TEST_ADDRESS_1);
subset.organization = "";
Assert.equal(await profileStorage.addresses.mergeIfPossible(guid, subset, true), false);
Assert.equal(profileStorage.addresses.mergeIfPossible(guid, subset, true), false);
// Shouldn't bump the change counter
Assert.equal(getSyncChangeCounter(profileStorage.addresses, guid), 1);
@ -621,15 +626,14 @@ add_task(async function test_mergeToStorage() {
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
// Merge an address to storage
let anotherAddress = profileStorage.addresses._clone(TEST_ADDRESS_2);
await profileStorage.addresses.add(anotherAddress);
profileStorage.addresses.add(anotherAddress);
anotherAddress.email = "timbl@w3.org";
Assert.equal((await profileStorage.addresses.mergeToStorage(anotherAddress)).length, 2);
Assert.equal((await profileStorage.addresses.getAll())[1].email, anotherAddress.email);
Assert.equal((await profileStorage.addresses.getAll())[2].email, anotherAddress.email);
Assert.equal(profileStorage.addresses.mergeToStorage(anotherAddress).length, 2);
Assert.equal(profileStorage.addresses.getAll()[1].email, anotherAddress.email);
Assert.equal(profileStorage.addresses.getAll()[2].email, anotherAddress.email);
// Empty computed fields shouldn't cause any problem.
Assert.equal((await profileStorage.addresses.mergeToStorage(TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD)).length, 3);
Assert.equal(profileStorage.addresses.mergeToStorage(TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD).length, 3);
});
add_task(async function test_mergeToStorage_strict() {
@ -638,9 +642,9 @@ add_task(async function test_mergeToStorage_strict() {
// Try to merge a subset with empty string
let anotherAddress = profileStorage.addresses._clone(TEST_ADDRESS_1);
anotherAddress.email = "";
Assert.equal((await profileStorage.addresses.mergeToStorage(anotherAddress, true)).length, 0);
Assert.equal((await profileStorage.addresses.getAll())[0].email, TEST_ADDRESS_1.email);
Assert.equal(profileStorage.addresses.mergeToStorage(anotherAddress, true).length, 0);
Assert.equal(profileStorage.addresses.getAll()[0].email, TEST_ADDRESS_1.email);
// Empty computed fields shouldn't cause any problem.
Assert.equal((await profileStorage.addresses.mergeToStorage(TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD, true)).length, 1);
Assert.equal(profileStorage.addresses.mergeToStorage(TEST_ADDRESS_WITH_EMPTY_COMPUTED_FIELD, true).length, 1);
});

View File

@ -210,9 +210,9 @@ let prepareTestCreditCards = async function(path) {
subject.wrappedJSObject.guid &&
subject.wrappedJSObject.collectionName == COLLECTION_NAME
);
Assert.ok(await profileStorage.creditCards.add(TEST_CREDIT_CARD_1));
Assert.ok(profileStorage.creditCards.add(TEST_CREDIT_CARD_1));
await onChanged;
Assert.ok(await profileStorage.creditCards.add(TEST_CREDIT_CARD_2));
Assert.ok(profileStorage.creditCards.add(TEST_CREDIT_CARD_2));
await onChanged;
await profileStorage._saveImmediately();
};
@ -259,7 +259,7 @@ add_task(async function test_getAll() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
Assert.equal(creditCards.length, 2);
do_check_credit_card_matches(creditCards[0], TEST_CREDIT_CARD_1);
@ -271,14 +271,14 @@ add_task(async function test_getAll() {
Assert.equal(creditCards[0]["cc-exp"], "2017-04");
// Test with rawData set.
creditCards = await profileStorage.creditCards.getAll({rawData: true});
creditCards = profileStorage.creditCards.getAll({rawData: true});
Assert.equal(creditCards[0]["cc-given-name"], undefined);
Assert.equal(creditCards[0]["cc-family-name"], undefined);
Assert.equal(creditCards[0]["cc-exp"], undefined);
// Modifying output shouldn't affect the storage.
creditCards[0]["cc-name"] = "test";
do_check_credit_card_matches((await profileStorage.creditCards.getAll())[0], TEST_CREDIT_CARD_1);
do_check_credit_card_matches(profileStorage.creditCards.getAll()[0], TEST_CREDIT_CARD_1);
});
add_task(async function test_get() {
@ -288,17 +288,17 @@ add_task(async function test_get() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
let guid = creditCards[0].guid;
let creditCard = await profileStorage.creditCards.get(guid);
let creditCard = profileStorage.creditCards.get(guid);
do_check_credit_card_matches(creditCard, TEST_CREDIT_CARD_1);
// Modifying output shouldn't affect the storage.
creditCards[0]["cc-name"] = "test";
do_check_credit_card_matches(await profileStorage.creditCards.get(guid), TEST_CREDIT_CARD_1);
do_check_credit_card_matches(profileStorage.creditCards.get(guid), TEST_CREDIT_CARD_1);
Assert.equal(await profileStorage.creditCards.get("INVALID_GUID"), null);
Assert.equal(profileStorage.creditCards.get("INVALID_GUID"), null);
});
add_task(async function test_add() {
@ -308,7 +308,7 @@ add_task(async function test_add() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
Assert.equal(creditCards.length, 2);
@ -323,25 +323,25 @@ add_task(async function test_add() {
Assert.equal(creditCards[0].timesUsed, 0);
// Empty string should be deleted before saving.
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_EMPTY_FIELD);
profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_EMPTY_FIELD);
let creditCard = profileStorage.creditCards._data[2];
Assert.equal(creditCard["cc-exp-month"], TEST_CREDIT_CARD_WITH_EMPTY_FIELD["cc-exp-month"]);
Assert.equal(creditCard["cc-name"], undefined);
Assert.equal(creditCard.billingAddressGUID, undefined);
// Empty computed fields shouldn't cause any problem.
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD);
profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD);
creditCard = profileStorage.creditCards._data[3];
Assert.equal(creditCard["cc-number"],
CreditCard.getLongMaskedNumber(TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD["cc-number"]));
await Assert.rejects(profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_FIELD),
Assert.throws(() => profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_FIELD),
/"invalidField" is not a valid field\./);
await Assert.rejects(profileStorage.creditCards.add({}),
Assert.throws(() => profileStorage.creditCards.add({}),
/Record contains no valid field\./);
await Assert.rejects(profileStorage.creditCards.add(TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE),
Assert.throws(() => profileStorage.creditCards.add(TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE),
/Record contains no valid field\./);
});
@ -350,13 +350,13 @@ add_task(async function test_addWithBillingAddress() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
Assert.equal(creditCards.length, 0);
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_BILLING_ADDRESS);
creditCards = await profileStorage.creditCards.getAll();
creditCards = profileStorage.creditCards.getAll();
Assert.equal(creditCards.length, 1);
do_check_credit_card_matches(creditCards[0], TEST_CREDIT_CARD_WITH_BILLING_ADDRESS);
});
@ -378,7 +378,7 @@ add_task(async function test_update() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
let guid = creditCards[1].guid;
let timeLastModified = creditCards[1].timeLastModified;
@ -391,21 +391,21 @@ add_task(async function test_update() {
);
Assert.notEqual(creditCards[1]["cc-name"], undefined);
await profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_3);
profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_3);
await onChanged;
await profileStorage._saveImmediately();
profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCard = await profileStorage.creditCards.get(guid);
let creditCard = profileStorage.creditCards.get(guid);
Assert.equal(creditCard["cc-name"], undefined);
Assert.notEqual(creditCard.timeLastModified, timeLastModified);
do_check_credit_card_matches(creditCard, TEST_CREDIT_CARD_3);
// Empty string should be deleted while updating.
await profileStorage.creditCards.update(profileStorage.creditCards._data[0].guid, TEST_CREDIT_CARD_WITH_EMPTY_FIELD);
profileStorage.creditCards.update(profileStorage.creditCards._data[0].guid, TEST_CREDIT_CARD_WITH_EMPTY_FIELD);
creditCard = profileStorage.creditCards._data[0];
Assert.equal(creditCard["cc-exp-month"], TEST_CREDIT_CARD_WITH_EMPTY_FIELD["cc-exp-month"]);
Assert.equal(creditCard["cc-name"], undefined);
@ -413,33 +413,38 @@ add_task(async function test_update() {
Assert.equal(creditCard.billingAddressGUID, undefined);
// Empty computed fields shouldn't cause any problem.
await profileStorage.creditCards.update(profileStorage.creditCards._data[0].guid, TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD, false);
profileStorage.creditCards.update(profileStorage.creditCards._data[0].guid, TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD, false);
creditCard = profileStorage.creditCards._data[0];
Assert.equal(creditCard["cc-number"],
CreditCard.getLongMaskedNumber(TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD["cc-number"]));
await profileStorage.creditCards.update(profileStorage.creditCards._data[1].guid, TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD, true);
profileStorage.creditCards.update(profileStorage.creditCards._data[1].guid, TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD, true);
creditCard = profileStorage.creditCards._data[1];
Assert.equal(creditCard["cc-number"],
CreditCard.getLongMaskedNumber(TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD["cc-number"]));
await Assert.rejects(profileStorage.creditCards.update("INVALID_GUID", TEST_CREDIT_CARD_3),
Assert.throws(
() => profileStorage.creditCards.update("INVALID_GUID", TEST_CREDIT_CARD_3),
/No matching record\./
);
await Assert.rejects(profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_WITH_INVALID_FIELD),
Assert.throws(
() => profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_WITH_INVALID_FIELD),
/"invalidField" is not a valid field\./
);
await Assert.rejects(profileStorage.creditCards.update(guid, {}),
Assert.throws(
() => profileStorage.creditCards.update(guid, {}),
/Record contains no valid field\./
);
await Assert.rejects(profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE),
Assert.throws(
() => profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE),
/Record contains no valid field\./
);
await profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_1);
await Assert.rejects(profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_EMPTY_AFTER_UPDATE_CREDIT_CARD_1),
profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_1);
Assert.throws(
() => profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_EMPTY_AFTER_UPDATE_CREDIT_CARD_1),
/Record contains no valid field\./
);
});
@ -450,12 +455,12 @@ add_task(async function test_validate() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_EXPIRY_DATE);
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR);
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_SPACES_BETWEEN_DIGITS);
await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_NETWORK);
profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_EXPIRY_DATE);
profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR);
profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_SPACES_BETWEEN_DIGITS);
profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_NETWORK);
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
Assert.equal(creditCards[0]["cc-exp-month"], undefined);
Assert.equal(creditCards[0]["cc-exp-year"], undefined);
@ -481,7 +486,7 @@ add_task(async function test_notifyUsed() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
let guid = creditCards[1].guid;
let timeLastUsed = creditCards[1].timeLastUsed;
let timesUsed = creditCards[1].timesUsed;
@ -501,7 +506,7 @@ add_task(async function test_notifyUsed() {
profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCard = await profileStorage.creditCards.get(guid);
let creditCard = profileStorage.creditCards.get(guid);
Assert.equal(creditCard.timesUsed, timesUsed + 1);
Assert.notEqual(creditCard.timeLastUsed, timeLastUsed);
@ -517,7 +522,7 @@ add_task(async function test_remove() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
let guid = creditCards[1].guid;
let onChanged = TestUtils.topicObserved(
@ -537,11 +542,11 @@ add_task(async function test_remove() {
profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
creditCards = await profileStorage.creditCards.getAll();
creditCards = profileStorage.creditCards.getAll();
Assert.equal(creditCards.length, 1);
Assert.equal(await profileStorage.creditCards.get(guid), null);
Assert.equal(profileStorage.creditCards.get(guid), null);
});
MERGE_TESTCASES.forEach((testcase) => {
@ -550,7 +555,7 @@ MERGE_TESTCASES.forEach((testcase) => {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[testcase.creditCardInStorage],
"creditCards");
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
let guid = creditCards[0].guid;
let timeLastModified = creditCards[0].timeLastModified;
// Merge creditCard and verify the guid in notifyObservers subject
@ -564,11 +569,11 @@ MERGE_TESTCASES.forEach((testcase) => {
// Force to create sync metadata.
profileStorage.creditCards.pullSyncChanges();
Assert.equal(getSyncChangeCounter(profileStorage.creditCards, guid), 1);
Assert.ok(await profileStorage.creditCards.mergeIfPossible(guid, testcase.creditCardToMerge));
Assert.ok(profileStorage.creditCards.mergeIfPossible(guid, testcase.creditCardToMerge));
if (!testcase.noNeedToUpdate) {
await onMerged;
}
creditCards = await profileStorage.creditCards.getAll();
creditCards = profileStorage.creditCards.getAll();
Assert.equal(creditCards.length, 1);
do_check_credit_card_matches(creditCards[0], testcase.expectedCreditCard);
if (!testcase.noNeedToUpdate) {
@ -589,7 +594,7 @@ add_task(async function test_merge_unable_merge() {
[TEST_CREDIT_CARD_1],
"creditCards");
let creditCards = await profileStorage.creditCards.getAll();
let creditCards = profileStorage.creditCards.getAll();
let guid = creditCards[0].guid;
// Force to create sync metadata.
profileStorage.creditCards.pullSyncChanges();
@ -598,14 +603,14 @@ add_task(async function test_merge_unable_merge() {
// Unable to merge because of conflict
let anotherCreditCard = profileStorage.creditCards._clone(TEST_CREDIT_CARD_1);
anotherCreditCard["cc-name"] = "Foo Bar";
Assert.equal(await profileStorage.creditCards.mergeIfPossible(guid, anotherCreditCard), false);
Assert.equal(profileStorage.creditCards.mergeIfPossible(guid, anotherCreditCard), false);
// The change counter is unchanged.
Assert.equal(getSyncChangeCounter(profileStorage.creditCards, guid), 1);
// Unable to merge because no credit card number
anotherCreditCard = profileStorage.creditCards._clone(TEST_CREDIT_CARD_1);
anotherCreditCard["cc-number"] = "";
Assert.equal(await profileStorage.creditCards.mergeIfPossible(guid, anotherCreditCard), false);
Assert.equal(profileStorage.creditCards.mergeIfPossible(guid, anotherCreditCard), false);
// The change counter is still unchanged.
Assert.equal(getSyncChangeCounter(profileStorage.creditCards, guid), 1);
});
@ -617,14 +622,14 @@ add_task(async function test_mergeToStorage() {
// Merge a creditCard to storage
let anotherCreditCard = profileStorage.creditCards._clone(TEST_CREDIT_CARD_3);
anotherCreditCard["cc-name"] = "Foo Bar";
Assert.equal((await profileStorage.creditCards.mergeToStorage(anotherCreditCard)).length, 2);
Assert.equal((await profileStorage.creditCards.getAll())[0]["cc-name"], "Foo Bar");
Assert.equal((await profileStorage.creditCards.getAll())[0]["cc-exp"], "2000-01");
Assert.equal((await profileStorage.creditCards.getAll())[1]["cc-name"], "Foo Bar");
Assert.equal((await profileStorage.creditCards.getAll())[1]["cc-exp"], "2000-01");
Assert.equal(profileStorage.creditCards.mergeToStorage(anotherCreditCard).length, 2);
Assert.equal(profileStorage.creditCards.getAll()[0]["cc-name"], "Foo Bar");
Assert.equal(profileStorage.creditCards.getAll()[0]["cc-exp"], "2000-01");
Assert.equal(profileStorage.creditCards.getAll()[1]["cc-name"], "Foo Bar");
Assert.equal(profileStorage.creditCards.getAll()[1]["cc-exp"], "2000-01");
// Empty computed fields shouldn't cause any problem.
Assert.equal((await profileStorage.creditCards.mergeToStorage(TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD)).length, 0);
Assert.equal(profileStorage.creditCards.mergeToStorage(TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD).length, 0);
});
add_task(async function test_getDuplicateGuid() {
@ -634,20 +639,20 @@ add_task(async function test_getDuplicateGuid() {
let guid = profileStorage.creditCards._data[0].guid;
// Absolutely a duplicate.
Assert.equal(await profileStorage.creditCards.getDuplicateGuid(TEST_CREDIT_CARD_3), guid);
Assert.equal(profileStorage.creditCards.getDuplicateGuid(TEST_CREDIT_CARD_3), guid);
// Absolutely not a duplicate.
Assert.equal(await profileStorage.creditCards.getDuplicateGuid(TEST_CREDIT_CARD_1), null);
Assert.equal(profileStorage.creditCards.getDuplicateGuid(TEST_CREDIT_CARD_1), null);
// Subset shouldn't be treated as a duplicate.
let record = Object.assign({}, TEST_CREDIT_CARD_3);
delete record["cc-exp-month"];
Assert.equal(await profileStorage.creditCards.getDuplicateGuid(record), null);
Assert.equal(profileStorage.creditCards.getDuplicateGuid(record), null);
// Superset shouldn't be treated as a duplicate.
record = Object.assign({}, TEST_CREDIT_CARD_3);
record["cc-name"] = "John Doe";
Assert.equal(await profileStorage.creditCards.getDuplicateGuid(record), null);
Assert.equal(profileStorage.creditCards.getDuplicateGuid(record), null);
// Numbers with the same last 4 digits shouldn't be treated as a duplicate.
record = Object.assign({}, TEST_CREDIT_CARD_3);
@ -655,7 +660,7 @@ add_task(async function test_getDuplicateGuid() {
// This number differs from TEST_CREDIT_CARD_3 by swapping the order of the
// 09 and 90 adjacent digits, which is still a valid credit card number.
record["cc-number"] = "358999378390" + last4Digits;
Assert.equal(await profileStorage.creditCards.getDuplicateGuid(record), null);
Assert.equal(profileStorage.creditCards.getDuplicateGuid(record), null);
// ... However, we treat numbers with the same last 4 digits as a duplicate if
// the master password is enabled.
@ -663,10 +668,10 @@ add_task(async function test_getDuplicateGuid() {
let token = tokendb.getInternalKeyToken();
token.reset();
token.initPassword("password");
Assert.equal(await profileStorage.creditCards.getDuplicateGuid(record), guid);
Assert.equal(profileStorage.creditCards.getDuplicateGuid(record), guid);
// ... Even though the master password is enabled and the last 4 digits are the
// same, an invalid credit card number should never be treated as a duplicate.
record["cc-number"] = "************" + last4Digits;
Assert.equal(await profileStorage.creditCards.getDuplicateGuid(record), null);
Assert.equal(profileStorage.creditCards.getDuplicateGuid(record), null);
});

View File

@ -79,7 +79,7 @@ add_task(async function test_getRecords() {
if (collection) {
sinon.stub(collection, "getAll");
collection.getAll.returns(Promise.resolve(expectedResult));
collection.getAll.returns(expectedResult);
}
await formAutofillParent._getRecords({collectionName}, target);
mock.verify();
@ -98,7 +98,7 @@ add_task(async function test_getRecords_addresses() {
let mockAddresses = [TEST_ADDRESS_1, TEST_ADDRESS_2];
let collection = formAutofillParent.formAutofillStorage.addresses;
sinon.stub(collection, "getAll");
collection.getAll.returns(Promise.resolve(mockAddresses));
collection.getAll.returns(mockAddresses);
let testCases = [
{
@ -173,14 +173,13 @@ add_task(async function test_getRecords_creditCards() {
await formAutofillParent.init();
await formAutofillParent.formAutofillStorage.initialize();
let collection = formAutofillParent.formAutofillStorage.creditCards;
let encryptedCCRecords = await Promise.all([TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2].map(async record => {
let encryptedCCRecords = [TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2].map(record => {
let clonedRecord = Object.assign({}, record);
clonedRecord["cc-number"] = CreditCard.getLongMaskedNumber(record["cc-number"]);
clonedRecord["cc-number-encrypted"] = await MasterPassword.encrypt(record["cc-number"]);
clonedRecord["cc-number-encrypted"] = MasterPassword.encryptSync(record["cc-number"]);
return clonedRecord;
}));
sinon.stub(collection, "getAll", () =>
Promise.resolve([Object.assign({}, encryptedCCRecords[0]), Object.assign({}, encryptedCCRecords[1])]));
});
sinon.stub(collection, "getAll", () => [Object.assign({}, encryptedCCRecords[0]), Object.assign({}, encryptedCCRecords[1])]);
let CreditCardsWithDecryptedNumber = [
Object.assign({}, encryptedCCRecords[0], {"cc-number-decrypted": TEST_CREDIT_CARD_1["cc-number"]}),
Object.assign({}, encryptedCCRecords[1], {"cc-number-decrypted": TEST_CREDIT_CARD_2["cc-number"]}),

View File

@ -246,11 +246,11 @@ add_task(async function test_migrateAddressRecords() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
await Promise.all(ADDRESS_TESTCASES.map(async testcase => {
ADDRESS_TESTCASES.forEach(testcase => {
info(testcase.description);
await profileStorage.addresses._migrateRecord(testcase.record);
profileStorage.addresses._migrateRecord(testcase.record);
do_check_record_matches(testcase.expectedResult, testcase.record);
}));
});
});
add_task(async function test_migrateCreditCardRecords() {
@ -259,9 +259,9 @@ add_task(async function test_migrateCreditCardRecords() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
await Promise.all(CREDIT_CARD_TESTCASES.map(async testcase => {
CREDIT_CARD_TESTCASES.forEach(testcase => {
info(testcase.description);
await profileStorage.creditCards._migrateRecord(testcase.record);
profileStorage.creditCards._migrateRecord(testcase.record);
do_check_record_matches(testcase.expectedResult, testcase.record);
}));
});
});

View File

@ -920,25 +920,27 @@ add_task(async function test_reconcile_unknown_version() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME);
// Cross-version reconciliation isn't supported yet. See bug 1377204.
await Assert.rejects(profileStorage.addresses.reconcile({
"guid": "31d83d2725ec",
"version": 2,
"given-name": "Mark",
"family-name": "Hammond",
}), /Got unknown record version/);
throws(() => {
profileStorage.addresses.reconcile({
"guid": "31d83d2725ec",
"version": 2,
"given-name": "Mark",
"family-name": "Hammond",
});
}, /Got unknown record version/);
});
add_task(async function test_reconcile_idempotent() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME);
let guid = "de1ba7b094fe";
await profileStorage.addresses.add({
profileStorage.addresses.add({
guid,
version: 1,
"given-name": "Mark",
"family-name": "Hammond",
}, {sourceSync: true});
await profileStorage.addresses.update(guid, {
profileStorage.addresses.update(guid, {
"given-name": "Skip",
"family-name": "Hammond",
"organization": "Mozilla",
@ -953,8 +955,8 @@ add_task(async function test_reconcile_idempotent() {
};
{
let {forkedGUID} = await profileStorage.addresses.reconcile(remote);
let updatedRecord = await profileStorage.addresses.get(guid, {
let {forkedGUID} = profileStorage.addresses.reconcile(remote);
let updatedRecord = profileStorage.addresses.get(guid, {
rawData: true,
});
@ -969,8 +971,8 @@ add_task(async function test_reconcile_idempotent() {
}
{
let {forkedGUID} = await profileStorage.addresses.reconcile(remote);
let updatedRecord = await profileStorage.addresses.get(guid, {
let {forkedGUID} = profileStorage.addresses.reconcile(remote);
let updatedRecord = profileStorage.addresses.get(guid, {
rawData: true,
});
@ -999,13 +1001,13 @@ add_task(async function test_reconcile_three_way_merge() {
for (let test of TESTCASES[collectionName]) {
info(test.description);
await profileStorage[collectionName].add(test.parent, {sourceSync: true});
profileStorage[collectionName].add(test.parent, {sourceSync: true});
for (let updatedRecord of test.local) {
await profileStorage[collectionName].update(test.parent.guid, updatedRecord);
profileStorage[collectionName].update(test.parent.guid, updatedRecord);
}
let localRecord = await profileStorage[collectionName].get(test.parent.guid, {
let localRecord = profileStorage[collectionName].get(test.parent.guid, {
rawData: true,
});
@ -1015,13 +1017,13 @@ add_task(async function test_reconcile_three_way_merge() {
data == "reconcile" &&
subject.wrappedJSObject.collectionName == collectionName
);
let {forkedGUID} = await profileStorage[collectionName].reconcile(test.remote);
let {forkedGUID} = profileStorage[collectionName].reconcile(test.remote);
await onReconciled;
let reconciledRecord = await profileStorage[collectionName].get(test.parent.guid, {
let reconciledRecord = profileStorage[collectionName].get(test.parent.guid, {
rawData: true,
});
if (forkedGUID) {
let forkedRecord = await profileStorage[collectionName].get(forkedGUID, {
let forkedRecord = profileStorage[collectionName].get(forkedGUID, {
rawData: true,
});

View File

@ -46,18 +46,15 @@ add_task(async function test_profileSavedFieldNames_update() {
Services.prefs.clearUserPref("extensions.formautofill.addresses.enabled");
});
Object.defineProperty(
formAutofillParent.formAutofillStorage.addresses,
"_data", {writable: true});
formAutofillParent.formAutofillStorage.addresses._data = [];
sinon.stub(formAutofillParent.formAutofillStorage.addresses, "getAll");
formAutofillParent.formAutofillStorage.addresses.getAll.returns([]);
// The set is empty if there's no profile in the store.
formAutofillParent._updateSavedFieldNames();
Assert.equal(Services.ppmm.initialProcessData.autofillSavedFieldNames.size, 0);
// 2 profiles with 4 valid fields.
formAutofillParent.formAutofillStorage.addresses._data = [{
let fakeStorage = [{
guid: "test-guid-1",
organization: "Sesame Street",
"street-address": "123 Sesame Street.",
@ -78,7 +75,7 @@ add_task(async function test_profileSavedFieldNames_update() {
timeLastModified: 0,
timesUsed: 0,
}];
formAutofillParent.formAutofillStorage.addresses.getAll.returns(fakeStorage);
formAutofillParent._updateSavedFieldNames();
let autofillSavedFieldNames = Services.ppmm.initialProcessData.autofillSavedFieldNames;

View File

@ -63,22 +63,22 @@ function add_storage_task(test_function) {
add_storage_task(async function test_remove_everything(storage, records) {
info("check simple tombstone semantics");
let guid = await storage.add(records[0]);
Assert.equal((await storage.getAll()).length, 1);
let guid = storage.add(records[0]);
Assert.equal(storage.getAll().length, 1);
storage.pullSyncChanges(); // force sync metadata, which triggers tombstone behaviour.
storage.remove(guid);
await storage.add(records[1]);
storage.add(records[1]);
// getAll() is still 1 as we deleted the first.
Assert.equal((await storage.getAll()).length, 1);
Assert.equal(storage.getAll().length, 1);
// check we have the tombstone.
Assert.equal((await storage.getAll({includeDeleted: true})).length, 2);
Assert.equal(storage.getAll({includeDeleted: true}).length, 2);
storage.removeAll();
// should have deleted both the existing and deleted records.
Assert.equal((await storage.getAll({includeDeleted: true})).length, 0);
Assert.equal(storage.getAll({includeDeleted: true}).length, 0);
});

View File

@ -34,8 +34,8 @@ const TEST_ADDRESS_3 = {
// storage.get() doesn't support getting deleted items. However, this test
// wants to do that, so rather than making .get() support that just for this
// test, we use this helper.
async function findGUID(storage, guid, options) {
let all = await storage.getAll(options);
function findGUID(storage, guid, options) {
let all = storage.getAll(options);
let records = all.filter(r => r.guid == guid);
equal(records.length, 1);
return records[0];
@ -45,7 +45,7 @@ add_task(async function test_changeCounter() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1]);
let [address] = await profileStorage.addresses.getAll();
let [address] = profileStorage.addresses.getAll();
// new records don't get the sync metadata.
equal(getSyncChangeCounter(profileStorage.addresses, address.guid), -1);
// But we can force one.
@ -59,7 +59,7 @@ add_task(async function test_pushChanges() {
profileStorage.addresses.pullSyncChanges(); // force sync metadata for all items
let [, address] = await profileStorage.addresses.getAll();
let [, address] = profileStorage.addresses.getAll();
let guid = address.guid;
let changeCounter = getSyncChangeCounter(profileStorage.addresses, guid);
@ -75,14 +75,14 @@ add_task(async function test_pushChanges() {
let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
(subject, data) => data == "update");
await profileStorage.addresses.update(guid, TEST_ADDRESS_3);
profileStorage.addresses.update(guid, TEST_ADDRESS_3);
await onChanged;
changeCounter = getSyncChangeCounter(profileStorage.addresses, guid);
Assert.equal(changeCounter, 2);
profileStorage.addresses.pushSyncChanges(changes);
address = await profileStorage.addresses.get(guid);
address = profileStorage.addresses.get(guid);
changeCounter = getSyncChangeCounter(profileStorage.addresses, guid);
// Counter should still be 1, since our sync didn't record the mid-sync change
@ -117,13 +117,14 @@ add_task(async function test_add_sourceSync() {
let guid = "aaaaaaaaaaaa";
let testAddr = Object.assign({guid, version: 1}, TEST_ADDRESS_1);
await checkingSyncChange("add", async () =>
await checkingSyncChange("add", () =>
profileStorage.addresses.add(testAddr, {sourceSync: true}));
let changeCounter = getSyncChangeCounter(profileStorage.addresses, guid);
equal(changeCounter, 0);
await Assert.rejects(profileStorage.addresses.add({guid, deleted: true}, {sourceSync: true}),
Assert.throws(() =>
profileStorage.addresses.add({guid, deleted: true}, {sourceSync: true}),
/Record aaaaaaaaaaaa already exists/
);
});
@ -133,20 +134,20 @@ add_task(async function test_add_tombstone_sourceSync() {
let guid = profileStorage.addresses._generateGUID();
let testAddr = {guid, deleted: true};
await checkingSyncChange("add", async () =>
await checkingSyncChange("add", () =>
profileStorage.addresses.add(testAddr, {sourceSync: true}));
let added = await findGUID(profileStorage.addresses, guid,
let added = findGUID(profileStorage.addresses, guid,
{includeDeleted: true});
ok(added);
equal(getSyncChangeCounter(profileStorage.addresses, guid), 0);
ok(added.deleted);
// Adding same record again shouldn't throw (or change anything)
await checkingSyncChange("add", async () =>
await checkingSyncChange("add", () =>
profileStorage.addresses.add(testAddr, {sourceSync: true}));
added = await findGUID(profileStorage.addresses, guid,
added = findGUID(profileStorage.addresses, guid,
{includeDeleted: true});
equal(getSyncChangeCounter(profileStorage.addresses, guid), 0);
ok(added.deleted);
@ -158,18 +159,18 @@ add_task(async function test_add_resurrects_tombstones() {
let guid = profileStorage.addresses._generateGUID();
// Add a tombstone.
await profileStorage.addresses.add({guid, deleted: true});
profileStorage.addresses.add({guid, deleted: true});
// You can't re-add an item with an explicit GUID.
let resurrected = Object.assign({}, TEST_ADDRESS_1, {guid, version: 1});
await Assert.rejects(profileStorage.addresses.add(resurrected),
Assert.throws(() => profileStorage.addresses.add(resurrected),
/"(guid|version)" is not a valid field/);
// But Sync can!
let guid3 = await profileStorage.addresses.add(resurrected, {sourceSync: true});
let guid3 = profileStorage.addresses.add(resurrected, {sourceSync: true});
equal(guid, guid3);
let got = await profileStorage.addresses.get(guid);
let got = profileStorage.addresses.get(guid);
equal(got["given-name"], TEST_ADDRESS_1["given-name"]);
});
@ -177,14 +178,14 @@ add_task(async function test_remove_sourceSync_localChanges() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME, [TEST_ADDRESS_1]);
profileStorage.addresses.pullSyncChanges(); // force sync metadata
let [{guid}] = await profileStorage.addresses.getAll();
let [{guid}] = profileStorage.addresses.getAll();
equal(getSyncChangeCounter(profileStorage.addresses, guid), 1);
// try and remove a record stored locally with local changes
await checkingSyncChange("remove", async () =>
await checkingSyncChange("remove", () =>
profileStorage.addresses.remove(guid, {sourceSync: true}));
let record = await profileStorage.addresses.get(guid);
let record = profileStorage.addresses.get(guid);
ok(record);
equal(getSyncChangeCounter(profileStorage.addresses, guid), 1);
});
@ -194,10 +195,10 @@ add_task(async function test_remove_sourceSync_unknown() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME, []);
let guid = profileStorage.addresses._generateGUID();
await checkingSyncChange("remove", async () =>
await checkingSyncChange("remove", () =>
profileStorage.addresses.remove(guid, {sourceSync: true}));
let tombstone = await findGUID(profileStorage.addresses, guid, {
let tombstone = findGUID(profileStorage.addresses, guid, {
includeDeleted: true,
});
ok(tombstone.deleted);
@ -211,15 +212,15 @@ add_task(async function test_remove_sourceSync_unchanged() {
let guid = profileStorage.addresses._generateGUID();
let addr = Object.assign({guid, version: 1}, TEST_ADDRESS_1);
// add a record with sourceSync to guarantee changeCounter == 0
await checkingSyncChange("add", async () =>
await checkingSyncChange("add", () =>
profileStorage.addresses.add(addr, {sourceSync: true}));
equal(getSyncChangeCounter(profileStorage.addresses, guid), 0);
await checkingSyncChange("remove", async () =>
await checkingSyncChange("remove", () =>
profileStorage.addresses.remove(guid, {sourceSync: true}));
let tombstone = await findGUID(profileStorage.addresses, guid, {
let tombstone = findGUID(profileStorage.addresses, guid, {
includeDeleted: true,
});
ok(tombstone.deleted);
@ -230,7 +231,7 @@ add_task(async function test_pullSyncChanges() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let startAddresses = await profileStorage.addresses.getAll();
let startAddresses = profileStorage.addresses.getAll();
equal(startAddresses.length, 2);
// All should start without sync metadata
for (let {guid} of profileStorage.addresses._store.data.addresses) {
@ -243,11 +244,11 @@ add_task(async function test_pullSyncChanges() {
let testAddr = Object.assign({guid: addedDirectGUID, version: 1},
TEST_ADDRESS_1, TEST_ADDRESS_3);
await checkingSyncChange("add", async () =>
await checkingSyncChange("add", () =>
profileStorage.addresses.add(testAddr, {sourceSync: true}));
let tombstoneGUID = profileStorage.addresses._generateGUID();
await checkingSyncChange("add", async () =>
await checkingSyncChange("add", () =>
profileStorage.addresses.add(
{guid: tombstoneGUID, deleted: true},
{sourceSync: true}));
@ -258,7 +259,7 @@ add_task(async function test_pullSyncChanges() {
profileStorage.addresses.remove(startAddresses[0].guid);
await onChanged;
let addresses = await profileStorage.addresses.getAll({
let addresses = profileStorage.addresses.getAll({
includeDeleted: true,
});
@ -293,9 +294,9 @@ add_task(async function test_pullPushChanges() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME, []);
let psa = profileStorage.addresses;
let guid1 = await psa.add(TEST_ADDRESS_1);
let guid2 = await psa.add(TEST_ADDRESS_2);
let guid3 = await psa.add(TEST_ADDRESS_3);
let guid1 = psa.add(TEST_ADDRESS_1);
let guid2 = psa.add(TEST_ADDRESS_2);
let guid3 = psa.add(TEST_ADDRESS_3);
let changes = psa.pullSyncChanges();
@ -304,7 +305,7 @@ add_task(async function test_pullPushChanges() {
equal(getSyncChangeCounter(psa, guid3), 1);
// between the pull and the push we change the second.
await psa.update(guid2, Object.assign({}, TEST_ADDRESS_2, {country: "AU"}));
psa.update(guid2, Object.assign({}, TEST_ADDRESS_2, {country: "AU"}));
equal(getSyncChangeCounter(psa, guid2), 2);
// and update the changeset to indicated we did update the first 2, but failed
// to update the 3rd for some reason.
@ -326,14 +327,14 @@ add_task(async function test_changeGUID() {
let newguid = () => profileStorage.addresses._generateGUID();
let guid_synced = await profileStorage.addresses.add(TEST_ADDRESS_1);
let guid_synced = profileStorage.addresses.add(TEST_ADDRESS_1);
// pullSyncChanges so guid_synced is flagged as syncing.
profileStorage.addresses.pullSyncChanges();
// and 2 items that haven't been synced.
let guid_u1 = await profileStorage.addresses.add(TEST_ADDRESS_2);
let guid_u2 = await profileStorage.addresses.add(TEST_ADDRESS_3);
let guid_u1 = profileStorage.addresses.add(TEST_ADDRESS_2);
let guid_u2 = profileStorage.addresses.add(TEST_ADDRESS_3);
// Change a non-existing guid
Assert.throws(() => profileStorage.addresses.changeGUID(newguid(), newguid()),
@ -350,23 +351,23 @@ add_task(async function test_changeGUID() {
/changeGUID: old and new IDs are the same/);
// and one that works.
equal((await profileStorage.addresses.getAll({includeDeleted: true})).length, 3);
equal(profileStorage.addresses.getAll({includeDeleted: true}).length, 3);
let targetguid = newguid();
profileStorage.addresses.changeGUID(guid_u1, targetguid);
equal((await profileStorage.addresses.getAll({includeDeleted: true})).length, 3);
equal(profileStorage.addresses.getAll({includeDeleted: true}).length, 3);
ok(await profileStorage.addresses.get(guid_synced), "synced item still exists.");
ok(await profileStorage.addresses.get(guid_u2), "guid we didn't touch still exists.");
ok(await profileStorage.addresses.get(targetguid), "target guid exists.");
ok(!await profileStorage.addresses.get(guid_u1), "old guid no longer exists.");
ok(profileStorage.addresses.get(guid_synced), "synced item still exists.");
ok(profileStorage.addresses.get(guid_u2), "guid we didn't touch still exists.");
ok(profileStorage.addresses.get(targetguid), "target guid exists.");
ok(!profileStorage.addresses.get(guid_u1), "old guid no longer exists.");
});
add_task(async function test_findDuplicateGUID() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1]);
let [record] = await profileStorage.addresses.getAll({rawData: true});
await Assert.rejects(profileStorage.addresses.findDuplicateGUID(record),
let [record] = profileStorage.addresses.getAll({rawData: true});
Assert.throws(() => profileStorage.addresses.findDuplicateGUID(record),
/Record \w+ already exists/,
"Should throw if the GUID already exists");
@ -375,14 +376,14 @@ add_task(async function test_findDuplicateGUID() {
let timeLastModified = Date.now();
let timeCreated = timeLastModified - 60 * 1000;
await profileStorage.addresses.add({
profileStorage.addresses.add({
guid: profileStorage.addresses._generateGUID(),
version: 1,
timeCreated,
timeLastModified,
}, {sourceSync: true});
strictEqual(await profileStorage.addresses.findDuplicateGUID({
strictEqual(profileStorage.addresses.findDuplicateGUID({
guid: profileStorage.addresses._generateGUID(),
version: 1,
timeCreated,
@ -394,7 +395,7 @@ add_task(async function test_reset() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = await profileStorage.addresses.getAll();
let addresses = profileStorage.addresses.getAll();
// All should start without sync metadata
for (let {guid} of addresses) {
let changeCounter = getSyncChangeCounter(profileStorage.addresses, guid);
@ -402,14 +403,14 @@ add_task(async function test_reset() {
}
// pullSyncChanges should create the metadata.
profileStorage.addresses.pullSyncChanges();
addresses = await profileStorage.addresses.getAll();
addresses = profileStorage.addresses.getAll();
for (let {guid} of addresses) {
let changeCounter = getSyncChangeCounter(profileStorage.addresses, guid);
equal(changeCounter, 1);
}
// and resetSync should wipe it.
profileStorage.addresses.resetSync();
addresses = await profileStorage.addresses.getAll();
addresses = profileStorage.addresses.getAll();
for (let {guid} of addresses) {
let changeCounter = getSyncChangeCounter(profileStorage.addresses, guid);
equal(changeCounter, -1);

View File

@ -56,39 +56,39 @@ function add_storage_task(test_function) {
add_storage_task(async function test_simple_tombstone(storage, record) {
info("check simple tombstone semantics");
let guid = await storage.add(record);
Assert.equal((await storage.getAll()).length, 1);
let guid = storage.add(record);
Assert.equal(storage.getAll().length, 1);
storage.remove(guid);
// should be unable to get it normally.
Assert.equal(await storage.get(guid), null);
Assert.equal(storage.get(guid), null);
// and getAll should also not return it.
Assert.equal((await storage.getAll()).length, 0);
Assert.equal(storage.getAll().length, 0);
// but getAll allows us to access deleted items - but we didn't create
// a tombstone here, so even that will not get it.
let all = await storage.getAll({includeDeleted: true});
let all = storage.getAll({includeDeleted: true});
Assert.equal(all.length, 0);
});
add_storage_task(async function test_simple_synctombstone(storage, record) {
info("check simple tombstone semantics for synced records");
let guid = await storage.add(record);
Assert.equal((await storage.getAll()).length, 1);
let guid = storage.add(record);
Assert.equal(storage.getAll().length, 1);
storage.pullSyncChanges(); // force sync metadata, which triggers tombstone behaviour.
storage.remove(guid);
// should be unable to get it normally.
Assert.equal(await storage.get(guid), null);
Assert.equal(storage.get(guid), null);
// and getAll should also not return it.
Assert.equal((await storage.getAll()).length, 0);
Assert.equal(storage.getAll().length, 0);
// but getAll allows us to access deleted items.
let all = await storage.getAll({includeDeleted: true});
let all = storage.getAll({includeDeleted: true});
Assert.equal(all.length, 1);
do_check_tombstone_record(all[0]);
@ -102,15 +102,15 @@ add_storage_task(async function test_simple_synctombstone(storage, record) {
add_storage_task(async function test_add_tombstone(storage, record) {
info("Should be able to add a new tombstone");
let guid = await storage.add({guid: "test-guid-1", deleted: true});
let guid = storage.add({guid: "test-guid-1", deleted: true});
// should be unable to get it normally.
Assert.equal(await storage.get(guid), null);
Assert.equal(storage.get(guid), null);
// and getAll should also not return it.
Assert.equal((await storage.getAll()).length, 0);
Assert.equal(storage.getAll().length, 0);
// but getAll allows us to access deleted items.
let all = await storage.getAll({rawData: true, includeDeleted: true});
let all = storage.getAll({rawData: true, includeDeleted: true});
Assert.equal(all.length, 1);
do_check_tombstone_record(all[0]);
@ -124,35 +124,35 @@ add_storage_task(async function test_add_tombstone(storage, record) {
add_storage_task(async function test_add_tombstone_without_guid(storage, record) {
info("Should not be able to add a new tombstone without specifying the guid");
await Assert.rejects(storage.add({deleted: true}),
Assert.throws(() => { storage.add({deleted: true}); },
/Record missing GUID/);
Assert.equal((await storage.getAll({includeDeleted: true})).length, 0);
Assert.equal(storage.getAll({includeDeleted: true}).length, 0);
});
add_storage_task(async function test_add_tombstone_existing_guid(storage, record) {
info("Should not be able to add a new tombstone when a record with that ID exists");
let guid = await storage.add(record);
await Assert.rejects(storage.add({guid, deleted: true}),
let guid = storage.add(record);
Assert.throws(() => { storage.add({guid, deleted: true}); },
/a record with this GUID already exists/);
// same if the existing item is already a tombstone.
await storage.add({guid: "test-guid-1", deleted: true});
await Assert.rejects(storage.add({guid: "test-guid-1", deleted: true}),
storage.add({guid: "test-guid-1", deleted: true});
Assert.throws(() => { storage.add({guid: "test-guid-1", deleted: true}); },
/a record with this GUID already exists/);
});
add_storage_task(async function test_update_tombstone(storage, record) {
info("Updating a tombstone should fail");
let guid = await storage.add({guid: "test-guid-1", deleted: true});
await Assert.rejects(storage.update(guid, {}), /No matching record./);
let guid = storage.add({guid: "test-guid-1", deleted: true});
Assert.throws(() => storage.update(guid, {}), /No matching record./);
});
add_storage_task(async function test_remove_existing_tombstone(storage, record) {
info("Removing a record that's already a tombstone should be a no-op");
let guid = await storage.add({guid: "test-guid-1", deleted: true, timeLastModified: 1234});
let guid = storage.add({guid: "test-guid-1", deleted: true, timeLastModified: 1234});
storage.remove(guid);
let all = await storage.getAll({rawData: true, includeDeleted: true});
let all = storage.getAll({rawData: true, includeDeleted: true});
Assert.equal(all.length, 1);
do_check_tombstone_record(all[0]);

View File

@ -44,8 +44,8 @@ const TEST_PROFILE_2 = {
country: "US",
};
async function expectLocalProfiles(profileStorage, expected) {
let profiles = await profileStorage.addresses.getAll({
function expectLocalProfiles(profileStorage, expected) {
let profiles = profileStorage.addresses.getAll({
rawData: true,
includeDeleted: true,
});
@ -72,7 +72,7 @@ async function expectLocalProfiles(profileStorage, expected) {
async function setup() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME);
// should always start with no profiles.
Assert.equal((await profileStorage.addresses.getAll({includeDeleted: true})).length, 0);
Assert.equal(profileStorage.addresses.getAll({includeDeleted: true}).length, 0);
Services.prefs.setCharPref("services.sync.log.logger.engine.addresses", "Trace");
let engine = new AddressesEngine(Service);
@ -131,12 +131,12 @@ add_task(async function test_outgoing() {
let {profileStorage, server, collection, engine} = await setup();
try {
equal(engine._tracker.score, 0);
let existingGUID = await profileStorage.addresses.add(TEST_PROFILE_1);
let existingGUID = profileStorage.addresses.add(TEST_PROFILE_1);
// And a deleted item.
let deletedGUID = profileStorage.addresses._generateGUID();
await profileStorage.addresses.add({guid: deletedGUID, deleted: true});
profileStorage.addresses.add({guid: deletedGUID, deleted: true});
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
{
guid: existingGUID,
},
@ -157,7 +157,7 @@ add_task(async function test_outgoing() {
Assert.ok(collection.wbo(existingGUID));
Assert.ok(collection.wbo(deletedGUID));
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
{
guid: existingGUID,
},
@ -197,7 +197,7 @@ add_task(async function test_incoming_new() {
await engine.setLastSync(0);
await engine.sync();
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
{
guid: profileID,
}, {
@ -220,8 +220,8 @@ add_task(async function test_incoming_new() {
add_task(async function test_incoming_existing() {
let {profileStorage, server, engine} = await setup();
try {
let guid1 = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid2 = await profileStorage.addresses.add(TEST_PROFILE_2);
let guid1 = profileStorage.addresses.add(TEST_PROFILE_1);
let guid2 = profileStorage.addresses.add(TEST_PROFILE_2);
// an initial sync so we don't think they are locally modified.
await engine.setLastSync(0);
@ -245,7 +245,7 @@ add_task(async function test_incoming_existing() {
await engine.sync();
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
Object.assign({}, modifiedEntry1, {guid: guid1}),
{guid: guid2, deleted: true},
]);
@ -257,7 +257,7 @@ add_task(async function test_incoming_existing() {
add_task(async function test_tombstones() {
let {profileStorage, server, collection, engine} = await setup();
try {
let existingGUID = await profileStorage.addresses.add(TEST_PROFILE_1);
let existingGUID = profileStorage.addresses.add(TEST_PROFILE_1);
await engine.setLastSync(0);
await engine.sync();
@ -283,7 +283,7 @@ add_task(async function test_tombstones() {
add_task(async function test_applyIncoming_both_deleted() {
let {profileStorage, server, engine} = await setup();
try {
let guid = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid = profileStorage.addresses.add(TEST_PROFILE_1);
await engine.setLastSync(0);
await engine.sync();
@ -301,10 +301,10 @@ add_task(async function test_applyIncoming_both_deleted() {
await engine.sync();
ok(!await await profileStorage.addresses.get(guid),
ok(!profileStorage.addresses.get(guid),
"Should not return record for locally deleted item");
let localRecords = await profileStorage.addresses.getAll({
let localRecords = profileStorage.addresses.getAll({
includeDeleted: true,
});
equal(localRecords.length, 1, "Only tombstone should exist locally");
@ -329,11 +329,11 @@ add_task(async function test_applyIncoming_nonexistent_tombstone() {
await engine.setLastSync(0);
await engine.sync();
ok(!await profileStorage.addresses.get(guid),
ok(!profileStorage.addresses.get(guid),
"Should not return record for uknown deleted item");
let localTombstone = (await profileStorage.addresses.getAll({
let localTombstone = profileStorage.addresses.getAll({
includeDeleted: true,
})).find(record => record.guid == guid);
}).find(record => record.guid == guid);
ok(localTombstone, "Should store tombstone for unknown item");
} finally {
await cleanup(server);
@ -343,7 +343,7 @@ add_task(async function test_applyIncoming_nonexistent_tombstone() {
add_task(async function test_applyIncoming_incoming_deleted() {
let {profileStorage, server, engine} = await setup();
try {
let guid = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid = profileStorage.addresses.add(TEST_PROFILE_1);
await engine.setLastSync(0);
await engine.sync();
@ -358,11 +358,11 @@ add_task(async function test_applyIncoming_incoming_deleted() {
await engine.sync();
ok(!await profileStorage.addresses.get(guid), "Should delete unmodified item locally");
ok(!profileStorage.addresses.get(guid), "Should delete unmodified item locally");
let localTombstone = (await profileStorage.addresses.getAll({
let localTombstone = profileStorage.addresses.getAll({
includeDeleted: true,
})).find(record => record.guid == guid);
}).find(record => record.guid == guid);
ok(localTombstone, "Should keep local tombstone for remotely deleted item");
strictEqual(getSyncChangeCounter(profileStorage.addresses, guid), 0,
"Local tombstone should be marked as syncing");
@ -374,7 +374,7 @@ add_task(async function test_applyIncoming_incoming_deleted() {
add_task(async function test_applyIncoming_incoming_restored() {
let {profileStorage, server, engine} = await setup();
try {
let guid = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid = profileStorage.addresses.add(TEST_PROFILE_1);
// Upload the record to the server.
await engine.setLastSync(0);
@ -394,7 +394,7 @@ add_task(async function test_applyIncoming_incoming_restored() {
await engine.sync();
// We should replace our tombstone with the server's version.
let localRecord = await profileStorage.addresses.get(guid);
let localRecord = profileStorage.addresses.get(guid);
ok(objectMatches(localRecord, {
"given-name": "Timothy",
"family-name": "Berners-Lee",
@ -411,7 +411,7 @@ add_task(async function test_applyIncoming_incoming_restored() {
add_task(async function test_applyIncoming_outgoing_restored() {
let {profileStorage, server, engine} = await setup();
try {
let guid = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid = profileStorage.addresses.add(TEST_PROFILE_1);
// Upload the record to the server.
await engine.setLastSync(0);
@ -420,7 +420,7 @@ add_task(async function test_applyIncoming_outgoing_restored() {
// Modify the local record.
let localCopy = Object.assign({}, TEST_PROFILE_1);
localCopy["street-address"] = "I moved!";
await profileStorage.addresses.update(guid, localCopy);
profileStorage.addresses.update(guid, localCopy);
// Replace the record with a tombstone on the server.
let lastSync = await engine.getLastSync();
@ -442,7 +442,7 @@ add_task(async function test_applyIncoming_outgoing_restored() {
"street-address": "I moved!",
}));
let localRecord = await profileStorage.addresses.get(guid);
let localRecord = profileStorage.addresses.get(guid);
ok(localRecord, "Modified record should not be deleted locally");
} finally {
await cleanup(server);
@ -455,7 +455,7 @@ add_task(async function test_reconcile_both_modified_identical() {
let {profileStorage, server, engine} = await setup();
try {
// create a record locally.
let guid = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid = profileStorage.addresses.add(TEST_PROFILE_1);
// and an identical record on the server.
server.insertWBO("foo", "addresses", new ServerWBO(guid, encryptPayload({
@ -466,7 +466,7 @@ add_task(async function test_reconcile_both_modified_identical() {
await engine.setLastSync(0);
await engine.sync();
await expectLocalProfiles(profileStorage, [{guid}]);
expectLocalProfiles(profileStorage, [{guid}]);
} finally {
await cleanup(server);
}
@ -477,13 +477,13 @@ add_task(async function test_incoming_dupes() {
try {
// Create a profile locally, then sync to upload the new profile to the
// server.
let guid1 = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid1 = profileStorage.addresses.add(TEST_PROFILE_1);
await engine.setLastSync(0);
await engine.sync();
// Create another profile locally, but don't sync it yet.
await profileStorage.addresses.add(TEST_PROFILE_2);
profileStorage.addresses.add(TEST_PROFILE_2);
// Now create two records on the server with the same contents as our local
// profiles, but different GUIDs.
@ -507,7 +507,7 @@ add_task(async function test_incoming_dupes() {
// reconcile changes.
await engine.sync();
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
// We uploaded `guid1` during the first sync. Even though its contents
// are the same as `guid1_dupe`, we keep both.
Object.assign({}, TEST_PROFILE_1, {guid: guid1}),
@ -525,7 +525,7 @@ add_task(async function test_dedupe_identical_unsynced() {
let {profileStorage, server, engine} = await setup();
try {
// create a record locally.
let localGuid = await profileStorage.addresses.add(TEST_PROFILE_1);
let localGuid = profileStorage.addresses.add(TEST_PROFILE_1);
// and an identical record on the server but different GUID.
let remoteGuid = Utils.makeGUID();
@ -542,7 +542,7 @@ add_task(async function test_dedupe_identical_unsynced() {
// Should have 1 item locally with GUID changed to the remote one.
// There's no tombstone as the original was unsynced.
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
{
guid: remoteGuid,
},
@ -556,7 +556,7 @@ add_task(async function test_dedupe_identical_synced() {
let {profileStorage, server, engine} = await setup();
try {
// create a record locally.
let localGuid = await profileStorage.addresses.add(TEST_PROFILE_1);
let localGuid = profileStorage.addresses.add(TEST_PROFILE_1);
// sync it - it will no longer be a candidate for de-duping.
await engine.setLastSync(0);
@ -575,7 +575,7 @@ add_task(async function test_dedupe_identical_synced() {
await engine.sync();
// Should have 2 items locally, since the first was synced.
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
{guid: localGuid},
{guid: remoteGuid},
]);
@ -606,8 +606,8 @@ add_task(async function test_dedupe_multiple_candidates() {
}, localRecord);
// We don't pass `sourceSync` so that the records are marked as NEW.
let aGuid = await profileStorage.addresses.add(localRecord);
let bGuid = await profileStorage.addresses.add(localRecord);
let aGuid = profileStorage.addresses.add(localRecord);
let bGuid = profileStorage.addresses.add(localRecord);
// Insert B before A.
server.insertWBO("foo", "addresses", new ServerWBO(bGuid, encryptPayload({
@ -622,7 +622,7 @@ add_task(async function test_dedupe_multiple_candidates() {
await engine.setLastSync(0);
await engine.sync();
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
{
"guid": aGuid,
"given-name": "Mark",
@ -656,7 +656,7 @@ add_task(async function test_reconcile_both_modified_conflict() {
let {profileStorage, server, engine} = await setup();
try {
// create a record locally.
let guid = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid = profileStorage.addresses.add(TEST_PROFILE_1);
// Upload the record to the server.
await engine.setLastSync(0);
@ -668,7 +668,7 @@ add_task(async function test_reconcile_both_modified_conflict() {
// Change the same field locally and on the server.
let localCopy = Object.assign({}, TEST_PROFILE_1);
localCopy["street-address"] = "I moved!";
await profileStorage.addresses.update(guid, localCopy);
profileStorage.addresses.update(guid, localCopy);
let lastSync = await engine.getLastSync();
let collection = server.user("foo").collection("addresses");
@ -687,7 +687,7 @@ add_task(async function test_reconcile_both_modified_conflict() {
let forkedPayload = serverPayloads.find(payload => payload.id != guid);
ok(forkedPayload, "Forked record should exist on server");
await expectLocalProfiles(profileStorage, [
expectLocalProfiles(profileStorage, [
{
guid,
"given-name": "Timothy",
@ -714,9 +714,9 @@ add_task(async function test_reconcile_both_modified_conflict() {
add_task(async function test_wipe() {
let {profileStorage, server, engine} = await setup();
try {
let guid = await profileStorage.addresses.add(TEST_PROFILE_1);
let guid = profileStorage.addresses.add(TEST_PROFILE_1);
await expectLocalProfiles(profileStorage, [{guid}]);
expectLocalProfiles(profileStorage, [{guid}]);
let promiseObserved = promiseOneObserver("formautofill-storage-changed");
@ -727,7 +727,7 @@ add_task(async function test_wipe() {
Assert.equal(subject.wrappedJSObject.collectionName, "addresses", "got the correct collection");
Assert.equal(data, "removeAll", "a removeAll should be noted");
await expectLocalProfiles(profileStorage, []);
expectLocalProfiles(profileStorage, []);
} finally {
await cleanup(server);
}

View File

@ -895,15 +895,15 @@ add_task(async function test_computeAddressFields() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
for (let testcase of ADDRESS_COMPUTE_TESTCASES) {
ADDRESS_COMPUTE_TESTCASES.forEach(testcase => {
info("Verify testcase: " + testcase.description);
let guid = await profileStorage.addresses.add(testcase.address);
let address = await profileStorage.addresses.get(guid);
let guid = profileStorage.addresses.add(testcase.address);
let address = profileStorage.addresses.get(guid);
do_check_record_matches(testcase.expectedResult, address);
profileStorage.addresses.remove(guid);
}
});
await profileStorage._finalize();
});
@ -914,15 +914,15 @@ add_task(async function test_normalizeAddressFields() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
for (let testcase of ADDRESS_NORMALIZE_TESTCASES) {
ADDRESS_NORMALIZE_TESTCASES.forEach(testcase => {
info("Verify testcase: " + testcase.description);
let guid = await profileStorage.addresses.add(testcase.address);
let address = await profileStorage.addresses.get(guid);
let guid = profileStorage.addresses.add(testcase.address);
let address = profileStorage.addresses.get(guid);
do_check_record_matches(testcase.expectedResult, address);
profileStorage.addresses.remove(guid);
}
});
await profileStorage._finalize();
});
@ -933,15 +933,15 @@ add_task(async function test_computeCreditCardFields() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
for (let testcase of CREDIT_CARD_COMPUTE_TESTCASES) {
CREDIT_CARD_COMPUTE_TESTCASES.forEach(testcase => {
info("Verify testcase: " + testcase.description);
let guid = await profileStorage.creditCards.add(testcase.creditCard);
let creditCard = await profileStorage.creditCards.get(guid);
let guid = profileStorage.creditCards.add(testcase.creditCard);
let creditCard = profileStorage.creditCards.get(guid);
do_check_record_matches(testcase.expectedResult, creditCard);
profileStorage.creditCards.remove(guid);
}
});
await profileStorage._finalize();
});
@ -952,15 +952,15 @@ add_task(async function test_normalizeCreditCardFields() {
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
for (let testcase of CREDIT_CARD_NORMALIZE_TESTCASES) {
CREDIT_CARD_NORMALIZE_TESTCASES.forEach(testcase => {
info("Verify testcase: " + testcase.description);
let guid = await profileStorage.creditCards.add(testcase.creditCard);
let creditCard = await profileStorage.creditCards.get(guid, {rawData: true});
let guid = profileStorage.creditCards.add(testcase.creditCard);
let creditCard = profileStorage.creditCards.get(guid, {rawData: true});
do_check_record_matches(testcase.expectedResult, creditCard);
profileStorage.creditCards.remove(guid);
}
});
await profileStorage._finalize();
});

View File

@ -39,7 +39,7 @@ class FormAutofillBase {
async Create() {
const storage = await this.getStorage();
await storage.add(this.props);
storage.add(this.props);
}
async Find() {
@ -52,7 +52,7 @@ class FormAutofillBase {
async Update() {
const storage = await this.getStorage();
const {guid} = await this.Find();
await storage.update(guid, this.updateProps, true);
storage.update(guid, this.updateProps, true);
}
async Remove() {
@ -110,9 +110,8 @@ class CreditCard extends FormAutofillBase {
async Find() {
const storage = await this.getStorage();
await Promise.all(storage._data.map(
async entry => entry["cc-number"] = await MasterPassword.decrypt(entry["cc-number-encrypted"])));
return storage._data.find(entry => {
entry["cc-number"] = MasterPassword.decryptSync(entry["cc-number-encrypted"]);
return this._fields.every(field => entry[field] === this.props[field]);
});
}