Backed out changeset bd6b3707b0b4 (bug 1836450) for causing xpcshell failures on...
[gecko.git] / browser / extensions / formautofill / test / unit / test_creditCardRecords.js
blob3b295c8ef7c82596d6ba1ae229666df8f96d1db8
1 /**
2  * Tests FormAutofillStorage object with creditCards records.
3  */
5 "use strict";
7 ChromeUtils.defineESModuleGetters(this, {
8   Preferences: "resource://gre/modules/Preferences.sys.mjs",
9 });
10 const { CreditCard } = ChromeUtils.importESModule(
11   "resource://gre/modules/CreditCard.sys.mjs"
14 let FormAutofillStorage;
15 let CREDIT_CARD_SCHEMA_VERSION;
16 add_setup(async () => {
17   ({ FormAutofillStorage } = ChromeUtils.importESModule(
18     "resource://autofill/FormAutofillStorage.sys.mjs"
19   ));
20   ({ CREDIT_CARD_SCHEMA_VERSION } = ChromeUtils.importESModule(
21     "resource://autofill/FormAutofillStorageBase.sys.mjs"
22   ));
23 });
25 const TEST_STORE_FILE_NAME = "test-credit-card.json";
26 const COLLECTION_NAME = "creditCards";
28 const TEST_CREDIT_CARD_1 = {
29   "cc-name": "John Doe",
30   "cc-number": "4929001587121045",
31   "cc-exp-month": 4,
32   "cc-exp-year": 2017,
35 const TEST_CREDIT_CARD_2 = {
36   "cc-name": "Timothy Berners-Lee",
37   "cc-number": "5103059495477870",
38   "cc-exp-month": 12,
39   "cc-exp-year": 2022,
42 const TEST_CREDIT_CARD_3 = {
43   "cc-number": "3589993783099582",
44   "cc-exp-month": 1,
45   "cc-exp-year": 2000,
48 const TEST_CREDIT_CARD_WITH_BILLING_ADDRESS = {
49   "cc-name": "J. Smith",
50   "cc-number": "4111111111111111",
51   billingAddressGUID: "9m6hf4gfr6ge",
54 const TEST_CREDIT_CARD_WITH_EMPTY_FIELD = {
55   billingAddressGUID: "",
56   "cc-name": "",
57   "cc-number": "344060747836806",
58   "cc-exp-month": 1,
61 const TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD = {
62   "cc-given-name": "",
63   "cc-additional-name": "",
64   "cc-family-name": "",
65   "cc-exp": "",
66   "cc-number": "5415425865751454",
69 const TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR = {
70   "cc-number": "344060747836806",
71   "cc-exp-month": 1,
72   "cc-exp-year": 12,
75 const TEST_CREDIT_CARD_WITH_INVALID_FIELD = {
76   "cc-name": "John Doe",
77   "cc-number": "344060747836806",
78   "cc-type": { invalid: "invalid" },
81 const TEST_CREDIT_CARD_WITH_INVALID_EXPIRY_DATE = {
82   "cc-name": "John Doe",
83   "cc-number": "5103059495477870",
84   "cc-exp-month": 13,
85   "cc-exp-year": -3,
88 const TEST_CREDIT_CARD_WITH_SPACES_BETWEEN_DIGITS = {
89   "cc-name": "John Doe",
90   "cc-number": "5103 0594 9547 7870",
93 const TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE = {
94   "cc-exp-month": 13,
97 const TEST_CREDIT_CARD_EMPTY_AFTER_UPDATE_CREDIT_CARD_1 = {
98   "cc-name": "",
99   "cc-number": "",
100   "cc-exp-month": 13,
101   "cc-exp-year": "",
104 let prepareTestCreditCards = async function (path) {
105   let profileStorage = new FormAutofillStorage(path);
106   await profileStorage.initialize();
108   let onChanged = TestUtils.topicObserved(
109     "formautofill-storage-changed",
110     (subject, data) =>
111       data == "add" &&
112       subject.wrappedJSObject.guid &&
113       subject.wrappedJSObject.collectionName == COLLECTION_NAME
114   );
115   Assert.ok(await profileStorage.creditCards.add(TEST_CREDIT_CARD_1));
116   await onChanged;
117   Assert.ok(await profileStorage.creditCards.add(TEST_CREDIT_CARD_2));
118   await onChanged;
119   await profileStorage._saveImmediately();
122 let reCCNumber = /^(\*+)(.{4})$/;
124 let do_check_credit_card_matches = (creditCardWithMeta, creditCard) => {
125   for (let key in creditCard) {
126     if (key == "cc-number") {
127       let matches = reCCNumber.exec(creditCardWithMeta["cc-number"]);
128       Assert.notEqual(matches, null);
129       Assert.equal(
130         creditCardWithMeta["cc-number"].length,
131         creditCard["cc-number"].length
132       );
133       Assert.equal(creditCard["cc-number"].endsWith(matches[2]), true);
134       Assert.notEqual(creditCard["cc-number-encrypted"], "");
135     } else {
136       Assert.equal(creditCardWithMeta[key], creditCard[key], "Testing " + key);
137     }
138   }
141 add_task(async function test_initialize() {
142   let path = getTempFile(TEST_STORE_FILE_NAME).path;
143   let profileStorage = new FormAutofillStorage(path);
144   await profileStorage.initialize();
146   Assert.equal(profileStorage._store.data.version, 1);
147   Assert.equal(profileStorage._store.data.creditCards.length, 0);
149   let data = profileStorage._store.data;
150   Assert.deepEqual(data.creditCards, []);
152   await profileStorage._saveImmediately();
154   profileStorage = new FormAutofillStorage(path);
155   await profileStorage.initialize();
157   Assert.deepEqual(profileStorage._store.data, data);
160 add_task(async function test_getAll() {
161   let path = getTempFile(TEST_STORE_FILE_NAME).path;
162   await prepareTestCreditCards(path);
164   let profileStorage = new FormAutofillStorage(path);
165   await profileStorage.initialize();
167   let creditCards = await profileStorage.creditCards.getAll();
169   Assert.equal(creditCards.length, 2);
170   do_check_credit_card_matches(creditCards[0], TEST_CREDIT_CARD_1);
171   do_check_credit_card_matches(creditCards[1], TEST_CREDIT_CARD_2);
173   // Check computed fields.
174   Assert.equal(creditCards[0]["cc-given-name"], "John");
175   Assert.equal(creditCards[0]["cc-family-name"], "Doe");
176   Assert.equal(creditCards[0]["cc-exp"], "2017-04");
178   // Test with rawData set.
179   creditCards = await profileStorage.creditCards.getAll({ rawData: true });
180   Assert.equal(creditCards[0]["cc-given-name"], undefined);
181   Assert.equal(creditCards[0]["cc-family-name"], undefined);
182   Assert.equal(creditCards[0]["cc-exp"], undefined);
184   // Modifying output shouldn't affect the storage.
185   creditCards[0]["cc-name"] = "test";
186   do_check_credit_card_matches(
187     (await profileStorage.creditCards.getAll())[0],
188     TEST_CREDIT_CARD_1
189   );
192 add_task(async function test_get() {
193   let path = getTempFile(TEST_STORE_FILE_NAME).path;
194   await prepareTestCreditCards(path);
196   let profileStorage = new FormAutofillStorage(path);
197   await profileStorage.initialize();
199   let creditCards = await profileStorage.creditCards.getAll();
200   let guid = creditCards[0].guid;
202   let creditCard = await profileStorage.creditCards.get(guid);
203   do_check_credit_card_matches(creditCard, TEST_CREDIT_CARD_1);
205   // Modifying output shouldn't affect the storage.
206   creditCards[0]["cc-name"] = "test";
207   do_check_credit_card_matches(
208     await profileStorage.creditCards.get(guid),
209     TEST_CREDIT_CARD_1
210   );
212   Assert.equal(await profileStorage.creditCards.get("INVALID_GUID"), null);
215 add_task(async function test_add() {
216   let path = getTempFile(TEST_STORE_FILE_NAME).path;
217   await prepareTestCreditCards(path);
219   let profileStorage = new FormAutofillStorage(path);
220   await profileStorage.initialize();
222   let creditCards = await profileStorage.creditCards.getAll();
224   Assert.equal(creditCards.length, 2);
226   do_check_credit_card_matches(creditCards[0], TEST_CREDIT_CARD_1);
227   do_check_credit_card_matches(creditCards[1], TEST_CREDIT_CARD_2);
229   Assert.notEqual(creditCards[0].guid, undefined);
230   Assert.equal(creditCards[0].version, CREDIT_CARD_SCHEMA_VERSION);
231   Assert.notEqual(creditCards[0].timeCreated, undefined);
232   Assert.equal(creditCards[0].timeLastModified, creditCards[0].timeCreated);
233   Assert.equal(creditCards[0].timeLastUsed, 0);
234   Assert.equal(creditCards[0].timesUsed, 0);
236   // Empty string should be deleted before saving.
237   await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_EMPTY_FIELD);
238   let creditCard = profileStorage.creditCards._data[2];
239   Assert.equal(
240     creditCard["cc-exp-month"],
241     TEST_CREDIT_CARD_WITH_EMPTY_FIELD["cc-exp-month"]
242   );
243   Assert.equal(creditCard["cc-name"], undefined);
244   Assert.equal(creditCard.billingAddressGUID, undefined);
246   // Empty computed fields shouldn't cause any problem.
247   await profileStorage.creditCards.add(
248     TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD
249   );
250   creditCard = profileStorage.creditCards._data[3];
251   Assert.equal(
252     creditCard["cc-number"],
253     CreditCard.getLongMaskedNumber(
254       TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD["cc-number"]
255     )
256   );
258   await Assert.rejects(
259     profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_INVALID_FIELD),
260     /"cc-type" contains invalid data type: object/
261   );
263   await Assert.rejects(
264     profileStorage.creditCards.add({}),
265     /Record contains no valid field\./
266   );
268   await Assert.rejects(
269     profileStorage.creditCards.add(TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE),
270     /Record contains no valid field\./
271   );
274 add_task(async function test_addWithBillingAddress() {
275   let path = getTempFile(TEST_STORE_FILE_NAME).path;
276   let profileStorage = new FormAutofillStorage(path);
277   await profileStorage.initialize();
279   let creditCards = await profileStorage.creditCards.getAll();
281   Assert.equal(creditCards.length, 0);
283   await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_BILLING_ADDRESS);
285   creditCards = await profileStorage.creditCards.getAll();
286   Assert.equal(creditCards.length, 1);
287   do_check_credit_card_matches(
288     creditCards[0],
289     TEST_CREDIT_CARD_WITH_BILLING_ADDRESS
290   );
293 add_task(async function test_update() {
294   // Test assumes that when an entry is saved a second time, it's last modified date will
295   // be different from the first. With high values of precision reduction, we execute too
296   // fast for that to be true.
297   let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
298   Preferences.set("privacy.reduceTimerPrecision", false);
300   registerCleanupFunction(function () {
301     Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
302   });
304   let path = getTempFile(TEST_STORE_FILE_NAME).path;
305   await prepareTestCreditCards(path);
307   let profileStorage = new FormAutofillStorage(path);
308   await profileStorage.initialize();
310   let creditCards = await profileStorage.creditCards.getAll();
311   let guid = creditCards[1].guid;
312   let timeLastModified = creditCards[1].timeLastModified;
314   let onChanged = TestUtils.topicObserved(
315     "formautofill-storage-changed",
316     (subject, data) =>
317       data == "update" &&
318       subject.wrappedJSObject.guid == guid &&
319       subject.wrappedJSObject.collectionName == COLLECTION_NAME
320   );
322   Assert.notEqual(creditCards[1]["cc-name"], undefined);
323   await profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_3);
324   await onChanged;
325   await profileStorage._saveImmediately();
327   profileStorage = new FormAutofillStorage(path);
328   await profileStorage.initialize();
330   let creditCard = await profileStorage.creditCards.get(guid);
332   Assert.equal(creditCard["cc-name"], undefined);
333   Assert.notEqual(creditCard.timeLastModified, timeLastModified);
334   do_check_credit_card_matches(creditCard, TEST_CREDIT_CARD_3);
336   // Empty string should be deleted while updating.
337   await profileStorage.creditCards.update(
338     profileStorage.creditCards._data[0].guid,
339     TEST_CREDIT_CARD_WITH_EMPTY_FIELD
340   );
341   creditCard = profileStorage.creditCards._data[0];
342   Assert.equal(
343     creditCard["cc-exp-month"],
344     TEST_CREDIT_CARD_WITH_EMPTY_FIELD["cc-exp-month"]
345   );
346   Assert.equal(creditCard["cc-name"], undefined);
347   Assert.equal(creditCard["cc-type"], "amex");
348   Assert.equal(creditCard.billingAddressGUID, undefined);
350   // Empty computed fields shouldn't cause any problem.
351   await profileStorage.creditCards.update(
352     profileStorage.creditCards._data[0].guid,
353     TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD,
354     false
355   );
356   creditCard = profileStorage.creditCards._data[0];
357   Assert.equal(
358     creditCard["cc-number"],
359     CreditCard.getLongMaskedNumber(
360       TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD["cc-number"]
361     )
362   );
363   await profileStorage.creditCards.update(
364     profileStorage.creditCards._data[1].guid,
365     TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD,
366     true
367   );
368   creditCard = profileStorage.creditCards._data[1];
369   Assert.equal(
370     creditCard["cc-number"],
371     CreditCard.getLongMaskedNumber(
372       TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD["cc-number"]
373     )
374   );
376   // Decryption failure of existing record should not prevent it from being updated.
377   creditCard = profileStorage.creditCards._data[0];
378   creditCard["cc-number-encrypted"] = "INVALID";
379   await profileStorage.creditCards.update(
380     profileStorage.creditCards._data[0].guid,
381     TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD,
382     false
383   );
384   creditCard = profileStorage.creditCards._data[0];
385   Assert.equal(
386     creditCard["cc-number"],
387     CreditCard.getLongMaskedNumber(
388       TEST_CREDIT_CARD_WITH_EMPTY_COMPUTED_FIELD["cc-number"]
389     )
390   );
392   await Assert.rejects(
393     profileStorage.creditCards.update("INVALID_GUID", TEST_CREDIT_CARD_3),
394     /No matching record\./
395   );
397   await Assert.rejects(
398     profileStorage.creditCards.update(
399       guid,
400       TEST_CREDIT_CARD_WITH_INVALID_FIELD
401     ),
402     /"cc-type" contains invalid data type: object/
403   );
405   await Assert.rejects(
406     profileStorage.creditCards.update(guid, {}),
407     /Record contains no valid field\./
408   );
410   await Assert.rejects(
411     profileStorage.creditCards.update(
412       guid,
413       TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE
414     ),
415     /Record contains no valid field\./
416   );
418   await profileStorage.creditCards.update(guid, TEST_CREDIT_CARD_1);
419   await Assert.rejects(
420     profileStorage.creditCards.update(
421       guid,
422       TEST_CREDIT_CARD_EMPTY_AFTER_UPDATE_CREDIT_CARD_1
423     ),
424     /Record contains no valid field\./
425   );
428 add_task(async function test_validate() {
429   let path = getTempFile(TEST_STORE_FILE_NAME).path;
431   let profileStorage = new FormAutofillStorage(path);
432   await profileStorage.initialize();
434   await profileStorage.creditCards.add(
435     TEST_CREDIT_CARD_WITH_INVALID_EXPIRY_DATE
436   );
437   await profileStorage.creditCards.add(TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR);
438   await profileStorage.creditCards.add(
439     TEST_CREDIT_CARD_WITH_SPACES_BETWEEN_DIGITS
440   );
441   let creditCards = await profileStorage.creditCards.getAll();
443   Assert.equal(creditCards[0]["cc-exp-month"], undefined);
444   Assert.equal(creditCards[0]["cc-exp-year"], undefined);
445   Assert.equal(creditCards[0]["cc-exp"], undefined);
447   let month = TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR["cc-exp-month"];
448   let year =
449     parseInt(TEST_CREDIT_CARD_WITH_2_DIGITS_YEAR["cc-exp-year"], 10) + 2000;
450   Assert.equal(creditCards[1]["cc-exp-month"], month);
451   Assert.equal(creditCards[1]["cc-exp-year"], year);
452   Assert.equal(
453     creditCards[1]["cc-exp"],
454     year + "-" + month.toString().padStart(2, "0")
455   );
457   Assert.equal(creditCards[2]["cc-number"].length, 16);
460 add_task(async function test_notifyUsed() {
461   let path = getTempFile(TEST_STORE_FILE_NAME).path;
462   await prepareTestCreditCards(path);
464   let profileStorage = new FormAutofillStorage(path);
465   await profileStorage.initialize();
467   let creditCards = await profileStorage.creditCards.getAll();
468   let guid = creditCards[1].guid;
469   let timeLastUsed = creditCards[1].timeLastUsed;
470   let timesUsed = creditCards[1].timesUsed;
472   let onChanged = TestUtils.topicObserved(
473     "formautofill-storage-changed",
474     (subject, data) =>
475       data == "notifyUsed" &&
476       subject.wrappedJSObject.collectionName == COLLECTION_NAME &&
477       subject.wrappedJSObject.guid == guid
478   );
480   profileStorage.creditCards.notifyUsed(guid);
481   await onChanged;
482   await profileStorage._saveImmediately();
484   profileStorage = new FormAutofillStorage(path);
485   await profileStorage.initialize();
487   let creditCard = await profileStorage.creditCards.get(guid);
489   Assert.equal(creditCard.timesUsed, timesUsed + 1);
490   Assert.notEqual(creditCard.timeLastUsed, timeLastUsed);
492   Assert.throws(
493     () => profileStorage.creditCards.notifyUsed("INVALID_GUID"),
494     /No matching record\./
495   );
498 add_task(async function test_remove() {
499   let path = getTempFile(TEST_STORE_FILE_NAME).path;
500   await prepareTestCreditCards(path);
502   let profileStorage = new FormAutofillStorage(path);
503   await profileStorage.initialize();
505   let creditCards = await profileStorage.creditCards.getAll();
506   let guid = creditCards[1].guid;
508   let onChanged = TestUtils.topicObserved(
509     "formautofill-storage-changed",
510     (subject, data) =>
511       data == "remove" &&
512       subject.wrappedJSObject.guid == guid &&
513       subject.wrappedJSObject.collectionName == COLLECTION_NAME
514   );
516   Assert.equal(creditCards.length, 2);
518   profileStorage.creditCards.remove(guid);
519   await onChanged;
520   await profileStorage._saveImmediately();
522   profileStorage = new FormAutofillStorage(path);
523   await profileStorage.initialize();
525   creditCards = await profileStorage.creditCards.getAll();
527   Assert.equal(creditCards.length, 1);
529   Assert.equal(await profileStorage.creditCards.get(guid), null);
532 add_task(async function test_getDuplicateRecords() {
533   let profileStorage = await initProfileStorage(
534     TEST_STORE_FILE_NAME,
535     [TEST_CREDIT_CARD_3],
536     "creditCards"
537   );
538   let guid = profileStorage.creditCards._data[0].guid;
540   // Absolutely a duplicate.
541   let getDuplicateRecords =
542     profileStorage.creditCards.getDuplicateRecords(TEST_CREDIT_CARD_3);
543   let dupe = (await getDuplicateRecords.next()).value;
544   Assert.equal(dupe.guid, guid);
546   // Absolutely not a duplicate.
547   getDuplicateRecords =
548     profileStorage.creditCards.getDuplicateRecords(TEST_CREDIT_CARD_1);
549   dupe = (await getDuplicateRecords.next()).value;
550   Assert.equal(dupe, null);
552   // Subset with the same number is a duplicate.
553   let record = Object.assign({}, TEST_CREDIT_CARD_3);
554   delete record["cc-exp-month"];
555   getDuplicateRecords = profileStorage.creditCards.getDuplicateRecords(record);
556   dupe = (await getDuplicateRecords.next()).value;
557   Assert.equal(dupe.guid, guid);
559   // Superset with the same number is a duplicate.
560   record = Object.assign({}, TEST_CREDIT_CARD_3);
561   record["cc-name"] = "John Doe";
562   getDuplicateRecords = profileStorage.creditCards.getDuplicateRecords(record);
563   dupe = (await getDuplicateRecords.next()).value;
564   Assert.equal(dupe.guid, guid);
566   // Numbers with the same last 4 digits shouldn't be treated as a duplicate.
567   record = Object.assign({}, TEST_CREDIT_CARD_3);
568   let last4Digits = record["cc-number"].substr(-4);
569   getDuplicateRecords = profileStorage.creditCards.getDuplicateRecords(record);
570   dupe = (await getDuplicateRecords.next()).value;
571   Assert.equal(dupe.guid, guid);
573   // This number differs from TEST_CREDIT_CARD_3 by swapping the order of the
574   // 09 and 90 adjacent digits, which is still a valid credit card number.
575   record["cc-number"] = "358999378390" + last4Digits;
577   // We don't treat numbers with the same last 4 digits as a duplicate.
578   getDuplicateRecords = profileStorage.creditCards.getDuplicateRecords(record);
579   dupe = (await getDuplicateRecords.next()).value;
580   Assert.equal(dupe, null);
583 add_task(async function test_getDuplicateRecordsMatch() {
584   let profileStorage = await initProfileStorage(
585     TEST_STORE_FILE_NAME,
586     [TEST_CREDIT_CARD_2],
587     "creditCards"
588   );
589   let guid = profileStorage.creditCards._data[0].guid;
591   // Absolutely a duplicate.
592   let getDuplicateRecords =
593     profileStorage.creditCards.getDuplicateRecords(TEST_CREDIT_CARD_2);
594   let dupe = (await getDuplicateRecords.next()).value;
595   Assert.equal(dupe.guid, guid);
597   // Absolutely not a duplicate.
598   getDuplicateRecords =
599     profileStorage.creditCards.getDuplicateRecords(TEST_CREDIT_CARD_1);
600   dupe = (await getDuplicateRecords.next()).value;
601   Assert.equal(dupe, null);
603   record = Object.assign({}, TEST_CREDIT_CARD_2);
605   // We change month from `1` to `2`
606   record["cc-exp-month"] = 2;
607   getDuplicateRecords = profileStorage.creditCards.getDuplicateRecords(record);
608   dupe = (await getDuplicateRecords.next()).value;
609   Assert.equal(dupe.guid, guid);
611   // We change year from `2000` to `2001`
612   record["cc-exp-year"] = 2001;
613   getDuplicateRecords = profileStorage.creditCards.getDuplicateRecords(record);
614   dupe = (await getDuplicateRecords.next()).value;
615   Assert.equal(dupe.guid, guid);
617   // New name, same card
618   record["cc-name"] = "John Doe";
619   getDuplicateRecords = profileStorage.creditCards.getDuplicateRecords(record);
620   dupe = (await getDuplicateRecords.next()).value;
621   Assert.equal(dupe.guid, guid);
624 add_task(async function test_getMatchRecord() {
625   let profileStorage = await initProfileStorage(
626     TEST_STORE_FILE_NAME,
627     [TEST_CREDIT_CARD_2],
628     "creditCards"
629   );
630   let guid = profileStorage.creditCards._data[0].guid;
632   const TEST_FIELDS = {
633     "cc-name": "John Doe",
634     "cc-exp-month": 10,
635     "cc-exp-year": 2001,
636   };
638   // Absolutely a match.
639   let getMatchRecords =
640     profileStorage.creditCards.getMatchRecords(TEST_CREDIT_CARD_2);
641   let match = (await getMatchRecords.next()).value;
642   Assert.equal(match.guid, guid);
644   // Subset with the same number is a match.
645   for (const field of Object.keys(TEST_FIELDS)) {
646     let record = Object.assign({}, TEST_CREDIT_CARD_2);
647     delete record[field];
648     getMatchRecords = profileStorage.creditCards.getMatchRecords(record);
649     match = (await getMatchRecords.next()).value;
650     Assert.equal(match.guid, guid);
651   }
653   // Subset with different number is not a match.
654   for (const field of Object.keys(TEST_FIELDS)) {
655     let record = Object.assign({}, TEST_CREDIT_CARD_2, {
656       "cc-number": TEST_CREDIT_CARD_1["cc-number"],
657     });
658     delete record[field];
659     getMatchRecords = profileStorage.creditCards.getMatchRecords(record);
660     match = (await getMatchRecords.next()).value;
661     Assert.equal(match, null);
662   }
664   // Superset with the same number is not a match.
665   for (const [field, value] of Object.entries(TEST_FIELDS)) {
666     let record = Object.assign({}, TEST_CREDIT_CARD_2);
667     record[field] = value;
668     getMatchRecords = profileStorage.creditCards.getMatchRecords(record);
669     match = (await getMatchRecords.next()).value;
670     Assert.equal(match, null);
671   }
673   // Superset with different number is not a match.
674   for (const [field, value] of Object.entries(TEST_FIELDS)) {
675     let record = Object.assign({}, TEST_CREDIT_CARD_2, {
676       "cc-number": TEST_CREDIT_CARD_1["cc-number"],
677     });
678     record[field] = value;
679     getMatchRecords = profileStorage.creditCards.getMatchRecords(record);
680     match = (await getMatchRecords.next()).value;
681     Assert.equal(match, null);
682   }
685 add_task(async function test_creditCardFillDisabled() {
686   Services.prefs.setBoolPref(
687     "extensions.formautofill.creditCards.enabled",
688     false
689   );
691   let path = getTempFile(TEST_STORE_FILE_NAME).path;
692   let profileStorage = new FormAutofillStorage(path);
693   await profileStorage.initialize();
695   Assert.equal(
696     !!profileStorage.creditCards,
697     true,
698     "credit card records initialized and available."
699   );
701   Services.prefs.setBoolPref(
702     "extensions.formautofill.creditCards.enabled",
703     true
704   );