summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/import/test/unit/resources
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--comm/mailnews/import/test/unit/resources/AB_README39
-rw-r--r--comm/mailnews/import/test/unit/resources/WindowsLiveMail/MicrosoftCommunities/account{2E23}.oeaccountbin0 -> 698 bytes
-rw-r--r--comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallimap/donhallimap{testimap}.oeaccountbin0 -> 4454 bytes
-rw-r--r--comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallnntp/donhallnntp{testnntp}.oeaccountbin0 -> 2728 bytes
-rw-r--r--comm/mailnews/import/test/unit/resources/WindowsLiveMail/news.mozilla.org/account{B3B3}.oeaccountbin0 -> 960 bytes
-rw-r--r--comm/mailnews/import/test/unit/resources/WindowsLiveMail/pop3.test.test/account{D244}.oeaccountbin0 -> 1478 bytes
-rw-r--r--comm/mailnews/import/test/unit/resources/addressbook.json170
-rw-r--r--comm/mailnews/import/test/unit/resources/basic_addressbook.csv2
-rw-r--r--comm/mailnews/import/test/unit/resources/basic_csv_addressbook.csv3
-rw-r--r--comm/mailnews/import/test/unit/resources/basic_ldif_addressbook.ldif45
-rw-r--r--comm/mailnews/import/test/unit/resources/basic_vcard_addressbook.vcf12
-rw-r--r--comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186e.bab26
-rw-r--r--comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186f.bab13
-rw-r--r--comm/mailnews/import/test/unit/resources/becky/addressbooks/do_not_import_this.nobab12
-rw-r--r--comm/mailnews/import/test/unit/resources/becky/filters/IFilter.def23
-rw-r--r--comm/mailnews/import/test/unit/resources/becky/filters/OFilter.def22
-rw-r--r--comm/mailnews/import/test/unit/resources/bug_263304.ldif7
-rw-r--r--comm/mailnews/import/test/unit/resources/csv_no_header.csv2
-rw-r--r--comm/mailnews/import/test/unit/resources/csv_semicolon.csv3
-rw-r--r--comm/mailnews/import/test/unit/resources/dos_vcard_addressbook.vcf6
-rw-r--r--comm/mailnews/import/test/unit/resources/emptylines_vcard_addressbook.vcf18
-rw-r--r--comm/mailnews/import/test/unit/resources/import_helper.js665
-rw-r--r--comm/mailnews/import/test/unit/resources/mock_windows_reg_factory.js84
-rw-r--r--comm/mailnews/import/test/unit/resources/quote.csv2
-rw-r--r--comm/mailnews/import/test/unit/resources/shiftjis_addressbook.csv2
-rw-r--r--comm/mailnews/import/test/unit/resources/tab_comma_mixed.csv4
-rw-r--r--comm/mailnews/import/test/unit/resources/utf16_addressbook.csvbin0 -> 1006 bytes
27 files changed, 1160 insertions, 0 deletions
diff --git a/comm/mailnews/import/test/unit/resources/AB_README b/comm/mailnews/import/test/unit/resources/AB_README
new file mode 100644
index 0000000000..3cbeb09508
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/AB_README
@@ -0,0 +1,39 @@
+To test importing an address book, make a new file in the
+/import/test/unit directory with the prefix test_ in the filename
+(ex. test_ldif_import.js).
+
+It should have a function named run_test with no parameters. If you are using
+import_helper.js, which is already imported, you must at least get the file
+to import and make a new AbImportHelper object with at least the file and type
+of import. Call the beginImport method on the object when you are ready to
+start the import.
+
+If you would like the results of the import checked, make sure to update
+addressbook.json. This file is read by import_helper.js to compare the address
+book cards imported to an array of "cards" in in this file. When making a new
+import, first chose a name for the array (like basic_addressbook) to store the
+cards that should be in the newly-imported address book. The properties and
+values of each object in the array should identical to the properties and values
+of the newly-imported card(s) and the cards themselves need to be in the
+expected order. If a card to be imported does not have a property, do not
+include it in the JSON card. Multiple types of imports can be tested with one
+array, as only the supported attributes are checked.
+
+You will also need to give the AbImportHelper constructor two additional
+parameters: the name the imported address book will have (the filename without
+the extension) and the name you chose for the JSON object.
+
+Here is a sample LDIF unit test that doesn't check the results:
+function run_test()
+{
+ var file = do_get_file("resources/basic_ldif_addressbook.ldif");
+ new AbImportHelper(file, "Text file").beginImport();
+}
+
+Here is a sample CSV unit test that checks the results:
+function run_test()
+{
+ var file = do_get_file("resources/basic_csv_addressbook.csv");
+ new AbImportHelper(file, "Text file", "basic_csv_addressbook",
+ "basic_addressbook").beginImport();
+}
diff --git a/comm/mailnews/import/test/unit/resources/WindowsLiveMail/MicrosoftCommunities/account{2E23}.oeaccount b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/MicrosoftCommunities/account{2E23}.oeaccount
new file mode 100644
index 0000000000..b1b278658a
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/MicrosoftCommunities/account{2E23}.oeaccount
Binary files differ
diff --git a/comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallimap/donhallimap{testimap}.oeaccount b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallimap/donhallimap{testimap}.oeaccount
new file mode 100644
index 0000000000..c23cf25d17
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallimap/donhallimap{testimap}.oeaccount
Binary files differ
diff --git a/comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallnntp/donhallnntp{testnntp}.oeaccount b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallnntp/donhallnntp{testnntp}.oeaccount
new file mode 100644
index 0000000000..65872dcdbe
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/donhallnntp/donhallnntp{testnntp}.oeaccount
Binary files differ
diff --git a/comm/mailnews/import/test/unit/resources/WindowsLiveMail/news.mozilla.org/account{B3B3}.oeaccount b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/news.mozilla.org/account{B3B3}.oeaccount
new file mode 100644
index 0000000000..f17de718ae
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/news.mozilla.org/account{B3B3}.oeaccount
Binary files differ
diff --git a/comm/mailnews/import/test/unit/resources/WindowsLiveMail/pop3.test.test/account{D244}.oeaccount b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/pop3.test.test/account{D244}.oeaccount
new file mode 100644
index 0000000000..5ec08c4945
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/WindowsLiveMail/pop3.test.test/account{D244}.oeaccount
Binary files differ
diff --git a/comm/mailnews/import/test/unit/resources/addressbook.json b/comm/mailnews/import/test/unit/resources/addressbook.json
new file mode 100644
index 0000000000..c9545d3027
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/addressbook.json
@@ -0,0 +1,170 @@
+{
+ "basic_addressbook": [
+ {
+ "DisplayName": "Display Name",
+ "PrimaryEmail": "primaryemail@host.invalid",
+ "FirstName": "First",
+ "LastName": "Last",
+ "NickName": "Nickname",
+ "SecondEmail": "secondemail@host.invalid",
+ "_AimScreenName": "screenname",
+ "LastModifiedDate": 1213818826,
+ "_vCard": [
+ "VERSION:4.0",
+ "FN:Display Name",
+ "EMAIL;PREF=1:primaryemail@host.invalid",
+ "EMAIL:secondemail@host.invalid",
+ "NICKNAME:Nickname",
+ "NOTE:Notes line 1\\nNotes line 2\\nNotes line 3\\nNotes line 4",
+ "ORG:Organization Name;Department",
+ "TITLE:Job Title",
+ "BDAY;VALUE=DATE:19000102",
+ "N:Last;First;;;",
+ "ADR;TYPE=home:;Home Address Line 2;Home Address Line 1;Home City;Home State",
+ " ;Home Zip;Home Country",
+ "ADR;TYPE=work:;Work Address Line 2;Work Address Line 1;Work City;Work State",
+ " ;Work Zip;Work Country",
+ "TEL;TYPE=home;VALUE=TEXT:234-567-8901",
+ "TEL;TYPE=work;VALUE=TEXT:123-456-7890",
+ "TEL;TYPE=fax;VALUE=TEXT:345-678-9012",
+ "TEL;TYPE=pager;VALUE=TEXT:456-789-0123",
+ "TEL;TYPE=cell;VALUE=TEXT:567-890-1234",
+ "URL;TYPE=work;VALUE=URL:http://127.0.0.1",
+ "URL;TYPE=home;VALUE=URL:http://localhost",
+ "X-CUSTOM1;VALUE=TEXT:Custom Field 1",
+ "X-CUSTOM2;VALUE=TEXT:Custom Field 2",
+ "X-CUSTOM3;VALUE=TEXT:Custom Field 3",
+ "X-CUSTOM4;VALUE=TEXT:Custom Field 4",
+ "UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ ]
+ }
+ ],
+ "bug_263304": [
+ {
+ "DisplayName": "Display Name",
+ "PrimaryEmail": "primaryemail@host.invalid",
+ "_vCard": [
+ "VERSION:4.0",
+ "FN:Display Name",
+ "EMAIL;PREF=1:primaryemail@host.invalid",
+ "URL;TYPE=work;VALUE=URL:http://127.0.0.1",
+ "UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ ]
+ }
+ ],
+ "utf16_csv": [
+ {
+ "DisplayName": "John Doe",
+ "PrimaryEmail": "johndoe@host.invalid",
+ "FirstName": "John",
+ "LastName": "Doe"
+ }
+ ],
+ "shiftjis_csv": [
+ {
+ "DisplayName": "名無しの権兵衛",
+ "PrimaryEmail": "名無しの権兵衛@host.invalid"
+ }
+ ],
+ "quote_csv": [
+ {
+ "DisplayName": "Acer America",
+ "_vCard": [
+ "VERSION:4.0",
+ "FN:Acer America",
+ "ORG:Acer America;",
+ "TEL;TYPE=work;VALUE=TEXT:(800) 000-0000",
+ "UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ ]
+ }
+ ],
+ "vcard_import": [
+ {
+ "DisplayName": "John Doe",
+ "FirstName": "John",
+ "LastName": "Doe",
+ "PrimaryEmail": "john.doe@genericemail.invalid"
+ },
+ {
+ "DisplayName": "Jane Doe",
+ "FirstName": "Jane",
+ "LastName": "Doe",
+ "PrimaryEmail": "jane.doe@genericemail.invalid"
+ }
+ ],
+ "dos_vcard_import": [
+ {
+ "DisplayName": "Name Surname",
+ "FirstName": "Name",
+ "LastName": "Surname",
+ "PrimaryEmail": "example@gmail.com"
+ }
+ ],
+ "csv_import": [
+ {
+ "DisplayName": "John Doe",
+ "FirstName": "John",
+ "LastName": "Doe",
+ "PrimaryEmail": "john@doe.invalid"
+ },
+ {
+ "DisplayName": "Jane Doe",
+ "FirstName": "Jane",
+ "LastName": "Doe",
+ "PrimaryEmail": "jane@doe.invalid"
+ }
+ ],
+ "becky_addressbook": [
+ {
+ "DisplayName": "The first man",
+ "PrimaryEmail": "first@host.invalid",
+ "_vCard": [
+ "VERSION:3.0",
+ "FN:The first man",
+ "ORG:Organization;Post;",
+ "X-BECKY-IMAGE:0",
+ "N:The nick name of the first man",
+ "TEL;TYPE=HOME:11-1111-1111",
+ "TEL;TYPE=WORK:22-2222-2222",
+ "TEL;TYPE=CELL:333-3333-3333",
+ "EMAIL;TYPE=INTERNET:first@host.invalid",
+ "NOTE:This is a note.",
+ "UID:4E4D17E8.0043655C"
+ ]
+ },
+ {
+ "DisplayName": "The second man",
+ "PrimaryEmail": "second@host.invalid",
+ "_vCard": [
+ "VERSION:3.0",
+ "FN:The second man",
+ "ORG:Organization;post;",
+ "X-BECKY-IMAGE:0",
+ "N:The nick name of the second man",
+ "TEL;TYPE=HOME:44-4444-4444",
+ "TEL;TYPE=WORK:55-5555-5555",
+ "TEL;TYPE=CELL:666-6666-6666",
+ "EMAIL;TYPE=INTERNET:second@host.invalid",
+ "NOTE:This is a note.",
+ "UID:4EBBF6FE.00AC632B"
+ ]
+ },
+ {
+ "DisplayName": "The third man",
+ "PrimaryEmail": "third@host.invalid",
+ "_vCard": [
+ "VERSION:3.0",
+ "FN:The third man",
+ "ORG:Organization;post;",
+ "X-BECKY-IMAGE:0",
+ "N:The third man",
+ "TEL;TYPE=HOME:77-7777-7777",
+ "TEL;TYPE=WORK:88-8888-8888",
+ "TEL;TYPE=CELL:999-9999-9999",
+ "EMAIL;TYPE=INTERNET:third@host.invalid",
+ "NOTE:This is a note.",
+ "UID:4E57AB44.0001D53E"
+ ]
+ }
+ ]
+}
diff --git a/comm/mailnews/import/test/unit/resources/basic_addressbook.csv b/comm/mailnews/import/test/unit/resources/basic_addressbook.csv
new file mode 100644
index 0000000000..5d97d36f17
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/basic_addressbook.csv
@@ -0,0 +1,2 @@
+First Name,Last Name,Display Name,Nickname,Primary Email,Secondary Email,Work Phone,Home Phone,Fax Number,Pager Number,Mobile Number,Home Address,Home Address 2,Home City,Home State,Home ZipCode,Home Country,Work Address,Work Address 2,Work City,Work State,Work ZipCode,Work Country,Job Title,Department,Organization,Web Page 1,Web Page 2,Birth Year,Birth Month,Birth Day,Custom 1,Custom 2,Custom 3,Custom 4,Notes,Screen Name,
+John,Doe,John Doe,,johndoe@host.invalid,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
diff --git a/comm/mailnews/import/test/unit/resources/basic_csv_addressbook.csv b/comm/mailnews/import/test/unit/resources/basic_csv_addressbook.csv
new file mode 100644
index 0000000000..d4ecd1a308
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/basic_csv_addressbook.csv
@@ -0,0 +1,3 @@
+First Name,Last Name,Display Name,Nickname,Primary Email,Secondary Email,Work Phone,Home Phone,Fax Number,Pager Number,Mobile Number,Home Address,Home Address 2,Home City,Home State,Home ZipCode,Home Country,Work Address,Work Address 2,Work City,Work State,Work ZipCode,Work Country,Job Title,Department,Organization,Web Page 1,Web Page 2,Birth Year,Birth Month,Birth Day,Custom 1,Custom 2,Custom 3,Custom 4,Notes,Screen Name
+John,Doe,John Doe,,john@doe.invalid,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+Jane,Doe,Jane Doe,,jane@doe.invalid,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
diff --git a/comm/mailnews/import/test/unit/resources/basic_ldif_addressbook.ldif b/comm/mailnews/import/test/unit/resources/basic_ldif_addressbook.ldif
new file mode 100644
index 0000000000..cf8ebab355
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/basic_ldif_addressbook.ldif
@@ -0,0 +1,45 @@
+dn: cn=Display Name,mail=primaryemail@host.invalid
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: mozillaAbPersonAlpha
+givenName: First
+sn: Last
+cn: Display Name
+mozillaNickname: Nickname
+mail: primaryemail@host.invalid
+mozillaSecondEmail: secondemail@host.invalid
+nsAIMid: screenname
+mozillaUseHtmlMail: true
+modifytimestamp: 1213818826
+telephoneNumber: 123-456-7890
+homePhone: 234-567-8901
+fax: 345-678-9012
+pager: 456-789-0123
+mobile: 567-890-1234
+mozillaHomeStreet: Home Address Line 1
+mozillaHomeStreet2: Home Address Line 2
+mozillaHomeLocalityName: Home City
+mozillaHomeState: Home State
+mozillaHomePostalCode: Home Zip
+mozillaHomeCountryName: Home Country
+street: Work Address Line 1
+mozillaWorkStreet2: Work Address Line 2
+l: Work City
+st: Work State
+postalCode: Work Zip
+c: Work Country
+title: Job Title
+ou: Department
+o: Organization Name
+mozillaWorkUrl: http://127.0.0.1
+mozillaHomeUrl: http://localhost
+birthyear: 1900
+birthmonth: 1
+birthday: 2
+mozillaCustom1: Custom Field 1
+mozillaCustom2: Custom Field 2
+mozillaCustom3: Custom Field 3
+mozillaCustom4: Custom Field 4
+description:: Tm90ZXMgbGluZSAxCk5vdGVzIGxpbmUgMgpOb3RlcyBsaW5lIDMKTm90ZXMgbGluZSA0
diff --git a/comm/mailnews/import/test/unit/resources/basic_vcard_addressbook.vcf b/comm/mailnews/import/test/unit/resources/basic_vcard_addressbook.vcf
new file mode 100644
index 0000000000..7232bd6f23
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/basic_vcard_addressbook.vcf
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+VERSION:2.1
+FN:John Doe
+N:Doe;John;;;
+EMAIL;TYPE=INTERNET:john.doe@genericemail.invalid
+END:VCARD
+BEGIN:VCARD
+VERSION:2.1
+FN:Jane Doe
+N:Doe;Jane;;;
+EMAIL;TYPE=INTERNET:jane.doe@genericemail.invalid
+END:VCARD
diff --git a/comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186e.bab b/comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186e.bab
new file mode 100644
index 0000000000..2b7e4de7e9
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186e.bab
@@ -0,0 +1,26 @@
+BEGIN:VCARD
+VERSION:3.0
+UID:4E4D17E8.0043655C
+FN:The first man
+ORG:Organization;Post;
+X-BECKY-IMAGE:0
+N:The nick name of the first man
+TEL;TYPE=HOME:11-1111-1111
+TEL;TYPE=WORK:22-2222-2222
+TEL;TYPE=CELL:333-3333-3333
+EMAIL;TYPE=INTERNET;PREF:first@host.invalid
+NOTE;ENCODING=QUOTED-PRINTABLE:This is a note.
+END:VCARD
+BEGIN:VCARD
+VERSION:3.0
+UID:4EBBF6FE.00AC632B
+FN:The second man
+ORG:Organization;post;
+X-BECKY-IMAGE:0
+N:The nick name of the second man
+TEL;TYPE=HOME:44-4444-4444
+TEL;TYPE=WORK:55-5555-5555
+TEL;TYPE=CELL:666-6666-6666
+EMAIL;TYPE=INTERNET;PREF:second@host.invalid
+NOTE;ENCODING=QUOTED-PRINTABLE:This is a note.
+END:VCARD
diff --git a/comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186f.bab b/comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186f.bab
new file mode 100644
index 0000000000..13df134ef8
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/becky/addressbooks/4e4d186f.bab
@@ -0,0 +1,13 @@
+BEGIN:VCARD
+VERSION:3.0
+UID:4E57AB44.0001D53E
+FN:The third man
+ORG:Organization;post;
+X-BECKY-IMAGE:0
+N:The third man
+TEL;TYPE=HOME:77-7777-7777
+TEL;TYPE=WORK:88-8888-8888
+TEL;TYPE=CELL:999-9999-9999
+EMAIL;TYPE=INTERNET;PREF:third@host.invalid
+NOTE;ENCODING=QUOTED-PRINTABLE:This is a note.
+END:VCARD
diff --git a/comm/mailnews/import/test/unit/resources/becky/addressbooks/do_not_import_this.nobab b/comm/mailnews/import/test/unit/resources/becky/addressbooks/do_not_import_this.nobab
new file mode 100644
index 0000000000..3a49cbfbf7
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/becky/addressbooks/do_not_import_this.nobab
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+UID:4E4D17E8.0043655C
+FN:Nobody
+ORG:Organization;post;
+X-BECKY-IMAGE:0
+N:Nobody
+TEL;HOME:00-0000-0000
+TEL;WORK:11-1111-1111
+TEL;CELL:090-0000-0000
+EMAIL;PREF:nobody@example.com
+NOTE;ENCODING=QUOTED-PRINTABLE:This is a note.
+END:VCARD
diff --git a/comm/mailnews/import/test/unit/resources/becky/filters/IFilter.def b/comm/mailnews/import/test/unit/resources/becky/filters/IFilter.def
new file mode 100644
index 0000000000..0777e163c1
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/becky/filters/IFilter.def
@@ -0,0 +1,23 @@
+Version=1
+AutoSorting=1
+OnlyRead=0
+OnlyOneFolder=1
+:Begin ""
+!M:11111111.mb\!!!!Inbox\Sub11_OR_12\
+@0:Subject:Subject11 O I
+@0:Subject:Subject12 O I
+$O:Sort=1
+:End ""
+:Begin ""
+!M:11111111.mb\!!!!Inbox\From11_OR_12\
+@0:From:From11@example.com O I
+@0:From:From12@example.com O I
+$O:Sort=1
+:End ""
+:Begin ""
+!M:11111111.mb\!!!!Inbox\Sub12+From11\
+@0:Subject:Subject12 O I
+@1:From:From11@example.com O I
+$O:Sort=1
+$X:disabled
+:End ""
diff --git a/comm/mailnews/import/test/unit/resources/becky/filters/OFilter.def b/comm/mailnews/import/test/unit/resources/becky/filters/OFilter.def
new file mode 100644
index 0000000000..bf7d184ff5
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/becky/filters/OFilter.def
@@ -0,0 +1,22 @@
+Version=1
+AutoSorting=1
+OnlyRead=0
+OnlyOneFolder=1
+:Begin ""
+!M:11111111.mb\!!!!Outbox\!!!Sent\Sub21_OR_22\
+@0:Subject:Subject21 O IT
+@0:Subject:Subject22 O IT
+$O:Sort=1
+:End ""
+:Begin ""
+!M:11111111.mb\!!!!Outbox\!!!Sent\To21_OR_22\
+@0:To:To21@example.com O I
+@0:To:To22@example.com O I
+$O:Sort=1
+:End ""
+:Begin ""
+!M:11111111.mb\!!!!Outbox\!!!Sent\To21\
+@0:To:To21@example.com O I
+$O:Sort=1
+$X:disabled
+:End ""
diff --git a/comm/mailnews/import/test/unit/resources/bug_263304.ldif b/comm/mailnews/import/test/unit/resources/bug_263304.ldif
new file mode 100644
index 0000000000..3e4e34ee0f
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/bug_263304.ldif
@@ -0,0 +1,7 @@
+dn: cn=Display Name,mail=primaryemail@host.invalid
+objectclass: top
+objectclass: person
+objectclass: inetOrgPerson
+cn: Display Name
+mail: primaryemail@host.invalid
+labeledURI: http://127.0.0.1 label
diff --git a/comm/mailnews/import/test/unit/resources/csv_no_header.csv b/comm/mailnews/import/test/unit/resources/csv_no_header.csv
new file mode 100644
index 0000000000..f017ec3f7d
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/csv_no_header.csv
@@ -0,0 +1,2 @@
+John Doe,John,Doe,john@doe.invalid
+Jane Doe,Jane,Doe,jane@doe.invalid
diff --git a/comm/mailnews/import/test/unit/resources/csv_semicolon.csv b/comm/mailnews/import/test/unit/resources/csv_semicolon.csv
new file mode 100644
index 0000000000..6323d439ee
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/csv_semicolon.csv
@@ -0,0 +1,3 @@
+Display Name;First Name;Last Name;Primary Email
+John Doe;John;Doe;john@doe.invalid
+Jane Doe;Jane;Doe;jane@doe.invalid
diff --git a/comm/mailnews/import/test/unit/resources/dos_vcard_addressbook.vcf b/comm/mailnews/import/test/unit/resources/dos_vcard_addressbook.vcf
new file mode 100644
index 0000000000..722bebc137
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/dos_vcard_addressbook.vcf
@@ -0,0 +1,6 @@
+BEGIN:VCARD
+VERSION:3.0
+N:Surname;Name;;;
+FN:Name Surname
+EMAIL;type=INTERNET;type=HOME:example@gmail.com
+END:VCARD
diff --git a/comm/mailnews/import/test/unit/resources/emptylines_vcard_addressbook.vcf b/comm/mailnews/import/test/unit/resources/emptylines_vcard_addressbook.vcf
new file mode 100644
index 0000000000..2f67c61dfe
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/emptylines_vcard_addressbook.vcf
@@ -0,0 +1,18 @@
+
+
+BEGIN:VCARD
+VERSION:2.1
+FN:John Doe
+N:Doe;John;;;
+EMAIL;TYPE=INTERNET:john.doe@genericemail.invalid
+END:VCARD
+
+
+BEGIN:VCARD
+VERSION:2.1
+FN:Jane Doe
+N:Doe;Jane;;;
+EMAIL;TYPE=INTERNET:jane.doe@genericemail.invalid
+END:VCARD
+
+
diff --git a/comm/mailnews/import/test/unit/resources/import_helper.js b/comm/mailnews/import/test/unit/resources/import_helper.js
new file mode 100644
index 0000000000..e689547377
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/import_helper.js
@@ -0,0 +1,665 @@
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+// used by checkProgress to periodically check the progress of the import
+var gGenericImportHelper;
+/**
+ * GenericImportHelper
+ * The parent class of AbImportHelper, MailImportHelper, SettingsImportHelper
+ * and FiltersImportHelper.
+ *
+ * @param aModuleType The type of import module. Should be addressbook or mail.
+ * @param aModuleSearchString
+ * The string to search the module names for, such as
+ * "Text file" to find the import module for comma-separated
+ * value, LDIF, and tab-delimited files.
+ * @param aFile An instance of nsIFile to import.
+ *
+ * @class
+ * @class
+ */
+function GenericImportHelper(aModuleType, aModuleSearchString, aFile) {
+ gGenericImportHelper = null;
+ if (!["addressbook", "mail", "settings", "filters"].includes(aModuleType)) {
+ do_throw("Unexpected type passed to the GenericImportHelper constructor");
+ }
+ this.mModuleType = aModuleType;
+ this.mModuleSearchString = aModuleSearchString;
+ this.mInterface = this._findInterface();
+ Assert.ok(this.mInterface !== null);
+
+ this.mFile = aFile; // checked in the beginImport method
+}
+
+GenericImportHelper.prototype = {
+ interfaceType: Ci.nsIImportGeneric,
+ /**
+ * GenericImportHelper.beginImport
+ * Imports the given address book export or mail data and invoke
+ * checkProgress of child class to check the data,
+ */
+ beginImport() {
+ Assert.ok(this.mFile instanceof Ci.nsIFile && this.mFile.exists());
+
+ if (this.mModuleType == "addressbook") {
+ this.mInterface.SetData("addressLocation", this.mFile);
+ } else if (this.mModuleType == "mail") {
+ this.mInterface.SetData("mailLocation", this.mFile);
+ }
+
+ Assert.ok(this.mInterface.WantsProgress());
+ const error = Cc["@mozilla.org/supports-string;1"].createInstance(
+ Ci.nsISupportsString
+ );
+ Assert.ok(this.mInterface.BeginImport(null, error));
+ Assert.equal(error.data, "");
+ do_test_pending();
+ this.checkProgress();
+ },
+ /**
+ * GenericImportHelper.getInterface
+ *
+ * @returns An nsIImportGeneric import interface.
+ */
+ getInterface() {
+ return this.mInterface;
+ },
+
+ _findInterface() {
+ var importService = Cc["@mozilla.org/import/import-service;1"].getService(
+ Ci.nsIImportService
+ );
+ var count = importService.GetModuleCount(this.mModuleType);
+
+ // Iterate through each import module until the one being searched for is
+ // found and then return the ImportInterface of that module
+ for (var i = 0; i < count; i++) {
+ // Check if the current module fits the search string gets the interface
+ if (
+ importService
+ .GetModuleName(this.mModuleType, i)
+ .includes(this.mModuleSearchString)
+ ) {
+ return importService
+ .GetModule(this.mModuleType, i)
+ .GetImportInterface(this.mModuleType)
+ .QueryInterface(this.interfaceType);
+ }
+ }
+ return null; // it wasn't found
+ },
+ /**
+ * GenericImportHelper.checkProgress
+ * Checks the progress of an import every 200 milliseconds until it is
+ * complete. Checks the test results if there is an original address book,
+ * otherwise evaluates the optional command, or calls do_test_finished().
+ */
+ checkProgress() {
+ Assert.ok(
+ this.mInterface && this.mInterface instanceof Ci.nsIImportGeneric
+ );
+ Assert.ok(this.mInterface.ContinueImport());
+ // if the import isn't done, check again in 200 milliseconds.
+ if (this.mInterface.GetProgress() != 100) {
+ // use the helper object to check the progress of the import after 200 ms
+ gGenericImportHelper = this;
+ do_timeout(200, function () {
+ gGenericImportHelper.checkProgress();
+ });
+ } else {
+ // if it is done, check the results or finish the test.
+ this.checkResults();
+ do_test_finished();
+ }
+ },
+
+ /**
+ * GenericImportHelper.checkResults
+ * Checks the results of the import.
+ * Child class should implement this method.
+ */
+ checkResults() {},
+};
+
+/**
+ * AbImportHelper
+ * A helper for Address Book imports. To use, supply at least the file and type.
+ * If you would like the results checked, add a new array in the addressbook
+ * JSON file in the resources folder and supply aAbName and aJsonName.
+ * See AB_README for more information.
+ *
+ * @param aFile An instance of nsIAbFile to import.
+ * @param aModuleSearchString
+ * The string to search the module names for, such as
+ * "Text file" to find the import module for comma-separated
+ * value, LDIF, and tab-delimited files.
+ * Optional parameters: Include if you would like the import checked.
+ * @param aAbName The name the address book will have (the filename without
+ * the extension).
+ * @param aJsonName The name of the array in addressbook.json with the cards
+ * to compare with the imported cards.
+ * @class
+ * @class
+ */
+function AbImportHelper(aFile, aModuleSearchString, aAbName, aJsonName) {
+ GenericImportHelper.call(this, "addressbook", aModuleSearchString, aFile);
+
+ this.mAbName = aAbName;
+ /* Attribute notes: The attributes listed in the declaration below are
+ * supported by all three text export/import types.
+ * The following are not supported: anniversaryYear, anniversaryMonth,
+ * anniversaryDay, popularityIndex, isMailList, mailListURI, lastModifiedDate.
+ */
+ var supportedAttributes = [
+ "FirstName",
+ "LastName",
+ "DisplayName",
+ "NickName",
+ "PrimaryEmail",
+ "SecondEmail",
+ "WorkPhone",
+ "HomePhone",
+ "FaxNumber",
+ "PagerNumber",
+ "CellularNumber",
+ "HomeAddress",
+ "HomeAddress2",
+ "HomeCity",
+ "HomeState",
+ "HomeZipCode",
+ "HomeCountry",
+ "WorkAddress",
+ "WorkAddress2",
+ "WorkCity",
+ "WorkState",
+ "WorkZipCode",
+ "WorkCountry",
+ "JobTitle",
+ "Department",
+ "Company",
+ "BirthYear",
+ "BirthMonth",
+ "BirthDay",
+ "WebPage1",
+ "WebPage2",
+ "Custom1",
+ "Custom2",
+ "Custom3",
+ "Custom4",
+ "Notes",
+ "_AimScreenName",
+ "_vCard",
+ ];
+
+ // get the extra attributes supported for the given type of import
+ if (this.mFile.leafName.toLowerCase().endsWith(".ldif")) {
+ this.mSupportedAttributes = supportedAttributes;
+ } else if (this.mFile.leafName.toLowerCase().endsWith(".csv")) {
+ this.mSupportedAttributes = supportedAttributes;
+ this.setFieldMap(this.getDefaultFieldMap(true));
+ } else if (this.mFile.leafName.toLowerCase().endsWith(".vcf")) {
+ this.mSupportedAttributes = supportedAttributes;
+ }
+
+ // get the "cards" from the JSON file, if necessary
+ if (aJsonName) {
+ this.mJsonCards = this.getJsonCards(aJsonName);
+ }
+}
+
+AbImportHelper.prototype = {
+ __proto__: GenericImportHelper.prototype,
+ /**
+ * AbImportHelper.getDefaultFieldMap
+ * Returns the default field map.
+ *
+ * @param aSkipFirstRecord True if the first record of the text file should
+ * be skipped.
+ * @returns A default field map.
+ */
+ getDefaultFieldMap(aSkipFirstRecord) {
+ var importService = Cc["@mozilla.org/import/import-service;1"].getService(
+ Ci.nsIImportService
+ );
+ var fieldMap = importService.CreateNewFieldMap();
+
+ fieldMap.DefaultFieldMap(fieldMap.numMozFields);
+ this.mInterface
+ .GetData("addressInterface")
+ .QueryInterface(Ci.nsIImportAddressBooks)
+ .InitFieldMap(fieldMap);
+ fieldMap.skipFirstRecord = aSkipFirstRecord;
+
+ return fieldMap;
+ },
+
+ /**
+ * AbImportHelper.setFieldMap
+ * Set the field map.
+ *
+ * @param aFieldMap The field map used for address book import.
+ */
+ setFieldMap(aFieldMap) {
+ this.mInterface.SetData("fieldMap", aFieldMap);
+ },
+
+ /**
+ * AbImportHelper.setAddressLocation
+ * Set the the location of the address book.
+ *
+ * @param aLocation The location of the source address book.
+ */
+ setAddressBookLocation(aLocation) {
+ this.mInterface.SetData("addressLocation", aLocation);
+ },
+
+ /**
+ * AbImportHelper.setAddressDestination
+ * Set the the destination of the address book.
+ *
+ * @param aDestination URI of destination address book or null if
+ * new address books will be created.
+ */
+ setAddressDestination(aDestination) {
+ this.mInterface.SetData("addressDestination", aDestination);
+ },
+
+ /**
+ * AbImportHelper.checkResults
+ * Checks the results of the import.
+ * Ensures the an address book was created, then compares the supported
+ * attributes of each card with the card(s) in the JSON array.
+ * Calls do_test_finished() when done
+ */
+ checkResults() {
+ if (!this.mJsonCards) {
+ do_throw("The address book must be setup before checking results");
+ }
+ // When do_test_pending() was called and there is an error the test hangs.
+ // This try/catch block will catch any errors and call do_throw() with the
+ // error to throw the error and avoid the hang.
+ try {
+ // make sure an address book was created
+ var newAb = this.getAbByName(this.mAbName);
+ Assert.ok(newAb !== null);
+ Assert.ok(newAb.QueryInterface(Ci.nsIAbDirectory));
+ // get the imported card(s) and check each one
+ var count = 0;
+ for (let importedCard of newAb.childCards) {
+ this.compareCards(this.mJsonCards[count], importedCard);
+ count++;
+ }
+ // make sure there are the same number of cards in the address book and
+ // the JSON array
+ Assert.equal(count, this.mJsonCards.length);
+ do_test_finished();
+ } catch (e) {
+ do_throw(e);
+ }
+ },
+ /**
+ * AbImportHelper.getAbByName
+ * Returns the Address Book (if any) with the given name.
+ *
+ * @param aName The name of the Address Book to find.
+ * @returns An nsIAbDirectory, if found.
+ * null if the requested Address Book could not be found.
+ */
+ getAbByName(aName) {
+ Assert.ok(aName && aName.length > 0);
+
+ for (let data of MailServices.ab.directories) {
+ if (data.dirName == aName) {
+ return data;
+ }
+ }
+ return null;
+ },
+ /**
+ * AbImportHelper.compareCards
+ * Compares a JSON "card" with an imported card and throws an error if the
+ * values of a supported attribute are different.
+ *
+ * @param aJsonCard The object decoded from addressbook.json.
+ * @param aCard The imported card to compare with.
+ */
+ compareCards(aJsonCard, aCard) {
+ for (let [key, value] of Object.entries(aJsonCard)) {
+ if (!this.mSupportedAttributes.includes(key)) {
+ continue;
+ }
+ if (key == "_vCard") {
+ equal(
+ aCard
+ .getProperty(key, "")
+ .replace(
+ /UID:[a-f0-9-]{36}/i,
+ "UID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
+ ),
+ `BEGIN:VCARD\r\n${value.join("\r\n")}\r\nEND:VCARD\r\n`,
+ "_vCard should be correct"
+ );
+ } else {
+ equal(aCard.getProperty(key, ""), value, `${key} should be correct`);
+ }
+ }
+ },
+ /**
+ * AbImportHelper.getJsonCards
+ * Gets an array of "cards" from the JSON file addressbook.json located in the
+ * mailnews/import/test/resources folder. The array should contain objects
+ * with the expected properties and values of the cards in the imported
+ * address book.
+ * See addressbook.json for an example and AB_README for more details.
+ *
+ * @param aName The name of the array in addressbook.json.
+ * @returns An array of "cards".
+ */
+ getJsonCards(aName) {
+ if (!aName) {
+ do_throw("Error - getJSONAb requires an address book name");
+ }
+ var file = do_get_file("resources/addressbook.json");
+ if (!file || !file.exists() || !file.isFile()) {
+ do_throw("Unable to get JSON file");
+ }
+
+ var fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
+ Ci.nsIFileInputStream
+ );
+ fis.init(file, 0x01, 0o444, 0);
+ var istream = Cc[
+ "@mozilla.org/intl/converter-input-stream;1"
+ ].createInstance(Ci.nsIConverterInputStream);
+ var replacementChar =
+ Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
+ istream.init(fis, "UTF-8", 1024, replacementChar);
+ var json = "";
+ var str = {};
+ // get the entire file into the json string
+ while (istream.readString(4096, str) != 0) {
+ json += str.value;
+ }
+ // close the input streams
+ istream.close();
+ fis.close();
+ // decode the JSON and get the array of cards
+ var arr = JSON.parse(json)[aName];
+ Assert.ok(arr && arr.length > 0);
+ return arr;
+ },
+
+ setSupportedAttributes(attributes) {
+ this.mSupportedAttributes = attributes;
+ },
+};
+
+/**
+ * MailImportHelper
+ * A helper for mail imports.
+ *
+ * @param aFile An instance of nsIFile to import.
+ * @param aModuleSearchString
+ * The string to search the module names for, such as
+ * "Outlook Express", etc.
+ * @param aExpected An instance of nsIFile to compare with the imported
+ * folders.
+ *
+ * @class
+ * @class
+ */
+function MailImportHelper(aFile, aModuleSearchString, aExpected) {
+ GenericImportHelper.call(this, "mail", aModuleSearchString, aFile);
+ this.mExpected = aExpected;
+}
+
+MailImportHelper.prototype = {
+ __proto__: GenericImportHelper.prototype,
+ interfaceType: Ci.nsIImportGeneric,
+ _checkEqualFolder(expectedFolder, actualFolder) {
+ Assert.equal(expectedFolder.leafName, actualFolder.name);
+
+ let expectedSubFolders = [];
+ for (let entry of expectedFolder.directoryEntries) {
+ if (entry.isDirectory()) {
+ expectedSubFolders.push(entry);
+ }
+ }
+ let actualSubFolders = actualFolder.subFolders;
+ Assert.equal(expectedSubFolders.length, actualSubFolders.length);
+ for (let i = 0; i < expectedSubFolders.length; i++) {
+ this._checkEqualFolder(expectedSubFolders[i], actualSubFolders[i]);
+ }
+ },
+
+ checkResults() {
+ let rootFolder = MailServices.accounts.localFoldersServer.rootFolder;
+ Assert.ok(rootFolder.containsChildNamed(this.mFile.leafName));
+ let importedFolder = rootFolder.getChildNamed(this.mFile.leafName);
+ Assert.notEqual(importedFolder, null);
+
+ this._checkEqualFolder(this.mExpected, importedFolder);
+ },
+};
+
+/**
+ * SettingsImportHelper
+ * A helper for settings imports.
+ *
+ * @param aFile An instance of nsIFile to import, can be null.
+ * @param aModuleSearchString
+ * The string to search the module names for, such as
+ * "Outlook Express", etc.
+ * @param aExpected An array of object which has incomingServer, identity
+ * and smtpSever to compare with imported nsIMsgAccount.
+ *
+ * @class
+ * @class
+ */
+function SettingsImportHelper(aFile, aModuleSearchString, aExpected) {
+ GenericImportHelper.call(this, "settings", aModuleSearchString, aFile);
+ this.mExpected = aExpected;
+}
+
+SettingsImportHelper.prototype = {
+ __proto__: GenericImportHelper.prototype,
+ interfaceType: Ci.nsIImportSettings,
+ /**
+ * SettingsImportHelper.beginImport
+ * Imports settings from a specific file or auto-located if the file is null,
+ * and compare the import results with the expected array.
+ */
+ beginImport() {
+ this._ensureNoAccounts();
+ if (this.mFile) {
+ this.mInterface.SetLocation(this.mFile);
+ } else {
+ Assert.equal(true, this.mInterface.AutoLocate({}, {}));
+ }
+ Assert.equal(true, this.mInterface.Import({}));
+ this.checkResults();
+ },
+
+ _ensureNoAccounts() {
+ for (let account of MailServices.accounts.accounts) {
+ MailServices.accounts.removeAccount(account);
+ }
+ },
+
+ _checkSmtpServer(expected, actual) {
+ Assert.equal(expected.port, actual.port);
+ Assert.equal(expected.username, actual.username);
+ Assert.equal(expected.authMethod, actual.authMethod);
+ Assert.equal(expected.socketType, actual.socketType);
+ },
+
+ _checkIdentity(expected, actual) {
+ Assert.equal(expected.fullName, actual.fullName);
+ Assert.equal(expected.email, actual.email);
+ Assert.equal(expected.replyTo, actual.replyTo);
+ Assert.equal(expected.organization, actual.organization);
+ },
+
+ _checkPop3IncomingServer(expected, actual) {
+ Assert.equal(expected.leaveMessagesOnServer, actual.leaveMessagesOnServer);
+ Assert.equal(
+ expected.deleteMailLeftOnServer,
+ actual.deleteMailLeftOnServer
+ );
+ Assert.equal(expected.deleteByAgeFromServer, actual.deleteByAgeFromServer);
+ Assert.equal(
+ expected.numDaysToLeaveOnServer,
+ actual.numDaysToLeaveOnServer
+ );
+ },
+
+ _checkIncomingServer(expected, actual) {
+ Assert.equal(expected.type, actual.type);
+ Assert.equal(expected.port, actual.port);
+ Assert.equal(expected.username, actual.username);
+ Assert.equal(expected.isSecure, actual.isSecure);
+ Assert.equal(expected.hostName, actual.hostName);
+ Assert.equal(expected.prettyName, actual.prettyName);
+ Assert.equal(expected.authMethod, actual.authMethod);
+ Assert.equal(expected.socketType, actual.socketType);
+ Assert.equal(expected.doBiff, actual.doBiff);
+ Assert.equal(expected.biffMinutes, actual.biffMinutes);
+
+ if (expected.type == "pop3") {
+ this._checkPop3IncomingServer(
+ expected,
+ actual.QueryInterface(Ci.nsIPop3IncomingServer)
+ );
+ }
+ },
+
+ _checkAccount(expected, actual) {
+ this._checkIncomingServer(expected.incomingServer, actual.incomingServer);
+
+ Assert.equal(1, actual.identities.length);
+ let actualIdentity = actual.identities[0];
+ this._checkIdentity(expected.identity, actualIdentity);
+
+ if (expected.incomingServer.type != "nntp") {
+ let actualSmtpServer = MailServices.smtp.getServerByKey(
+ actualIdentity.smtpServerKey
+ );
+ this._checkSmtpServer(expected.smtpServer, actualSmtpServer);
+ }
+ },
+
+ _isLocalMailAccount(account) {
+ return (
+ account.incomingServer.type == "none" &&
+ account.incomingServer.username == "nobody" &&
+ account.incomingServer.hostName == "Local Folders"
+ );
+ },
+
+ _findExpectedAccount(account) {
+ return this.mExpected.filter(function (expectedAccount) {
+ return (
+ expectedAccount.incomingServer.type == account.incomingServer.type &&
+ expectedAccount.incomingServer.username ==
+ account.incomingServer.username &&
+ expectedAccount.incomingServer.hostName ==
+ account.incomingServer.hostName
+ );
+ });
+ },
+
+ checkResults() {
+ for (let actualAccount of MailServices.accounts.accounts) {
+ if (this._isLocalMailAccount(actualAccount)) {
+ continue;
+ }
+ let expectedAccounts = this._findExpectedAccount(actualAccount);
+ Assert.notEqual(null, expectedAccounts);
+ Assert.equal(1, expectedAccounts.length);
+ this._checkAccount(expectedAccounts[0], actualAccount);
+ }
+ },
+};
+
+/**
+ * FiltersImportHelper
+ * A helper for filter imports.
+ *
+ * @param aFile An instance of nsIFile to import.
+ * @param aModuleSearchString
+ * The string to search the module names for, such as
+ * "Outlook Express", etc.
+ * @param aExpected The number of filters that should exist after import.
+ *
+ * @class
+ * @class
+ */
+function FiltersImportHelper(aFile, aModuleSearchString, aExpected) {
+ GenericImportHelper.call(this, "filters", aModuleSearchString, aFile);
+ this.mExpected = aExpected;
+}
+
+FiltersImportHelper.prototype = {
+ __proto__: GenericImportHelper.prototype,
+ interfaceType: Ci.nsIImportFilters,
+
+ /**
+ * FiltersImportHelper.beginImport
+ * Imports filters from a specific file/folder or auto-located if the file is null,
+ * and compare the import results with the expected array.
+ */
+ beginImport() {
+ if (this.mFile) {
+ this.mInterface.SetLocation(this.mFile);
+ } else {
+ Assert.equal(true, this.mInterface.AutoLocate({}, {}));
+ }
+ Assert.equal(true, this.mInterface.Import({}));
+ this.checkResults();
+ },
+
+ _loopOverFilters(aFilterList, aCondition) {
+ let result = 0;
+ for (let i = 0; i < aFilterList.filterCount; i++) {
+ let filter = aFilterList.getFilterAt(i);
+ if (aCondition(filter)) {
+ result++;
+ }
+ }
+ return result;
+ },
+
+ checkResults() {
+ let expected = this.mExpected;
+ let server = MailServices.accounts.localFoldersServer;
+ let filterList = server.getFilterList(null);
+ if ("count" in expected) {
+ Assert.equal(filterList.filterCount, expected.count);
+ }
+ if ("enabled" in expected) {
+ Assert.equal(
+ this._loopOverFilters(filterList, f => f.enabled),
+ expected.enabled
+ );
+ }
+ if ("incoming" in expected) {
+ Assert.equal(
+ this._loopOverFilters(
+ filterList,
+ f => f.filterType & Ci.nsMsgFilterType.InboxRule
+ ),
+ expected.incoming
+ );
+ }
+ if ("outgoing" in expected) {
+ Assert.equal(
+ this._loopOverFilters(
+ filterList,
+ f => f.filterType & Ci.nsMsgFilterType.PostOutgoing
+ ),
+ expected.outgoing
+ );
+ }
+ },
+};
diff --git a/comm/mailnews/import/test/unit/resources/mock_windows_reg_factory.js b/comm/mailnews/import/test/unit/resources/mock_windows_reg_factory.js
new file mode 100644
index 0000000000..19583d5007
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/mock_windows_reg_factory.js
@@ -0,0 +1,84 @@
+var { MockRegistrar } = ChromeUtils.importESModule(
+ "resource://testing-common/MockRegistrar.sys.mjs"
+);
+
+var gCid;
+
+function MockWindowsRegKey(registryData) {
+ this._registryData = registryData;
+}
+
+MockWindowsRegKey.prototype = {
+ QueryInterface: ChromeUtils.generateQI(["nsIWindowsRegKey"]),
+
+ open(aRootKey, aRelPath, aMode) {
+ if (!this._registryData[aRelPath]) {
+ throw Components.Exception("", Cr.NS_ERROR_FAILURE);
+ }
+ this._keyPath = aRelPath;
+ },
+
+ close() {},
+
+ openChild(aRelPath, aMode) {
+ if (
+ !this._registryData[this._keyPath] ||
+ !this._registryData[this._keyPath][aRelPath]
+ ) {
+ throw Components.Exception("", Cr.NS_ERROR_FAILURE);
+ }
+
+ let child = new MockWindowsRegKey({});
+ let newKeyPath = this._keyPath + "\\" + aRelPath;
+ child._keyPath = newKeyPath;
+ child._registryData[newKeyPath] =
+ this._registryData[this._keyPath][aRelPath];
+ return child;
+ },
+
+ get childCount() {
+ return Object.keys(this._registryData[this._keyPath]).length;
+ },
+
+ getChildName(aIndex) {
+ let keys = Object.keys(this._registryData[this._keyPath]);
+ let keyAtIndex = keys[aIndex];
+ if (!keyAtIndex) {
+ throw Components.Exception("", Cr.NS_ERROR_FAILURE);
+ }
+
+ return keyAtIndex;
+ },
+
+ _readValue(aName) {
+ if (
+ !this._registryData[this._keyPath] ||
+ !this._registryData[this._keyPath][aName]
+ ) {
+ throw Components.Exception("", Cr.NS_ERROR_FAILURE);
+ }
+
+ return this._registryData[this._keyPath][aName];
+ },
+
+ readIntValue(aName) {
+ return this._readValue(aName);
+ },
+
+ readStringValue(aName) {
+ return this._readValue(aName);
+ },
+};
+
+/* exported setup_mock_registry, teardown_mock_registry */
+function setup_mock_registry(mockRegistry) {
+ gCid = MockRegistrar.register(
+ "@mozilla.org/windows-registry-key;1",
+ MockWindowsRegKey,
+ [mockRegistry]
+ );
+}
+
+function teardown_mock_registry() {
+ MockRegistrar.unregister(gCid);
+}
diff --git a/comm/mailnews/import/test/unit/resources/quote.csv b/comm/mailnews/import/test/unit/resources/quote.csv
new file mode 100644
index 0000000000..d508eac33c
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/quote.csv
@@ -0,0 +1,2 @@
+First Name,Last Name,Display Name,Nickname,Primary Email,Secondary Email,Screen Name,Work Phone,Home Phone,Fax Number,Pager Number,Mobile Number,Home Address,Home Address 2,Home City,Home State,Home ZipCode,Home Country,Work Address,Work Address 2,Work City,Work State,Work ZipCode,Work Country,Job Title,Department,Organization,Web Page 1,Web Page 2,Birth Year,Birth Month,Birth Day,Custom 1,Custom 2,Custom 3,Custom 4,Notes
+,,"Acer America",,,,,"(800) 000-0000","","","","","","","","","","","","","","","","",,,"Acer America",,,,,,,,,,
diff --git a/comm/mailnews/import/test/unit/resources/shiftjis_addressbook.csv b/comm/mailnews/import/test/unit/resources/shiftjis_addressbook.csv
new file mode 100644
index 0000000000..31467dd42f
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/shiftjis_addressbook.csv
@@ -0,0 +1,2 @@
+First Name,Last Name,Display Name,Nickname,Primary Email,Secondary Email,Work Phone,Home Phone,Fax Number,Pager Number,Mobile Number,Home Address,Home Address 2,Home City,Home State,Home ZipCode,Home Country,Work Address,Work Address 2,Work City,Work State,Work ZipCode,Work Country,Job Title,Department,Organization,Web Page 1,Web Page 2,Birth Year,Birth Month,Birth Day,Custom 1,Custom 2,Custom 3,Custom 4,Notes,Screen Name,
+q,,̌q,,̌q@host.invalid,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
diff --git a/comm/mailnews/import/test/unit/resources/tab_comma_mixed.csv b/comm/mailnews/import/test/unit/resources/tab_comma_mixed.csv
new file mode 100644
index 0000000000..804a330e22
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/tab_comma_mixed.csv
@@ -0,0 +1,4 @@
+1,1,1,1,1@host.invalid,,,,,,,,,,,,,,,,,,,,,
+2 2 2 2 2@host.invalid
+3 3 3 3 3@host.invalid
+4 4 4 4 4@host.invalid
diff --git a/comm/mailnews/import/test/unit/resources/utf16_addressbook.csv b/comm/mailnews/import/test/unit/resources/utf16_addressbook.csv
new file mode 100644
index 0000000000..e22a64b187
--- /dev/null
+++ b/comm/mailnews/import/test/unit/resources/utf16_addressbook.csv
Binary files differ