summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/import/test/unit/test_AddrBookFileImporter.js
blob: 2ba696d1ed49731888921d29eb96ce2f9ea1deb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

var { AddrBookFileImporter } = ChromeUtils.import(
  "resource:///modules/AddrBookFileImporter.jsm"
);

/**
 * Create a temporary address book, import a source file into it, then test the
 * cards are correct.
 *
 * @param {string} type - A source file type supported by AddrBookFileImporter.
 * @param {string} filePath - The path of a source file.
 * @param {string} refDataKey - The key of an object in addressbook.json.
 * @param {string[]} [csvFieldMap] - Map of CSV fields to address book fields.
 */
async function test_importAbFile(type, filePath, refDataKey, csvFieldMap) {
  // Create an address book and init the importer.
  let dirId = MailServices.ab.newAddressBook(
    `tmp-${type}`,
    "",
    Ci.nsIAbManager.JS_DIRECTORY_TYPE
  );
  let targetDir = MailServices.ab.getDirectoryFromId(dirId);
  let importer = new AddrBookFileImporter(type);

  // Start importing.
  let sourceFile = do_get_file(filePath);
  if (type == "csv") {
    let unmatched = await importer.parseCsvFile(sourceFile);
    if (unmatched.length) {
      importer.setCsvFields(csvFieldMap);
    }
  }
  await importer.startImport(sourceFile, targetDir);

  // Read in the reference data.
  let refFile = do_get_file("resources/addressbook.json");
  let refData = JSON.parse(await IOUtils.readUTF8(refFile.path))[refDataKey];

  // Compare with the reference data.
  for (let i = 0; i < refData.length; i++) {
    let card = targetDir.childCards[i];
    for (let [key, value] of Object.entries(refData[i])) {
      if (key == "LastModifiedDate") {
        continue;
      }
      if (key == "_vCard") {
        equal(
          card
            .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(card.getProperty(key, ""), value, `${key} should be correct`);
      }
    }
  }
}

/** Test importing .csv file works. */
add_task(async function test_importCsvFile() {
  // A comma separated file.
  await test_importAbFile(
    "csv",
    "resources/basic_csv_addressbook.csv",
    "csv_import"
  );

  // A semicolon separated file.
  await test_importAbFile("csv", "resources/csv_semicolon.csv", "csv_import");

  // A comma separated file without header row.
  Services.prefs.setBoolPref("mail.import.csv.skipfirstrow", false);
  await test_importAbFile("csv", "resources/csv_no_header.csv", "csv_import", [
    2, // DisplayName
    0, // FirstName
    1, // LastName
    4, // PrimaryEmail
  ]);
  Services.prefs.clearUserPref("mail.import.csv.skipfirstrow");

  // A comma separated file with some fields containing quotes.
  await test_importAbFile("csv", "resources/quote.csv", "quote_csv");

  // Non-UTF8 csv file.
  await test_importAbFile(
    "csv",
    "resources/shiftjis_addressbook.csv",
    "shiftjis_csv"
  );
  await test_importAbFile(
    "csv",
    "resources/utf16_addressbook.csv",
    "utf16_csv"
  );
});

/** Test importing .vcf file works. */
add_task(async function test_importVCardFile() {
  return test_importAbFile(
    "vcard",
    "resources/basic_vcard_addressbook.vcf",
    "vcard_import"
  );
});

/** Test importing .vcf file with \r\r\n as line breaks works. */
add_task(async function test_importDosVCardFile() {
  return test_importAbFile(
    "vcard",
    "resources/dos_vcard_addressbook.vcf",
    "dos_vcard_import"
  );
});

/** Test importing .ldif file works. */
add_task(async function test_importLdifFile() {
  return test_importAbFile(
    "ldif",
    "resources/basic_ldif_addressbook.ldif",
    "basic_addressbook"
  );
});