From 2af1fe8a7cebfeb166d2254144fc840ed9c4f04a Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Wed, 28 Aug 2019 12:32:06 +1200 Subject: [PATCH] Bug 1576525 - Use JS address book provider for the default address books in new profiles; r=mkmelin --- mail/base/content/msgHdrView.js | 6 +- mail/base/modules/MailMigrator.jsm | 28 ++++ mail/components/addrbook/content/abCommon.js | 20 ++- mail/components/addrbook/content/abTrees.js | 16 ++- .../addrbook/content/addressbook.js | 4 +- .../addrbook/content/menulist-addrbooks.js | 20 ++- .../extensions/parent/ext-addressBook.js | 7 +- .../test/xpcshell/test_ext_addressBook.js | 5 +- .../migration/src/nsProfileMigratorBase.cpp | 2 +- .../mozmill/addrbook/test-address-book.js | 8 +- .../addrbook/test-update-mailing-list.js | 6 +- .../mozmill/composition/test-send-button.js | 8 +- .../message-header/test-message-header.js | 5 +- .../multiple-identities/test-display-names.js | 2 +- .../quick-filter-bar/test-filter-logic.js | 5 +- .../test-address-book-helpers.js | 23 ++-- .../content/abAddressBookNameDialog.js | 10 +- mailnews/addrbook/jsaddrbook/AddrBookCard.jsm | 42 ++++-- .../addrbook/jsaddrbook/AddrBookDirectory.jsm | 124 ++++++++++------- .../addrbook/jsaddrbook/AddrBookFactory.jsm | 2 +- .../jsaddrbook/AddrBookMailingList.jsm | 30 ++++- mailnews/addrbook/public/nsIAbDirectory.idl | 10 +- .../addrbook/src/nsAbAddressCollector.cpp | 24 +++- mailnews/addrbook/src/nsAbAddressCollector.h | 3 +- .../addrbook/src/nsAddbookProtocolHandler.cpp | 16 +-- mailnews/addrbook/src/nsDirPrefs.cpp | 15 ++- .../addrbook/test/unit/data/cardForEmail.sql | 1 + mailnews/addrbook/test/unit/data/collect.sql | 1 + mailnews/addrbook/test/unit/head_addrbook.js | 48 ++++++- .../addrbook/test/unit/head_jsaddrbook.js | 71 +--------- .../addrbook/test/unit/test_jsaddrbook.js | 28 +++- .../addrbook/test/unit/test_nsAbManager2.js | 4 - mailnews/base/search/content/searchWidgets.js | 2 +- mailnews/base/src/nsMsgDBView.cpp | 6 +- .../base/test/unit/data/remoteContent.sql | 41 ++++++ .../base/test/unit/test_accountMigration.js | 5 +- .../base/test/unit/test_junkWhitelisting.js | 9 +- .../base/test/unit/test_searchAddressInAb.js | 9 +- .../compose/test/unit/data/listexpansion.sql | 126 ++++++++++++++++++ .../test/unit/test_expandMailingLists.js | 6 +- .../compose/test/unit/test_nsMsgCompose1.js | 12 +- .../compose/test/unit/test_nsMsgCompose3.js | 6 +- .../compose/test/unit/test_nsMsgCompose4.js | 12 +- mailnews/mailnews.js | 12 +- mailnews/test/data/abLists1.sql | 3 +- mailnews/test/data/abLists2.sql | 62 +++++++++ mailnews/test/data/tb2hexpopularity.sql | 1 + mailnews/test/resources/abSetup.js | 50 ++++++- 48 files changed, 666 insertions(+), 290 deletions(-) create mode 100644 mailnews/base/test/unit/data/remoteContent.sql create mode 100644 mailnews/compose/test/unit/data/listexpansion.sql create mode 100644 mailnews/test/data/abLists2.sql diff --git a/mail/base/content/msgHdrView.js b/mail/base/content/msgHdrView.js index 4b5a34ec8d..d88132a961 100644 --- a/mail/base/content/msgHdrView.js +++ b/mail/base/content/msgHdrView.js @@ -1655,7 +1655,11 @@ function AddContact(emailAddressNode) { // leaving something else there). emailAddressNode.setAttribute("updatingUI", true); - const kPersonalAddressbookURI = "moz-abmdbdirectory://abook.mab"; + let stillUsingMabFiles = + Services.prefs.getIntPref("ldap_2.servers.pab.dirType") == 2; + let kPersonalAddressbookURI = stillUsingMabFiles + ? "moz-abmdbdirectory://abook.mab" + : "jsaddrbook://abook.sqlite"; let addressBook = MailServices.ab.getDirectory(kPersonalAddressbookURI); let card = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance( diff --git a/mail/base/modules/MailMigrator.jsm b/mail/base/modules/MailMigrator.jsm index bbd627bf1d..50c3f0cf1b 100644 --- a/mail/base/modules/MailMigrator.jsm +++ b/mail/base/modules/MailMigrator.jsm @@ -417,11 +417,39 @@ var MailMigrator = { this.migrateToClearTypeFonts(); }, + /** + * Migrate address books away from Mork. In time this will do actual + * migration, but for now, just set the default pref back to what it was. + */ + _migrateAddressBooks() { + let pab = Services.dirsvc.get("ProfD", Ci.nsIFile); + pab.append("abook.mab"); + if (pab.exists()) { + let defaultBranch = Services.prefs.getDefaultBranch(""); + defaultBranch.setIntPref("ldap_2.servers.pab.dirType", 2); + defaultBranch.setStringPref("ldap_2.servers.pab.filename", "abook.mab"); + defaultBranch.setIntPref("ldap_2.servers.history.dirType", 2); + defaultBranch.setStringPref( + "ldap_2.servers.history.filename", + "history.mab" + ); + defaultBranch.setStringPref( + "mail.collect_addressbook", + "moz-abmdbdirectory://history.mab" + ); + defaultBranch.setStringPref( + "mail.server.default.whiteListAbURI", + "moz-abmdbdirectory://abook.mab" + ); + } + }, + /** * Perform any migration work that needs to occur once the user profile has * been loaded. */ migrateAtProfileStartup() { + this._migrateAddressBooks(); this._migrateUI(); }, }; diff --git a/mail/components/addrbook/content/abCommon.js b/mail/components/addrbook/content/abCommon.js index ea577f06f3..cc1630d9c9 100644 --- a/mail/components/addrbook/content/abCommon.js +++ b/mail/components/addrbook/content/abCommon.js @@ -39,8 +39,14 @@ const kMaxYear = 9999; const kMinYear = 1; var kAllDirectoryRoot = "moz-abdirectory://"; var kLdapUrlPrefix = "moz-abldapdirectory://"; -var kPersonalAddressbookURI = "moz-abmdbdirectory://abook.mab"; -var kCollectedAddressbookURI = "moz-abmdbdirectory://history.mab"; +var stillUsingMabFiles = + Services.prefs.getIntPref("ldap_2.servers.pab.dirType") == 2; +var kPersonalAddressbookURI = stillUsingMabFiles + ? "moz-abmdbdirectory://abook.mab" + : "jsaddrbook://abook.sqlite"; +var kCollectedAddressbookURI = stillUsingMabFiles + ? "moz-abmdbdirectory://history.mab" + : "jsaddrbook://history.sqlite"; // The default, generic contact image is displayed via CSS when the photoURI is // blank. var defaultPhotoURI = ""; @@ -861,14 +867,14 @@ function GetDirectoryFromURI(uri) { function GetParentDirectoryFromMailingListURI(abURI) { var abURIArr = abURI.split("/"); /* - turn turn "moz-abmdbdirectory://abook.mab/MailList6" - into ["moz-abmdbdirectory:","","abook.mab","MailList6"] - then, turn ["moz-abmdbdirectory:","","abook.mab","MailList6"] - into "moz-abmdbdirectory://abook.mab" + turn turn "jsaddrbook://abook.sqlite/MailList6" + into ["jsaddrbook:","","abook.sqlite","MailList6"] + then, turn ["jsaddrbook:","","abook.sqlite","MailList6"] + into "jsaddrbook://abook.sqlite" */ if ( abURIArr.length == 4 && - abURIArr[0] == "moz-abmdbdirectory:" && + ["jsaddrbook:", "moz-abmdbdirectory:"].includes(abURIArr[0]) && abURIArr[3] != "" ) { return abURIArr[0] + "/" + abURIArr[1] + "/" + abURIArr[2]; diff --git a/mail/components/addrbook/content/abTrees.js b/mail/components/addrbook/content/abTrees.js index 44766670a9..25b67d8711 100644 --- a/mail/components/addrbook/content/abTrees.js +++ b/mail/components/addrbook/content/abTrees.js @@ -16,8 +16,19 @@ var { MailServices } = ChromeUtils.import( ); var { IOUtils } = ChromeUtils.import("resource:///modules/IOUtils.js"); +const DIRTYPE_JS = 101; + // Tree Sort helper methods. -var AB_ORDER = ["aab", "pab", "mork", "ldap", "mapi+other", "anyab", "cab"]; +var AB_ORDER = [ + "aab", + "pab", + "mork", + "js", + "ldap", + "mapi+other", + "anyab", + "cab", +]; function getDirectoryValue(aDir, aKey) { if (aKey == "ab_type") { @@ -33,6 +44,9 @@ function getDirectoryValue(aDir, aKey) { if (aDir._directory instanceof Ci.nsIAbMDBDirectory) { return "mork"; } + if (aDir._directory.dirType == DIRTYPE_JS) { + return "js"; + } if (aDir._directory instanceof Ci.nsIAbLDAPDirectory) { return "ldap"; } diff --git a/mail/components/addrbook/content/addressbook.js b/mail/components/addrbook/content/addressbook.js index a6286ec749..d0909dad7e 100644 --- a/mail/components/addrbook/content/addressbook.js +++ b/mail/components/addrbook/content/addressbook.js @@ -409,8 +409,8 @@ function AbPrintAddressBookInternal(doPrintPreview, msgType) { statusFeedback = statusFeedback.QueryInterface(Ci.nsIMsgStatusFeedback); /* - turn "moz-abmdbdirectory://abook.mab" into - "addbook://moz-abmdbdirectory/abook.mab?action=print" + turn "jsaddrbook://abook.sqlite" into + "addbook://jsaddrbook/abook.sqlite?action=print" */ var abURIArr = uri.split("://"); diff --git a/mail/components/addrbook/content/menulist-addrbooks.js b/mail/components/addrbook/content/menulist-addrbooks.js index 9c7193feb5..482496f131 100644 --- a/mail/components/addrbook/content/menulist-addrbooks.js +++ b/mail/components/addrbook/content/menulist-addrbooks.js @@ -278,22 +278,30 @@ if (!customElements.get("menulist")) { } // Personal at the top. - const kPersonalAddressbookURI = "moz-abmdbdirectory://abook.mab"; - if (a.URI == kPersonalAddressbookURI) { + // Having two possible options here seems illogical, but there can be + // only one of them. Once migration happens we can remove this oddity. + const kPersonalAddressbookURIs = [ + "jsaddrbook://abook.sqlite", + "moz-abmdbdirectory://abook.mab", + ]; + if (kPersonalAddressbookURIs.includes(a.URI)) { return -1; } - if (b.URI == kPersonalAddressbookURI) { + if (kPersonalAddressbookURIs.includes(b.URI)) { return 1; } // Collected at the bottom. - const kCollectedAddressbookURI = "moz-abmdbdirectory://history.mab"; - if (a.URI == kCollectedAddressbookURI) { + const kCollectedAddressbookURIs = [ + "jsaddrbook://history.sqlite", + "moz-abmdbdirectory://history.mab", + ]; + if (kCollectedAddressbookURIs.includes(a.URI)) { return 1; } - if (b.URI == kCollectedAddressbookURI) { + if (kCollectedAddressbookURIs.includes(b.URI)) { return -1; } diff --git a/mail/components/extensions/parent/ext-addressBook.js b/mail/components/extensions/parent/ext-addressBook.js index 12de619590..95381bf976 100644 --- a/mail/components/extensions/parent/ext-addressBook.js +++ b/mail/components/extensions/parent/ext-addressBook.js @@ -372,10 +372,9 @@ var addressBookCache = new (class extends EventEmitter { } case "addrbook-list-updated": { subject.QueryInterface(Ci.nsIAbDirectory); - this.emit( - "mailing-list-updated", - this.findMailingListById(subject.UID) - ); + let listNode = this.findMailingListById(subject.UID); + listNode.item = subject; + this.emit("mailing-list-updated", listNode); break; } case "addrbook-list-member-added": { diff --git a/mail/components/extensions/test/xpcshell/test_ext_addressBook.js b/mail/components/extensions/test/xpcshell/test_ext_addressBook.js index cee4f28633..30c5733198 100644 --- a/mail/components/extensions/test/xpcshell/test_ext_addressBook.js +++ b/mail/components/extensions/test/xpcshell/test_ext_addressBook.js @@ -4,6 +4,9 @@ "use strict"; +var { fixIterator } = ChromeUtils.import( + "resource:///modules/iteratorUtils.jsm" +); var { ExtensionTestUtils } = ChromeUtils.import( "resource://testing-common/ExtensionXPCShellUtils.jsm" ); @@ -597,7 +600,7 @@ add_task(async function test_addressBooks() { return null; } function findMailingList(id) { - for (let list of parent.addressLists.enumerate()) { + for (let list of fixIterator(parent.addressLists, Ci.nsIAbDirectory)) { if (list.UID == id) { return list; } diff --git a/mail/components/migration/src/nsProfileMigratorBase.cpp b/mail/components/migration/src/nsProfileMigratorBase.cpp index eb604b7774..f5cbd2d28b 100644 --- a/mail/components/migration/src/nsProfileMigratorBase.cpp +++ b/mail/components/migration/src/nsProfileMigratorBase.cpp @@ -13,7 +13,7 @@ #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" -#define kPersonalAddressbookUri "moz-abmdbdirectory://abook.mab" +#define kPersonalAddressbookUri "jsaddrbook://abook.sqlite" nsProfileMigratorBase::nsProfileMigratorBase() { mObserverService = do_GetService("@mozilla.org/observer-service;1"); diff --git a/mail/test/mozmill/addrbook/test-address-book.js b/mail/test/mozmill/addrbook/test-address-book.js index 9adb4ed146..61d4571c86 100644 --- a/mail/test/mozmill/addrbook/test-address-book.js +++ b/mail/test/mozmill/addrbook/test-address-book.js @@ -48,10 +48,10 @@ function setupModule(module) { // out of order to properly test the alphabetical // ordering of the address books. ldapBook = create_ldap_address_book("LDAP Book"); - addrBook3 = create_mork_address_book("AB 3"); - addrBook1 = create_mork_address_book("AB 1"); - addrBook4 = create_mork_address_book("AB 4"); - addrBook2 = create_mork_address_book("AB 2"); + addrBook3 = create_address_book("AB 3"); + addrBook1 = create_address_book("AB 1"); + addrBook4 = create_address_book("AB 4"); + addrBook2 = create_address_book("AB 2"); mListA = create_mailing_list("ML A"); addrBook1.addMailList(mListA); diff --git a/mail/test/mozmill/addrbook/test-update-mailing-list.js b/mail/test/mozmill/addrbook/test-update-mailing-list.js index 8d754cf672..87df643abd 100644 --- a/mail/test/mozmill/addrbook/test-update-mailing-list.js +++ b/mail/test/mozmill/addrbook/test-update-mailing-list.js @@ -30,7 +30,7 @@ function test_contact_in_mailing_list_updated() { const kNewAddress = "after@example.com"; // Create some address book to work with... - let ab = create_mork_address_book("Some Address Book"); + let ab = create_address_book("Some Address Book"); // And a contact... let contact = create_contact(kOldAddress, "Some Contact", true); // And our mailing list. @@ -38,10 +38,8 @@ function test_contact_in_mailing_list_updated() { // Add the mailing list to the address book, and then the card to the // address book, and finally, the card to the mailing list. - ml.addressLists.appendElement(contact); ml = ab.addMailList(ml); - - contact = ml.addressLists.queryElementAt(0, Ci.nsIAbCard); + contact = ml.addCard(contact); // Open the address book, select our contact... let abw = open_address_book_window(mc); diff --git a/mail/test/mozmill/composition/test-send-button.js b/mail/test/mozmill/composition/test-send-button.js index a799ba710e..fc36a463c7 100644 --- a/mail/test/mozmill/composition/test-send-button.js +++ b/mail/test/mozmill/composition/test-send-button.js @@ -135,9 +135,7 @@ function test_send_enabled_manual_address() { // - a mailinglist in addressbook // Button is enabled without checking whether it contains valid addresses. - let defaultAB = MailServices.ab.getDirectory( - "moz-abmdbdirectory://abook.mab" - ); + let defaultAB = MailServices.ab.getDirectory("jsaddrbook://abook.sqlite"); let ml = create_mailing_list("emptyList"); defaultAB.addMailList(ml); @@ -237,9 +235,7 @@ function test_send_enabled_prefilled_address_from_identity() { */ function test_send_enabled_address_contacts_sidebar() { // Create some contact address book card in the Personal addressbook. - let defaultAB = MailServices.ab.getDirectory( - "moz-abmdbdirectory://abook.mab" - ); + let defaultAB = MailServices.ab.getDirectory("jsaddrbook://abook.sqlite"); let contact = create_contact("test@example.com", "Sammy Jenkis", true); load_contacts_into_address_book(defaultAB, [contact]); diff --git a/mail/test/mozmill/message-header/test-message-header.js b/mail/test/mozmill/message-header/test-message-header.js index e1d62d8051..e8ea7252bd 100644 --- a/mail/test/mozmill/message-header/test-message-header.js +++ b/mail/test/mozmill/message-header/test-message-header.js @@ -641,7 +641,7 @@ function test_address_book_switch_disabled_on_contact_in_mailing_list() { // Add the card to a new address book, and insert it // into a mailing list under that address book - let ab = create_mork_address_book(ADDRESS_BOOK_NAME); + let ab = create_address_book(ADDRESS_BOOK_NAME); ab.dropCard(card, false); let ml = create_mailing_list(MAILING_LIST_DIRNAME); ab.addMailList(ml); @@ -650,8 +650,7 @@ function test_address_book_switch_disabled_on_contact_in_mailing_list() { // the address book, in order for us to add and // delete cards from it. ml = get_mailing_list_from_address_book(ab, MAILING_LIST_DIRNAME); - - ml.addressLists.appendElement(card); + ml.addCard(card); // Re-open the inline contact editing panel mc.click(getElement(lastAddr, ".emailStar")); diff --git a/mail/test/mozmill/multiple-identities/test-display-names.js b/mail/test/mozmill/multiple-identities/test-display-names.js index 89c8c177e7..6033bbc313 100644 --- a/mail/test/mozmill/multiple-identities/test-display-names.js +++ b/mail/test/mozmill/multiple-identities/test-display-names.js @@ -78,7 +78,7 @@ function setupModule(module) { // Ensure all the directories are initialised. MailServices.ab.directories; collectedAddresses = MailServices.ab.getDirectory( - "moz-abmdbdirectory://history.mab" + "jsaddrbook://history.sqlite" ); let bundle = Services.strings.createBundle( diff --git a/mail/test/mozmill/quick-filter-bar/test-filter-logic.js b/mail/test/mozmill/quick-filter-bar/test-filter-logic.js index 117049cee9..4a8864c6b0 100644 --- a/mail/test/mozmill/quick-filter-bar/test-filter-logic.js +++ b/mail/test/mozmill/quick-filter-bar/test-filter-logic.js @@ -113,10 +113,7 @@ function add_email_to_address_book(aEmailAddr) { let enumerator = MailServices.ab.directories; while (enumerator.hasMoreElements()) { let addrbook = enumerator.getNext(); - if ( - addrbook instanceof Ci.nsIAbMDBDirectory && - addrbook instanceof Ci.nsIAbDirectory - ) { + if (addrbook instanceof Ci.nsIAbDirectory) { addrbook.addCard(card); return; } diff --git a/mail/test/mozmill/shared-modules/test-address-book-helpers.js b/mail/test/mozmill/shared-modules/test-address-book-helpers.js index f0ddd4d6e6..fa8c0782f5 100644 --- a/mail/test/mozmill/shared-modules/test-address-book-helpers.js +++ b/mail/test/mozmill/shared-modules/test-address-book-helpers.js @@ -13,7 +13,7 @@ var { MailServices } = ChromeUtils.import( "resource:///modules/MailServices.jsm" ); -var ABMDB_PREFIX = "moz-abmdbdirectory://"; +var ABJS_PREFIX = "jsaddrbook://"; var ABLDAP_PREFIX = "moz-abldapdirectory://"; var collectedAddresses; @@ -31,7 +31,7 @@ function setupModule() { // Ensure all the directories are initialised. MailServices.ab.directories; collectedAddresses = MailServices.ab.getDirectory( - "moz-abmdbdirectory://history.mab" + "jsaddrbook://history.sqlite" ); } @@ -43,7 +43,7 @@ function installInto(module) { module.ensure_no_card_exists = ensure_no_card_exists; module.open_address_book_window = open_address_book_window; module.close_address_book_window = close_address_book_window; - module.create_mork_address_book = create_mork_address_book; + module.create_address_book = create_address_book; module.create_ldap_address_book = create_ldap_address_book; module.create_contact = create_contact; module.create_mailing_list = create_mailing_list; @@ -150,14 +150,14 @@ function close_address_book_window(abc) { } /** - * Creates and returns a Mork-backed address book. + * Creates and returns a SQLite-backed address book. * @param aName the name for the address book * @returns the nsIAbDirectory address book */ -function create_mork_address_book(aName) { - let abPrefString = MailServices.ab.newAddressBook(aName, "", 2); +function create_address_book(aName) { + let abPrefString = MailServices.ab.newAddressBook(aName, "", 101); let abURI = Services.prefs.getCharPref(abPrefString + ".filename"); - return MailServices.ab.getDirectory(ABMDB_PREFIX + abURI); + return MailServices.ab.getDirectory(ABJS_PREFIX + abURI); } /** @@ -233,12 +233,13 @@ function get_mailing_list_from_address_book(aAddressBook, aDirName) { * [{email: 'test@example.com', displayName: 'Sammy Jenkis'}] */ function load_contacts_into_address_book(aAddressBook, aContacts) { - for (let contact of aContacts) { + for (let i = 0; i < aContacts.length; i++) { + let contact = aContacts[i]; if (!(contact instanceof Ci.nsIAbCard)) { contact = create_contact(contact.email, contact.displayName, true); } - aAddressBook.addCard(contact); + aContacts[i] = aAddressBook.addCard(contact); } } @@ -266,7 +267,7 @@ function load_contacts_into_mailing_list(aMailingList, aContacts) { function get_address_book_tree_view_index(aAddrBook) { let addrbooks = abController.window.gDirectoryTreeView._rowMap; for (let i = 0; i < addrbooks.length; i++) { - if (addrbooks[i]._directory == aAddrBook) { + if (addrbooks[i]._directory.URI == aAddrBook.URI) { return i; } } @@ -286,7 +287,7 @@ function get_contact_ab_view_index(aContact) { let contacts = abController.window.gAbView; for (let i = 0; i < contacts.rowCount; i++) { let contact = contacts.getCardFromRow(i); - if (contact.localId == aContact.localId && !contact.isMailList) { + if (contact.equals(aContact)) { return i; } } diff --git a/mailnews/addrbook/content/abAddressBookNameDialog.js b/mailnews/addrbook/content/abAddressBookNameDialog.js index 05466706eb..9298224e26 100644 --- a/mailnews/addrbook/content/abAddressBookNameDialog.js +++ b/mailnews/addrbook/content/abAddressBookNameDialog.js @@ -14,8 +14,14 @@ var gOkButton; var gNameInput; var gDirectory = null; -var kPersonalAddressbookURI = "moz-abmdbdirectory://abook.mab"; -var kCollectedAddressbookURI = "moz-abmdbdirectory://history.mab"; +var stillUsingMabFiles = + Services.prefs.getIntPref("ldap_2.servers.pab.dirType") == 2; +var kPersonalAddressbookURI = stillUsingMabFiles + ? "moz-abmdbdirectory://abook.mab" + : "jsaddrbook://abook.sqlite"; +var kCollectedAddressbookURI = stillUsingMabFiles + ? "moz-abmdbdirectory://history.mab" + : "jsaddrbook://history.sqlite"; var kAllDirectoryRoot = "moz-abdirectory://"; var kPABDirectory = 2; // defined in nsDirPrefs.h diff --git a/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm b/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm index fdf295c727..dd7ed5d664 100644 --- a/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm +++ b/mailnews/addrbook/jsaddrbook/AddrBookCard.jsm @@ -24,8 +24,13 @@ ChromeUtils.defineModuleGetter( function AddrBookCard() { this._directoryId = ""; this._localId = ""; - this._properties = new Map(); + this._properties = new Map([ + ["PreferMailFormat", Ci.nsIAbPreferMailFormat.unknown], + ["PopularityIndex", 0], + ["LastModifiedDate", 0], + ]); } + AddrBookCard.prototype = { QueryInterface: ChromeUtils.generateQI([Ci.nsIAbCard]), classID: Components.ID("{1143991d-31cd-4ea6-9c97-c587d990d724}"), @@ -141,7 +146,7 @@ AddrBookCard.prototype = { return false; }, get mailListURI() { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; + return ""; }, getProperty(name, defaultValue) { @@ -151,16 +156,37 @@ AddrBookCard.prototype = { return defaultValue; }, getPropertyAsAString(name) { + if (!this._properties.has(name)) { + throw Cr.NS_ERROR_NOT_AVAILABLE; + } return this.getProperty(name); }, getPropertyAsAUTF8String(name) { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; + if (!this._properties.has(name)) { + throw Cr.NS_ERROR_NOT_AVAILABLE; + } + return this.getProperty(name); }, getPropertyAsUint32(name) { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; + let value = this.getProperty(name); + if (isNaN(parseInt(value, 10))) { + throw Cr.NS_ERROR_NOT_AVAILABLE; + } + return value; }, getPropertyAsBool(name) { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; + let value = this.getProperty(name); + switch (value) { + case false: + case 0: + case "0": + return false; + case true: + case 1: + case "1": + return true; + } + throw Cr.NS_ERROR_NOT_AVAILABLE; }, setProperty(name, value) { this._properties.set(name, value); @@ -169,13 +195,13 @@ AddrBookCard.prototype = { throw Cr.NS_ERROR_NOT_IMPLEMENTED; }, setPropertyAsAUTF8String(name, value) { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; + this.setProperty(name, value); }, setPropertyAsUint32(name, value) { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; + this.setProperty(name, value); }, setPropertyAsBool(name, value) { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; + this.setProperty(name, value ? 1 : 0); }, deleteProperty(name) { this._properties.delete(name); diff --git a/mailnews/addrbook/jsaddrbook/AddrBookDirectory.jsm b/mailnews/addrbook/jsaddrbook/AddrBookDirectory.jsm index 9b796db42b..08df452692 100644 --- a/mailnews/addrbook/jsaddrbook/AddrBookDirectory.jsm +++ b/mailnews/addrbook/jsaddrbook/AddrBookDirectory.jsm @@ -105,7 +105,12 @@ AddrBookDirectory.prototype = { if (!this.dirPrefId) { throw Cr.NS_ERROR_UNEXPECTED; } - this.UID; + // Make sure we always have a file. If a file is not created, the + // filename may be accidentally reused. + let file = FileUtils.getFile("ProfD", [filename]); + if (!file.exists()) { + file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644); + } } }, }; @@ -125,11 +130,43 @@ var closeObserver = { Services.obs.addObserver(closeObserver, "addrbook-reload"); Services.obs.addObserver(closeObserver, "quit-application"); -function closeConnectionTo(path) { - let connection = connections.get(path); +/** + * Opens an SQLite connection to `file`, caches the connection, and upgrades + * the database schema if necessary. + */ +function openConnectionTo(file) { + let connection = connections.get(file.path); + if (!connection) { + connection = Services.storage.openDatabase(file); + if (connection.schemaVersion == 0) { + connection.executeSimpleSQL("PRAGMA journal_mode=WAL"); + connection.executeSimpleSQL( + "CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER)" + ); + connection.executeSimpleSQL( + "CREATE TABLE properties (card TEXT, name TEXT, value TEXT)" + ); + connection.executeSimpleSQL( + "CREATE TABLE lists (uid TEXT PRIMARY KEY, localId INTEGER, name TEXT, nickName TEXT, description TEXT)" + ); + connection.executeSimpleSQL( + "CREATE TABLE list_cards (list TEXT, card TEXT, PRIMARY KEY(list, card))" + ); + connection.schemaVersion = 1; + } + connections.set(file.path, connection); + } + return connection; +} + +/** + * Closes the SQLite connection to `file` and removes it from the cache. + */ +function closeConnectionTo(file) { + let connection = connections.get(file.path); if (connection) { connection.close(); - connections.delete(path); + connections.delete(file.path); } } @@ -150,27 +187,7 @@ var bookPrototype = { }, get _dbConnection() { let file = FileUtils.getFile("ProfD", [this.fileName]); - let connection = connections.get(file.path); - if (!connection) { - connection = Services.storage.openDatabase(file); - if (connection.schemaVersion == 0) { - connection.executeSimpleSQL("PRAGMA journal_mode=WAL"); - connection.executeSimpleSQL( - "CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER)" - ); - connection.executeSimpleSQL( - "CREATE TABLE properties (card TEXT, name TEXT, value TEXT)" - ); - connection.executeSimpleSQL( - "CREATE TABLE lists (uid TEXT PRIMARY KEY, localId INTEGER, name TEXT, nickName TEXT, description TEXT)" - ); - connection.executeSimpleSQL( - "CREATE TABLE list_cards (list TEXT, card TEXT, PRIMARY KEY(list, card))" - ); - connection.schemaVersion = 1; - } - connections.set(file.path, connection); - } + let connection = openConnectionTo(file); delete this._dbConnection; Object.defineProperty(this, "_dbConnection", { @@ -214,30 +231,32 @@ var bookPrototype = { _getNextCardId() { if (this._nextCardId === null) { - let value = 1; + let value = 0; let selectStatement = this._dbConnection.createStatement( "SELECT MAX(localId) AS localId FROM cards" ); if (selectStatement.executeStep()) { - value = selectStatement.row.localId + 1; + value = selectStatement.row.localId; } this._nextCardId = value; selectStatement.finalize(); } + this._nextCardId++; return this._nextCardId.toString(); }, _getNextListId() { if (this._nextListId === null) { - let value = 1; + let value = 0; let selectStatement = this._dbConnection.createStatement( "SELECT MAX(localId) AS localId FROM lists" ); if (selectStatement.executeStep()) { - value = selectStatement.row.localId + 1; + value = selectStatement.row.localId; } this._nextListId = value; selectStatement.finalize(); } + this._nextListId++; return this._nextListId.toString(); }, _getCard({ uid, localId = null }) { @@ -321,11 +340,12 @@ var bookPrototype = { let selectStatement = this._dbConnection.createStatement(sql); selectStatement.params.name = property; selectStatement.params.value = value; + let result = null; if (selectStatement.executeStep()) { - return this._getCard({ uid: selectStatement.row.card }); + result = this._getCard({ uid: selectStatement.row.card }); } selectStatement.finalize(); - return null; + return result; }, getCardsFromProperty(property, value, caseSensitive) { let sql = caseSensitive @@ -348,11 +368,11 @@ var bookPrototype = { return "chrome://messenger/content/addressbook/abAddressBookNameDialog.xul"; }, get dirName() { - return this._prefBranch.getStringPref("description", ""); + return this.getLocalizedStringValue("description", ""); }, set dirName(value) { let oldValue = this.dirName; - this._prefBranch.setStringPref("description", value); + this.setLocalizedStringValue("description", value); MailServices.ab.notifyItemPropertyChanged(this, "DirName", oldValue, value); }, get dirType() { @@ -573,7 +593,7 @@ var bookPrototype = { return this._lists.has(dir.UID); }, hasMailListWithName(name) { - for (let list of this._lists) { + for (let list of this._lists.values()) { if (list.name == name) { return true; } @@ -612,31 +632,25 @@ var bookPrototype = { let deleteCardStatement = this._dbConnection.createStatement( "DELETE FROM cards WHERE uid = :uid" ); - let selectListCardStatement = this._dbConnection.createStatement( - "SELECT list FROM list_cards WHERE card = :card" - ); for (let card of cards.enumerate(Ci.nsIAbCard)) { deleteCardStatement.params.uid = card.UID; deleteCardStatement.execute(); deleteCardStatement.reset(); - MailServices.ab.notifyDirectoryItemDeleted(this, card); - - selectListCardStatement.params.card = card.UID; - while (selectListCardStatement.executeStep()) { - let list = new AddrBookMailingList( - selectListCardStatement.row.list, - this - ); - list.asDirectory.deleteCards(toXPCOMArray([card], Ci.nsIMutableArray)); - } } - this._dbConnection.executeSimpleSQL( "DELETE FROM properties WHERE card NOT IN (SELECT DISTINCT uid FROM cards)" ); + for (let card of cards.enumerate(Ci.nsIAbCard)) { + MailServices.ab.notifyDirectoryItemDeleted(this, card); + } + + // We could just delete all non-existent cards from list_cards, but a + // notification should be fired for each one. Let the list handle that. + for (let list of this.childNodes) { + list.deleteCards(cards); + } deleteCardStatement.finalize(); - selectListCardStatement.finalize(); }, dropCard(card, needToCopyCard) { let newCard = new AddrBookCard(); @@ -714,7 +728,7 @@ var bookPrototype = { return defaultValue; } return this._prefBranch.getComplexValue(name, Ci.nsIPrefLocalizedString) - .value; + .data; }, setIntValue(name, value) { this._prefBranch.setIntPref(name, value); @@ -726,6 +740,14 @@ var bookPrototype = { this._prefBranch.setStringPref(name, value); }, setLocalizedStringValue(name, value) { - this._prefBranch.setComplexValue(name, Ci.nsIPrefLocalizedString, value); + let valueLocal = Cc["@mozilla.org/pref-localizedstring;1"].createInstance( + Ci.nsIPrefLocalizedString + ); + valueLocal.data = value; + this._prefBranch.setComplexValue( + name, + Ci.nsIPrefLocalizedString, + valueLocal + ); }, }; diff --git a/mailnews/addrbook/jsaddrbook/AddrBookFactory.jsm b/mailnews/addrbook/jsaddrbook/AddrBookFactory.jsm index 2fffe4b305..55485aba36 100644 --- a/mailnews/addrbook/jsaddrbook/AddrBookFactory.jsm +++ b/mailnews/addrbook/jsaddrbook/AddrBookFactory.jsm @@ -61,7 +61,7 @@ AddrBookFactory.prototype = { deleteDirectory(directory) { let file = FileUtils.getFile("ProfD", [directory.fileName]); if (file.exists()) { - closeConnectionTo(file.path); + closeConnectionTo(file); file.remove(false); } }, diff --git a/mailnews/addrbook/jsaddrbook/AddrBookMailingList.jsm b/mailnews/addrbook/jsaddrbook/AddrBookMailingList.jsm index 50bf0e270f..782bd05ae5 100644 --- a/mailnews/addrbook/jsaddrbook/AddrBookMailingList.jsm +++ b/mailnews/addrbook/jsaddrbook/AddrBookMailingList.jsm @@ -4,6 +4,11 @@ this.EXPORTED_SYMBOLS = ["AddrBookMailingList"]; +ChromeUtils.defineModuleGetter( + this, + "fixIterator", + "resource:///modules/iteratorUtils.jsm" +); ChromeUtils.defineModuleGetter( this, "MailServices", @@ -138,6 +143,9 @@ AddrBookMailingList.prototype = { if (!card.primaryEmail) { return card; } + if (!self._parent.hasCard(card)) { + self._parent.addCard(card); + } let insertStatement = self._parent._dbConnection.createStatement( "REPLACE INTO list_cards (list, card) VALUES (:list, :card)" ); @@ -156,17 +164,19 @@ AddrBookMailingList.prototype = { let deleteCardStatement = self._parent._dbConnection.createStatement( "DELETE FROM list_cards WHERE list = :list AND card = :card" ); - for (let card of cards.enumerate()) { + for (let card of fixIterator(cards, Ci.nsIAbCard)) { deleteCardStatement.params.list = self._uid; deleteCardStatement.params.card = card.UID; deleteCardStatement.execute(); + if (self._parent._dbConnection.affectedRows) { + MailServices.ab.notifyDirectoryItemDeleted(this, card); + Services.obs.notifyObservers( + card, + "addrbook-list-member-removed", + self._uid + ); + } deleteCardStatement.reset(); - MailServices.ab.notifyDirectoryItemDeleted(this, card); - Services.obs.notifyObservers( - card, - "addrbook-list-member-removed", - self._uid - ); } deleteCardStatement.finalize(); }, @@ -206,6 +216,12 @@ AddrBookMailingList.prototype = { return `${self._parent.URI}/MailList${self._localId}`; }, + get directoryId() { + return self._parent.uuid; + }, + get localId() { + return self._localId; + }, get displayName() { return self._name; }, diff --git a/mailnews/addrbook/public/nsIAbDirectory.idl b/mailnews/addrbook/public/nsIAbDirectory.idl index 8e4ae12336..959930513a 100644 --- a/mailnews/addrbook/public/nsIAbDirectory.idl +++ b/mailnews/addrbook/public/nsIAbDirectory.idl @@ -17,15 +17,17 @@ interface nsIMutableArray; %{C++ #define kAllDirectoryRoot "moz-abdirectory://" -#define kPersonalAddressbook "abook.mab" -#define kPersonalAddressbookUri "moz-abmdbdirectory://abook.mab" -#define kCollectedAddressbook "history.mab" -#define kCollectedAddressbookUri "moz-abmdbdirectory://history.mab" +#define kPersonalAddressbook "abook.sqlite" +#define kPersonalAddressbookUri "jsaddrbook://abook.sqlite" +#define kCollectedAddressbook "history.sqlite" +#define kCollectedAddressbookUri "jsaddrbook://history.sqlite" #define kABFileName_PreviousSuffix ".na2" /* final v2 address book format */ #define kABFileName_PreviousSuffixLen 4 #define kABFileName_CurrentSuffix ".mab" /* v3 address book extension */ +#define kMDBAddressBook "abook.mab" + #define kJSDirectoryRoot "jsaddrbook://" #define kJSAddressBook "abook.sqlite" %} diff --git a/mailnews/addrbook/src/nsAbAddressCollector.cpp b/mailnews/addrbook/src/nsAbAddressCollector.cpp index f6aa428855..db450d843f 100644 --- a/mailnews/addrbook/src/nsAbAddressCollector.cpp +++ b/mailnews/addrbook/src/nsAbAddressCollector.cpp @@ -39,7 +39,8 @@ nsAbAddressCollector::~nsAbAddressCollector() { * returns an already addrefed pointer to the card if the card is found. */ already_AddRefed nsAbAddressCollector::GetCardForAddress( - const nsACString &aEmailAddress, nsIAbDirectory **aDirectory) { + const char *aProperty, const nsACString &aEmailAddress, + nsIAbDirectory **aDirectory) { nsresult rv; nsCOMPtr abManager(do_GetService(NS_ABMANAGER_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, nullptr); @@ -61,8 +62,8 @@ already_AddRefed nsAbAddressCollector::GetCardForAddress( // Some implementations may return NS_ERROR_NOT_IMPLEMENTED here, // so just catch the value and continue. - if (NS_FAILED(directory->CardForEmailAddress(aEmailAddress, - getter_AddRefs(result)))) { + if (NS_FAILED(directory->GetCardFromProperty( + aProperty, aEmailAddress, false, getter_AddRefs(result)))) { continue; } @@ -111,10 +112,19 @@ nsAbAddressCollector::CollectSingleAddress(const nsACString &aEmail, nsresult rv; nsCOMPtr originDirectory; - nsCOMPtr card = - (!aSkipCheckExisting) - ? GetCardForAddress(aEmail, getter_AddRefs(originDirectory)) - : nullptr; + nsCOMPtr card; + if (!aSkipCheckExisting) { + card = GetCardForAddress(kPriEmailProperty, aEmail, + getter_AddRefs(originDirectory)); + + // If a card has aEmail, but it's the secondary address, we don't want to + // update any properties, so just return. + if (!card) { + card = GetCardForAddress(k2ndEmailProperty, aEmail, + getter_AddRefs(originDirectory)); + if (card) return NS_OK; + } + } if (!card && (aCreateCard || aSkipCheckExisting)) { card = do_CreateInstance(NS_ABCARDPROPERTY_CONTRACTID, &rv); diff --git a/mailnews/addrbook/src/nsAbAddressCollector.h b/mailnews/addrbook/src/nsAbAddressCollector.h index 52e3783c1d..1e49302b23 100644 --- a/mailnews/addrbook/src/nsAbAddressCollector.h +++ b/mailnews/addrbook/src/nsAbAddressCollector.h @@ -27,7 +27,8 @@ class nsAbAddressCollector : public nsIAbAddressCollector, public nsIObserver { private: virtual ~nsAbAddressCollector(); - already_AddRefed GetCardForAddress(const nsACString &aEmailAddress, + already_AddRefed GetCardForAddress(const char *aProperty, + const nsACString &aEmailAddress, nsIAbDirectory **aDirectory); void AutoCollectScreenName(nsIAbCard *aCard, const nsACString &aEmail); bool SetNamesForCard(nsIAbCard *aSenderCard, const nsACString &aFullName); diff --git a/mailnews/addrbook/src/nsAddbookProtocolHandler.cpp b/mailnews/addrbook/src/nsAddbookProtocolHandler.cpp index 5d6c736f2a..587fc7837a 100644 --- a/mailnews/addrbook/src/nsAddbookProtocolHandler.cpp +++ b/mailnews/addrbook/src/nsAddbookProtocolHandler.cpp @@ -180,21 +180,21 @@ nsresult nsAddbookProtocolHandler::GeneratePrintOutput( NS_ENSURE_SUCCESS(rv, rv); /* turn - "//moz-abmdbdirectory/abook.mab?action=print" - into "moz-abmdbdirectory://abook.mab" + "//jsaddrbook/abook.sqlite?action=print" + into "jsaddrbook://abook.sqlite" */ /* step 1: - turn "//moz-abmdbdirectory/abook.mab?action=print" - into "moz-abmdbdirectory/abook.mab?action=print" + turn "//jsaddrbook/abook.sqlite?action=print" + into "jsaddrbook/abook.sqlite?action=print" */ if (uri[0] != '/' && uri[1] != '/') return NS_ERROR_UNEXPECTED; uri.Cut(0, 2); /* step 2: - turn "moz-abmdbdirectory/abook.mab?action=print" - into "moz-abmdbdirectory/abook.mab" + turn "jsaddrbook/abook.sqlite?action=print" + into "jsaddrbook/abook.sqlite" */ int32_t pos = uri.Find("?action=print"); if (pos == -1) return NS_ERROR_UNEXPECTED; @@ -202,8 +202,8 @@ nsresult nsAddbookProtocolHandler::GeneratePrintOutput( uri.SetLength(pos); /* step 2: - turn "moz-abmdbdirectory/abook.mab" - into "moz-abmdbdirectory://abook.mab" + turn "jsaddrbook/abook.sqlite" + into "jsaddrbook://abook.sqlite" */ pos = uri.FindChar('/'); if (pos == -1) return NS_ERROR_UNEXPECTED; diff --git a/mailnews/addrbook/src/nsDirPrefs.cpp b/mailnews/addrbook/src/nsDirPrefs.cpp index 8e79cc2b4e..f422133097 100644 --- a/mailnews/addrbook/src/nsDirPrefs.cpp +++ b/mailnews/addrbook/src/nsDirPrefs.cpp @@ -262,7 +262,7 @@ nsresult DIR_AddNewAddressBook(const nsAString &dirName, if (!fileName.IsEmpty()) server->fileName = ToNewCString(fileName); else if (dirType == PABDirectory) - DIR_SetFileName(&server->fileName, kPersonalAddressbook); + DIR_SetFileName(&server->fileName, kMDBAddressBook); else if (dirType == LDAPDirectory) DIR_SetFileName(&server->fileName, kMainLdapAddressBook); else if (dirType == JSDirectory) @@ -587,8 +587,8 @@ nsresult DIR_DeleteServerFromList(DIR_Server *server) { // "abook.mab" as the file name for LDAP directories, which would cause a // crash on delete of LDAP directories. this is just extra protection. if (server->fileName && server->dirType != JSDirectory && - strcmp(server->fileName, kPersonalAddressbook) && - strcmp(server->fileName, kCollectedAddressbook)) { + strcmp(server->fileName, "abook.mab") && + strcmp(server->fileName, "history.mab")) { nsCOMPtr database; rv = dbPath->AppendNative(nsDependentCString(server->fileName)); @@ -912,7 +912,7 @@ void DIR_SetServerFileName(DIR_Server *server) { server->prefName = dir_CreateServerPrefName(server); /* set default personal address book file name*/ - if ((server->position == 1) && (server->dirType == PABDirectory)) + if ((server->position == 1) && (server->dirType == JSDirectory)) server->fileName = strdup(kPersonalAddressbook); else { /* now use the pref name as the file name since we know the pref name @@ -937,12 +937,15 @@ void DIR_SetServerFileName(DIR_Server *server) { if (!server->fileName || !*server->fileName) /* when all else has failed, generate a default name */ { - if (server->dirType == LDAPDirectory) + if (server->dirType == PABDirectory) { + DIR_SetFileName(&(server->fileName), kMDBAddressBook); + } else if (server->dirType == LDAPDirectory) { DIR_SetFileName( &(server->fileName), kMainLdapAddressBook); /* generates file name with an ldap prefix */ - else + } else { DIR_SetFileName(&(server->fileName), kPersonalAddressbook); + } } } } diff --git a/mailnews/addrbook/test/unit/data/cardForEmail.sql b/mailnews/addrbook/test/unit/data/cardForEmail.sql index ea266d61ab..6cd37c95b7 100644 --- a/mailnews/addrbook/test/unit/data/cardForEmail.sql +++ b/mailnews/addrbook/test/unit/data/cardForEmail.sql @@ -1,3 +1,4 @@ +-- Address book data for use in various tests. PRAGMA user_version = 1; CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER); diff --git a/mailnews/addrbook/test/unit/data/collect.sql b/mailnews/addrbook/test/unit/data/collect.sql index d50cbefb0a..dba17a7392 100644 --- a/mailnews/addrbook/test/unit/data/collect.sql +++ b/mailnews/addrbook/test/unit/data/collect.sql @@ -1,3 +1,4 @@ +-- Collection address book for use in test_collection_2.js. PRAGMA user_version = 1; CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER); diff --git a/mailnews/addrbook/test/unit/head_addrbook.js b/mailnews/addrbook/test/unit/head_addrbook.js index dbdc6314d6..350fcfe1d3 100644 --- a/mailnews/addrbook/test/unit/head_addrbook.js +++ b/mailnews/addrbook/test/unit/head_addrbook.js @@ -8,12 +8,54 @@ var { XPCOMUtils } = ChromeUtils.import( var CC = Components.Constructor; +Services.prefs.setIntPref("ldap_2.servers.history.dirType", 2); +Services.prefs.setStringPref("ldap_2.servers.history.filename", "history.mab"); +Services.prefs.setIntPref("ldap_2.servers.pab.dirType", 2); +Services.prefs.setStringPref("ldap_2.servers.pab.filename", "abook.mab"); +Services.prefs.setIntPref("mail.addr_book.newDirType", 2); +Services.prefs.setStringPref( + "mail.collect_addressbook", + "moz-abmdbdirectory://history.mab" +); +Services.prefs.setStringPref( + "mail.server.default.whiteListAbURI", + "moz-abmdbdirectory://abook.mab" +); + // Ensure the profile directory is set up do_get_profile(); -// Import the required setup scripts. -/* import-globals-from ../../../test/resources/abSetup.js */ -load("../../../resources/abSetup.js"); +// Personal Address Book configuration items. +var kPABData = { + URI: "moz-abmdbdirectory://abook.mab", + fileName: "abook.mab", + dirName: "Personal Address Book", + dirType: 2, + dirPrefID: "ldap_2.servers.pab", + readOnly: false, + position: 1, +}; + +// Collected Address Book configuration items. +var kCABData = { + URI: "moz-abmdbdirectory://history.mab", + fileName: "history.mab", + dirName: "Collected Addresses", + dirType: 2, + dirPrefID: "ldap_2.servers.history", + readOnly: false, + position: 2, +}; + +// Windows (Outlook Express) Address Book deactivation. (Bug 448859) +Services.prefs.deleteBranch("ldap_2.servers.oe."); + +// OSX Address Book deactivation (Bug 955842) +Services.prefs.deleteBranch("ldap_2.servers.osx."); + +// This currently applies to all address books of local type. +var kNormalPropertiesURI = + "chrome://messenger/content/addressbook/abAddressBookNameDialog.xul"; function loadABFile(source, dest) { let testAB = do_get_file(`${source}.mab`); diff --git a/mailnews/addrbook/test/unit/head_jsaddrbook.js b/mailnews/addrbook/test/unit/head_jsaddrbook.js index 7a99ee8b40..caf040ff78 100644 --- a/mailnews/addrbook/test/unit/head_jsaddrbook.js +++ b/mailnews/addrbook/test/unit/head_jsaddrbook.js @@ -9,74 +9,9 @@ var { XPCOMUtils } = ChromeUtils.import( // Ensure the profile directory is set up do_get_profile(); -// What follows is a copy of abSetup.js modified for tests with the -// JS directory provider. We don't yet make the personal address book -// and collected addresses book with this provider, so add two new -// directories and pretend they are the original ones. - -MailServices.ab.newAddressBook("pab2", "jsaddrbook://abook.sqlite", 101); -MailServices.ab.newAddressBook("history2", "jsaddrbook://abook-1.sqlite", 101); -Services.prefs.setIntPref("ldap_2.servers.history2.position", 2); - -// Personal Address Book configuration items. -var kPABData = { - URI: "jsaddrbook://abook.sqlite", - fileName: "abook.sqlite", - dirName: "pab2", - dirType: 101, - dirPrefID: "ldap_2.servers.pab2", - readOnly: false, - position: 1, -}; - -// Collected Address Book configuration items. -var kCABData = { - URI: "jsaddrbook://abook-1.sqlite", - fileName: "abook-1.sqlite", - dirName: "history2", - dirType: 101, - dirPrefID: "ldap_2.servers.history2", - readOnly: false, - position: 2, -}; - -// Windows (Outlook Express) Address Book deactivation. (Bug 448859) -Services.prefs.deleteBranch("ldap_2.servers.oe."); - -// OSX Address Book deactivation (Bug 955842) -Services.prefs.deleteBranch("ldap_2.servers.osx."); - -// This currently applies to all address books of local type. -var kNormalPropertiesURI = - "chrome://messenger/content/addressbook/abAddressBookNameDialog.xul"; - -function loadABFile(source, dest) { - let sourceFile = do_get_file(`${source}.sql`); - let destFile = do_get_profile(); - destFile.append(kPABData.fileName); - - let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( - Ci.nsIFileInputStream - ); - let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance( - Ci.nsIConverterInputStream - ); - fstream.init(sourceFile, -1, 0, 0); - cstream.init(fstream, "UTF-8", 0, 0); - - let data = ""; - let read = 0; - do { - let str = {}; - read = cstream.readString(0xffffffff, str); - data += str.value; - } while (read != 0); - cstream.close(); - - let conn = Services.storage.openDatabase(destFile); - conn.executeSimpleSQL(data); - conn.close(); -} +// Import the required setup scripts. +/* import-globals-from ../../../test/resources/abSetup.js */ +load("../../../resources/abSetup.js"); registerCleanupFunction(function() { load("../../../resources/mailShutdown.js"); diff --git a/mailnews/addrbook/test/unit/test_jsaddrbook.js b/mailnews/addrbook/test/unit/test_jsaddrbook.js index bd2069f33b..5263478077 100644 --- a/mailnews/addrbook/test/unit/test_jsaddrbook.js +++ b/mailnews/addrbook/test/unit/test_jsaddrbook.js @@ -5,7 +5,7 @@ "use strict"; var DIR_TYPE = kPABData.dirType; -var FILE_NAME = DIR_TYPE == 101 ? "abook-2.sqlite" : "abook-1.mab"; +var FILE_NAME = DIR_TYPE == 101 ? "abook-1.sqlite" : "abook-1.mab"; var SCHEME = DIR_TYPE == 101 ? "jsaddrbook" : "moz-abmdbdirectory"; var { MailServices } = ChromeUtils.import( @@ -88,8 +88,23 @@ var observer = { }; add_task(async function setUp() { - do_get_profile(); + let profileDir = do_get_profile(); observer.setUp(); + + let dirs = [...MailServices.ab.directories]; + equal(dirs.length, 2); + equal(dirs[0].fileName, kPABData.fileName); + equal(dirs[1].fileName, kCABData.fileName); + + // Check the PAB file was created. + let pabFile = profileDir.clone(); + pabFile.append(kPABData.fileName); + ok(pabFile.exists()); + + // Check the CAB file was created. + let cabFile = profileDir.clone(); + cabFile.append(kCABData.fileName); + ok(cabFile.exists()); }); add_task(async function createAddressBook() { @@ -132,7 +147,12 @@ add_task(async function createAddressBook() { FILE_NAME ); equal(Services.prefs.getStringPref("ldap_2.servers.newbook.uid"), book.UID); - equal([...MailServices.ab.directories].length, DIR_TYPE == 101 ? 5 : 3); + equal([...MailServices.ab.directories].length, 3); + + // Check the file was created. + let dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile); + dbFile.append(FILE_NAME); + ok(dbFile.exists()); }); add_task(async function editAddressBook() { @@ -348,7 +368,7 @@ add_task(async function deleteAddressBook() { let dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile); dbFile.append(FILE_NAME); ok(!dbFile.exists()); - equal([...MailServices.ab.directories].length, DIR_TYPE == 101 ? 4 : 2); + equal([...MailServices.ab.directories].length, 2); if (DIR_TYPE == 101) { throws( () => MailServices.ab.getDirectory(`${SCHEME}://${FILE_NAME}`), diff --git a/mailnews/addrbook/test/unit/test_nsAbManager2.js b/mailnews/addrbook/test/unit/test_nsAbManager2.js index 1fb4bf193c..0c58b2e246 100644 --- a/mailnews/addrbook/test/unit/test_nsAbManager2.js +++ b/mailnews/addrbook/test/unit/test_nsAbManager2.js @@ -123,10 +123,6 @@ function run_test() { } var expectedABs = [kPABData.URI, kCABData.URI]; - if (kPABData.dirType == 101) { - expectedABs.push("moz-abmdbdirectory://abook.mab"); - expectedABs.push("moz-abmdbdirectory://history.mab"); - } // Test - Check initial directories diff --git a/mailnews/base/search/content/searchWidgets.js b/mailnews/base/search/content/searchWidgets.js index 88d3d8937e..31189ebbef 100644 --- a/mailnews/base/search/content/searchWidgets.js +++ b/mailnews/base/search/content/searchWidgets.js @@ -877,7 +877,7 @@ this.internalOperator != Ci.nsMsgSearchOp.IsInAB ) { const abs = children[4].querySelector( - `[value="moz-abmdbdirectory://abook.mab"]` + `[value="moz-abmdbdirectory://abook.mab"], [value="jsaddrbook://abook.sqlite"]` ); if (abs) { children[4].selectedItem = abs; diff --git a/mailnews/base/src/nsMsgDBView.cpp b/mailnews/base/src/nsMsgDBView.cpp index ffefe04e00..78974affda 100644 --- a/mailnews/base/src/nsMsgDBView.cpp +++ b/mailnews/base/src/nsMsgDBView.cpp @@ -291,9 +291,11 @@ static nsresult GetDisplayNameInAddressBook(const nsACString &emailAddress, if (cardForAddress) { bool preferDisplayName = true; - cardForAddress->GetPropertyAsBool("PreferDisplayName", &preferDisplayName); + rv = cardForAddress->GetPropertyAsBool("PreferDisplayName", + &preferDisplayName); - if (preferDisplayName) rv = cardForAddress->GetDisplayName(displayName); + if (NS_FAILED(rv) || preferDisplayName) + rv = cardForAddress->GetDisplayName(displayName); } return rv; diff --git a/mailnews/base/test/unit/data/remoteContent.sql b/mailnews/base/test/unit/data/remoteContent.sql new file mode 100644 index 0000000000..042cfefbd9 --- /dev/null +++ b/mailnews/base/test/unit/data/remoteContent.sql @@ -0,0 +1,41 @@ +-- Address book with remote content permissions for use in test_accountMigration.js. +PRAGMA user_version = 1; + +CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER); +CREATE TABLE properties (card TEXT, name TEXT, value TEXT); +CREATE TABLE lists (uid TEXT PRIMARY KEY, localId INTEGER, name TEXT, nickName TEXT, description TEXT); +CREATE TABLE list_cards (list TEXT, card TEXT, PRIMARY KEY(list, card)); + +INSERT INTO cards (uid, localId) VALUES + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 1), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 2), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 3); + +INSERT INTO properties (card, name, value) VALUES + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'PrimaryEmail', 'no@test.invalid'), + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'PhotoType', 'generic'), + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'LowercasePrimaryEmail', 'no@test.invalid'), + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'PopularityIndex', '0'), + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'PreferMailFormat', '0'), + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'LastModifiedDate', '0'), + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'PreferDisplayName', '1'), + ('f36c4b94-fbab-4cd6-b175-bf8242e6e757', 'AllowRemoteContent', '0'), + + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'PrimaryEmail', 'yes@test.invalid'), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'PhotoType', 'generic'), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'LowercasePrimaryEmail', 'yes@test.invalid'), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'PopularityIndex', '0'), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'PreferMailFormat', '0'), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'LastModifiedDate', '0'), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'PreferDisplayName', '1'), + ('7ecf5197-87cd-4633-8fcb-bf4ed8f6239e', 'AllowRemoteContent', '0'), + + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'LastModifiedDate', '1397383824'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'PrimaryEmail', 'yes@test.invalid'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'PhotoType', 'generic'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'SecondEmail', 'yes2@test.invalid'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'LowercasePrimaryEmail', 'yes@test.invalid'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'PopularityIndex', '0'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'PreferMailFormat', '0'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'PreferDisplayName', '1'), + ('90a1de3d-0f5d-4352-b927-60ee8205ac8f', 'AllowRemoteContent', '1'); diff --git a/mailnews/base/test/unit/test_accountMigration.js b/mailnews/base/test/unit/test_accountMigration.js index 6315f31c85..f8ed4147bd 100644 --- a/mailnews/base/test/unit/test_accountMigration.js +++ b/mailnews/base/test/unit/test_accountMigration.js @@ -30,10 +30,7 @@ function run_test() { "account1,account2" ); - let testAB = do_get_file("data/remoteContent.mab"); - - // Copy the file to the profile directory for a PAB. - testAB.copyTo(do_get_profile(), kPABData.fileName); + loadABFile("data/remoteContent", kPABData.fileName); let uriAllowed = Services.io.newURI( "chrome://messenger/content/email=yes@test.invalid" diff --git a/mailnews/base/test/unit/test_junkWhitelisting.js b/mailnews/base/test/unit/test_junkWhitelisting.js index 8e06074a96..29d5d21733 100644 --- a/mailnews/base/test/unit/test_junkWhitelisting.js +++ b/mailnews/base/test/unit/test_junkWhitelisting.js @@ -39,11 +39,10 @@ var Files = ["../../../data/bugmail1", "../../../data/bugmail3"]; var hdrs = []; function run_test() { - // Test setup - copy the data file into place - var testAB = do_get_file("../../../addrbook/test/unit/data/cardForEmail.mab"); - - // Copy the file to the profile directory for a PAB (this is the personal address book) - testAB.copyTo(do_get_profile(), kPABData.fileName); + loadABFile( + "../../../addrbook/test/unit/data/cardForEmail", + kPABData.fileName + ); do_test_pending(); diff --git a/mailnews/base/test/unit/test_searchAddressInAb.js b/mailnews/base/test/unit/test_searchAddressInAb.js index fa01f15518..b2ca941517 100644 --- a/mailnews/base/test/unit/test_searchAddressInAb.js +++ b/mailnews/base/test/unit/test_searchAddressInAb.js @@ -183,11 +183,10 @@ function run_test() { // Setup local mail accounts. localAccountUtils.loadLocalMailAccount(); - // Test setup - copy the data file into place - var testAB = do_get_file("../../../addrbook/test/unit/data/cardForEmail.mab"); - - // Copy the file to the profile directory for a PAB - testAB.copyTo(do_get_profile(), kPABData.fileName); + loadABFile( + "../../../addrbook/test/unit/data/cardForEmail", + kPABData.fileName + ); // test that validity table terms are valid diff --git a/mailnews/compose/test/unit/data/listexpansion.sql b/mailnews/compose/test/unit/data/listexpansion.sql new file mode 100644 index 0000000000..6c4f6491be --- /dev/null +++ b/mailnews/compose/test/unit/data/listexpansion.sql @@ -0,0 +1,126 @@ +-- Address book with nested mailing lists for use in test_expandMailingLists.js. +PRAGMA user_version = 1; + +CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER); +CREATE TABLE properties (card TEXT, name TEXT, value TEXT); +CREATE TABLE lists (uid TEXT PRIMARY KEY, localId INTEGER, name TEXT, nickName TEXT, description TEXT); +CREATE TABLE list_cards (list TEXT, card TEXT, PRIMARY KEY(list, card)); + +INSERT INTO cards (uid, localId) VALUES + ('813155c6-924d-4751-95d0-70d8e64f16bc', 1), -- homer + ('b2cc8395-d959-45e4-9516-17457adb16fa', 2), -- marge + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 3), -- bart + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 4), -- lisa + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 5), -- maggie + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', 6), --simpson + ('18204ef9-e4e3-4cd5-9981-604c69bbb9ee', 7), --marge + ('ad305609-3535-4d51-8c96-cd82d93aed46', 8), --family + ('4808121d-ebad-4564-864d-8f1149aa053b', 9), --kids + ('4926ff7a-e929-475a-8aa8-2baac994390c', 10), --parents + ('84fa4513-9b60-4379-ade7-1e4b48d67c84', 11), --older-kids + ('8e88b9a4-2500-48e0-bcea-b1fa4eab6b72', 12), --bad-kids + ('34e60324-4fb6-4f10-ab1b-333b07680228', 13); --bad-younger-kids + +INSERT INTO properties (card, name, value) VALUES + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'PrimaryEmail', 'homer@example.com'), + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'PhotoType', 'generic'), + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'LowercasePrimaryEmail', 'homer@example.com'), + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'DisplayName', 'Simpson'), + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'LastModifiedDate', '1473722922'), + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'PopularityIndex', '0'), + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'PreferMailFormat', '0'), + ('813155c6-924d-4751-95d0-70d8e64f16bc', 'PreferDisplayName', '1'), + + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'DisplayName', 'Marge'), + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'PrimaryEmail', 'marge@example.com'), + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'PhotoType', 'generic'), + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'LowercasePrimaryEmail', 'marge@example.com'), + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'LastModifiedDate', '1473723020'), + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'PopularityIndex', '0'), + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'PreferMailFormat', '0'), + ('b2cc8395-d959-45e4-9516-17457adb16fa', 'PreferDisplayName', '1'), + + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'PhotoType', 'generic'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'PopularityIndex', '0'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'PreferMailFormat', '0'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'PreferDisplayName', '1'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'DisplayName', 'Bart'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'PrimaryEmail', 'bart@foobar.invalid'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'LowercasePrimaryEmail', 'bart@foobar.invalid'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'SecondEmail', 'bart@example.com'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'LowercaseSecondEmail', 'bart@example.com'), + ('979f194e-49f2-4bbb-b364-598cdc6a7d11', 'LastModifiedDate', '1473716192'), + + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'PrimaryEmail', 'lisa@example.com'), + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'PhotoType', 'generic'), + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'LowercasePrimaryEmail', 'lisa@example.com'), + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'DisplayName', 'lisa@example.com'), + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'PopularityIndex', '0'), + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'PreferMailFormat', '0'), + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'LastModifiedDate', '0'), + ('4dd13a79-b70c-4b43-bdba-bacd4e977c1b', 'PreferDisplayName', '1'), + + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'DisplayName', 'Maggie'), + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'LastModifiedDate', '1473723047'), + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'PrimaryEmail', 'maggie@example.com'), + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'PhotoType', 'generic'), + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'LowercasePrimaryEmail', 'maggie@example.com'), + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'PopularityIndex', '0'), + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'PreferMailFormat', '0'), + ('c96402d7-1c7b-4242-a35c-b92c8ec9dfa2', 'PreferDisplayName', '1'), + + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', 'DisplayName', 'simpson'), + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', 'PrimaryEmail', 'simpson'), + ('18204ef9-e4e3-4cd5-9981-604c69bbb9ee', 'DisplayName', 'marge'), + ('18204ef9-e4e3-4cd5-9981-604c69bbb9ee', 'PrimaryEmail', 'marge'), + ('ad305609-3535-4d51-8c96-cd82d93aed46', 'DisplayName', 'family'), + ('ad305609-3535-4d51-8c96-cd82d93aed46', 'PrimaryEmail', 'family'), + ('4808121d-ebad-4564-864d-8f1149aa053b', 'DisplayName', 'kids'), + ('4808121d-ebad-4564-864d-8f1149aa053b', 'PrimaryEmail', 'kids'), + ('4926ff7a-e929-475a-8aa8-2baac994390c', 'DisplayName', 'parents'), + ('4926ff7a-e929-475a-8aa8-2baac994390c', 'PrimaryEmail', 'parents'), + ('84fa4513-9b60-4379-ade7-1e4b48d67c84', 'PrimaryEmail', 'older-kids'), + ('84fa4513-9b60-4379-ade7-1e4b48d67c84', 'DisplayName', 'older-kids'), + ('8e88b9a4-2500-48e0-bcea-b1fa4eab6b72', 'DisplayName', 'bad-kids'), + ('8e88b9a4-2500-48e0-bcea-b1fa4eab6b72', 'PrimaryEmail', 'bad-kids'), + ('34e60324-4fb6-4f10-ab1b-333b07680228', 'DisplayName', 'bad-younger-kids'), + ('34e60324-4fb6-4f10-ab1b-333b07680228', 'PrimaryEmail', 'bad-younger-kids'); + +INSERT INTO lists (uid, localId, name, nickName, description) VALUES + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', 1, 'simpson', '', ''), + ('18204ef9-e4e3-4cd5-9981-604c69bbb9ee', 2, 'marge', '', 'marges own list'), + ('ad305609-3535-4d51-8c96-cd82d93aed46', 3, 'family', '', ''), + ('4808121d-ebad-4564-864d-8f1149aa053b', 4, 'kids', '', ''), + ('4926ff7a-e929-475a-8aa8-2baac994390c', 5, 'parents', '', ''), + ('84fa4513-9b60-4379-ade7-1e4b48d67c84', 6, 'older-kids', '', ''), + ('8e88b9a4-2500-48e0-bcea-b1fa4eab6b72', 7, 'bad-kids', '', ''), + ('34e60324-4fb6-4f10-ab1b-333b07680228', 8, 'bad-younger-kids', '', ''); + +INSERT INTO list_cards (list, card) VALUES + -- simpson + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', '813155c6-924d-4751-95d0-70d8e64f16bc'), -- homer + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', 'b2cc8395-d959-45e4-9516-17457adb16fa'), -- marge + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', '979f194e-49f2-4bbb-b364-598cdc6a7d11'), -- bart + ('5ec12f1d-7ee9-403c-a617-48596dacbc18', '4dd13a79-b70c-4b43-bdba-bacd4e977c1b'), -- lisa + -- marge + ('18204ef9-e4e3-4cd5-9981-604c69bbb9ee', '813155c6-924d-4751-95d0-70d8e64f16bc'), -- homer + ('18204ef9-e4e3-4cd5-9981-604c69bbb9ee', 'b2cc8395-d959-45e4-9516-17457adb16fa'), -- marge + -- family + ('ad305609-3535-4d51-8c96-cd82d93aed46', '4926ff7a-e929-475a-8aa8-2baac994390c'), -- parents + ('ad305609-3535-4d51-8c96-cd82d93aed46', '4808121d-ebad-4564-864d-8f1149aa053b'), -- kids + -- parents + ('4926ff7a-e929-475a-8aa8-2baac994390c', '813155c6-924d-4751-95d0-70d8e64f16bc'), -- homer + ('4926ff7a-e929-475a-8aa8-2baac994390c', 'b2cc8395-d959-45e4-9516-17457adb16fa'), -- marge + ('4926ff7a-e929-475a-8aa8-2baac994390c', '4926ff7a-e929-475a-8aa8-2baac994390c'), -- parents + -- kids + ('4808121d-ebad-4564-864d-8f1149aa053b', '84fa4513-9b60-4379-ade7-1e4b48d67c84'), -- older-kids + ('4808121d-ebad-4564-864d-8f1149aa053b', 'c96402d7-1c7b-4242-a35c-b92c8ec9dfa2'), -- maggie + -- older-kids + ('84fa4513-9b60-4379-ade7-1e4b48d67c84', '4dd13a79-b70c-4b43-bdba-bacd4e977c1b'), -- lisa + ('84fa4513-9b60-4379-ade7-1e4b48d67c84', '979f194e-49f2-4bbb-b364-598cdc6a7d11'), -- bart + -- bad-kids + ('8e88b9a4-2500-48e0-bcea-b1fa4eab6b72', '84fa4513-9b60-4379-ade7-1e4b48d67c84'), -- older-kids + ('8e88b9a4-2500-48e0-bcea-b1fa4eab6b72', '34e60324-4fb6-4f10-ab1b-333b07680228'), -- bad-younger-kids + -- bad-younger-kids + ('34e60324-4fb6-4f10-ab1b-333b07680228', 'c96402d7-1c7b-4242-a35c-b92c8ec9dfa2'), -- maggie + ('34e60324-4fb6-4f10-ab1b-333b07680228', '8e88b9a4-2500-48e0-bcea-b1fa4eab6b72'); -- bad-kids diff --git a/mailnews/compose/test/unit/test_expandMailingLists.js b/mailnews/compose/test/unit/test_expandMailingLists.js index 7ce08c3b9a..4699924078 100644 --- a/mailnews/compose/test/unit/test_expandMailingLists.js +++ b/mailnews/compose/test/unit/test_expandMailingLists.js @@ -44,11 +44,7 @@ function checkPopulate(aTo, aCheckTo) { } function run_test() { - // Test setup - copy the data files into place - let testAB = do_get_file("./data/listexpansion.mab"); - - // Copy the file to the profile directory for a PAB - testAB.copyTo(do_get_profile(), kPABData.fileName); + loadABFile("data/listexpansion", kPABData.fileName); // XXX Getting all directories ensures we create all ABs because mailing // lists need help initialising themselves diff --git a/mailnews/compose/test/unit/test_nsMsgCompose1.js b/mailnews/compose/test/unit/test_nsMsgCompose1.js index dad7d73d4b..1a746516ec 100644 --- a/mailnews/compose/test/unit/test_nsMsgCompose1.js +++ b/mailnews/compose/test/unit/test_nsMsgCompose1.js @@ -43,16 +43,8 @@ function checkPopulate(aTo, aCheckTo) { } function run_test() { - // Test setup - copy the data files into place - var testAB = do_get_file("../../../data/abLists1.mab"); - - // Copy the file to the profile directory for a PAB - testAB.copyTo(do_get_profile(), kPABData.fileName); - - testAB = do_get_file("../../../data/abLists2.mab"); - - // Copy the file to the profile directory for a CAB - testAB.copyTo(do_get_profile(), kCABData.fileName); + loadABFile("../../../data/abLists1", kPABData.fileName); + loadABFile("../../../data/abLists2", kCABData.fileName); // Test - Check we can initialize with fewest specified // parameters and don't fail/crash like we did in bug 411646. diff --git a/mailnews/compose/test/unit/test_nsMsgCompose3.js b/mailnews/compose/test/unit/test_nsMsgCompose3.js index 0a325dca77..71521abff4 100644 --- a/mailnews/compose/test/unit/test_nsMsgCompose3.js +++ b/mailnews/compose/test/unit/test_nsMsgCompose3.js @@ -59,11 +59,7 @@ function checkPopulate(aTo, aCheckTo) { } function run_test() { - // Test setup - copy the data files into place - let testAB = do_get_file("../../../data/tb2hexpopularity.mab"); - - // Copy the file to the profile directory for a PAB - testAB.copyTo(do_get_profile(), kPABData.fileName); + loadABFile("../../../data/tb2hexpopularity", kPABData.fileName); // Check the popularity index on a couple of cards. let AB = MailServices.ab.getDirectory(kPABData.URI); diff --git a/mailnews/compose/test/unit/test_nsMsgCompose4.js b/mailnews/compose/test/unit/test_nsMsgCompose4.js index 0a03ecece4..657cfe87e8 100644 --- a/mailnews/compose/test/unit/test_nsMsgCompose4.js +++ b/mailnews/compose/test/unit/test_nsMsgCompose4.js @@ -44,16 +44,8 @@ function checkPopulate( } function run_test() { - // Test setup - copy the data files into place - var testAB = do_get_file("../../../data/abLists1.mab"); - - // Copy the file to the profile directory for a PAB - testAB.copyTo(do_get_profile(), kPABData.fileName); - - testAB = do_get_file("../../../data/abLists2.mab"); - - // Copy the file to the profile directory for a CAB - testAB.copyTo(do_get_profile(), kCABData.fileName); + loadABFile("../../../data/abLists1", kPABData.fileName); + loadABFile("../../../data/abLists2", kCABData.fileName); // Test - Check we can initialize with fewest specified // parameters and don't fail/crash like we did in bug 411646. diff --git a/mailnews/mailnews.js b/mailnews/mailnews.js index 2d44f13cb3..8da470798e 100644 --- a/mailnews/mailnews.js +++ b/mailnews/mailnews.js @@ -322,14 +322,14 @@ pref("ldap_2.autoComplete.directoryServer", ""); pref("ldap_2.servers.pab.position", 1); pref("ldap_2.servers.pab.description", "chrome://messenger/locale/addressbook/addressBook.properties"); -pref("ldap_2.servers.pab.dirType", 2); -pref("ldap_2.servers.pab.filename", "abook.mab"); +pref("ldap_2.servers.pab.dirType", 101); +pref("ldap_2.servers.pab.filename", "abook.sqlite"); pref("ldap_2.servers.pab.isOffline", false); pref("ldap_2.servers.history.position", 2); pref("ldap_2.servers.history.description", "chrome://messenger/locale/addressbook/addressBook.properties"); -pref("ldap_2.servers.history.dirType", 2); -pref("ldap_2.servers.history.filename", "history.mab"); +pref("ldap_2.servers.history.dirType", 101); +pref("ldap_2.servers.history.filename", "history.sqlite"); pref("ldap_2.servers.history.isOffline", false); // default mapping of addressbook properties to ldap attributes @@ -451,7 +451,7 @@ pref("mail.collect_email_address_newsgroup", false); #endif pref("mail.collect_email_address_outgoing", true); // by default, use the Collected Addressbook for collection -pref("mail.collect_addressbook", "moz-abmdbdirectory://history.mab"); +pref("mail.collect_addressbook", "jsaddrbook://history.sqlite"); pref("mail.default_sendlater_uri", "mailbox://nobody@Local%20Folders/Unsent%20Messages"); @@ -520,7 +520,7 @@ pref("mail.server.default.moveTargetMode", 0); // 0 == "Junk" on server, 1 == sp pref("mail.server.default.spamActionTargetAccount", ""); pref("mail.server.default.spamActionTargetFolder", ""); pref("mail.server.default.useWhiteList", true); -pref("mail.server.default.whiteListAbURI", "moz-abmdbdirectory://abook.mab"); // the Personal addressbook. +pref("mail.server.default.whiteListAbURI", "jsaddrbook://abook.sqlite"); // the Personal addressbook. pref("mail.server.default.useServerFilter", false); pref("mail.server.default.serverFilterName", "SpamAssassin"); pref("mail.server.default.serverFilterTrustFlags", 1); // 1 == trust positives, 2 == trust negatives, 3 == trust both diff --git a/mailnews/test/data/abLists1.sql b/mailnews/test/data/abLists1.sql index fa19a9e421..77963da29e 100644 --- a/mailnews/test/data/abLists1.sql +++ b/mailnews/test/data/abLists1.sql @@ -1,3 +1,4 @@ +-- Address book data for use in various tests. PRAGMA user_version = 1; CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER); @@ -58,4 +59,4 @@ INSERT INTO list_cards (list, card) VALUES ('98636844-ed9c-4ac1-98ac-de7989a93615', 'ce1bd5ad-17e7-4a1b-a51e-fbce76556ebd'), ('98636844-ed9c-4ac1-98ac-de7989a93615', 'caaadb6c-425d-40e3-8f19-72546f6b01d8'), ('31c44c28-450f-44d6-ba39-71cae90fac21', '23acb230-f0d9-4348-a7be-1242cd579631'), - ('31c44c28-450f-44d6-ba39-71cae90fac21', '02cf43d5-e5b8-48b4-9546-1bb509cd998f'); + ('46cf4cbf-5945-43e4-a822-30c2f2969db9', '02cf43d5-e5b8-48b4-9546-1bb509cd998f'); diff --git a/mailnews/test/data/abLists2.sql b/mailnews/test/data/abLists2.sql new file mode 100644 index 0000000000..f37d1a1cda --- /dev/null +++ b/mailnews/test/data/abLists2.sql @@ -0,0 +1,62 @@ +-- Address book data for use in various tests. +PRAGMA user_version = 1; + +CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER); +CREATE TABLE properties (card TEXT, name TEXT, value TEXT); +CREATE TABLE lists (uid TEXT PRIMARY KEY, localId INTEGER, name TEXT, nickName TEXT, description TEXT); +CREATE TABLE list_cards (list TEXT, card TEXT, PRIMARY KEY(list, card)); + +INSERT INTO cards (uid, localId) VALUES + ('420a2534-7e35-45e3-88b1-104e92608faa', 1), + ('3291e9a7-cbd9-4146-9c4e-e1afe5e25085', 2), + ('fcc46367-7081-487d-bbd3-f8f8e03e5262', 3), + ('e62f6ec2-8248-478e-8f6d-e31cdbeda4b8', 4), + ('4bc4f8c2-66d4-4421-a7b4-4be9d8be8614', 5); + +INSERT INTO properties (card, name, value) VALUES + ('420a2534-7e35-45e3-88b1-104e92608faa', 'PrimaryEmail', 'test1@com.invalid'), + ('420a2534-7e35-45e3-88b1-104e92608faa', 'LowercasePrimaryEmail', 'test1@com.invalid'), + ('420a2534-7e35-45e3-88b1-104e92608faa', 'PreferMailFormat', '0'), + ('420a2534-7e35-45e3-88b1-104e92608faa', 'PopularityIndex', '0'), + ('420a2534-7e35-45e3-88b1-104e92608faa', 'AllowRemoteContent', '0'), + ('420a2534-7e35-45e3-88b1-104e92608faa', 'LastModifiedDate', '0'), + + ('3291e9a7-cbd9-4146-9c4e-e1afe5e25085', 'PrimaryEmail', 'test2@com.invalid'), + ('3291e9a7-cbd9-4146-9c4e-e1afe5e25085', 'LowercasePrimaryEmail', 'test2@com.invalid'), + ('3291e9a7-cbd9-4146-9c4e-e1afe5e25085', 'PreferMailFormat', '0'), + ('3291e9a7-cbd9-4146-9c4e-e1afe5e25085', 'PopularityIndex', '0'), + ('3291e9a7-cbd9-4146-9c4e-e1afe5e25085', 'AllowRemoteContent', '0'), + ('3291e9a7-cbd9-4146-9c4e-e1afe5e25085', 'LastModifiedDate', '0'), + + ('fcc46367-7081-487d-bbd3-f8f8e03e5262', 'PrimaryEmail', 'test3@com.invalid'), + ('fcc46367-7081-487d-bbd3-f8f8e03e5262', 'LowercasePrimaryEmail', 'test3@com.invalid'), + ('fcc46367-7081-487d-bbd3-f8f8e03e5262', 'PreferMailFormat', '0'), + ('fcc46367-7081-487d-bbd3-f8f8e03e5262', 'PopularityIndex', '0'), + ('fcc46367-7081-487d-bbd3-f8f8e03e5262', 'AllowRemoteContent', '0'), + ('fcc46367-7081-487d-bbd3-f8f8e03e5262', 'LastModifiedDate', '0'), + + ('e62f6ec2-8248-478e-8f6d-e31cdbeda4b8', 'PrimaryEmail', 'test4@com.invalid'), + ('e62f6ec2-8248-478e-8f6d-e31cdbeda4b8', 'LowercasePrimaryEmail', 'test4@com.invalid'), + ('e62f6ec2-8248-478e-8f6d-e31cdbeda4b8', 'PreferMailFormat', '1'), + ('e62f6ec2-8248-478e-8f6d-e31cdbeda4b8', 'PopularityIndex', '0'), + ('e62f6ec2-8248-478e-8f6d-e31cdbeda4b8', 'AllowRemoteContent', '0'), + ('e62f6ec2-8248-478e-8f6d-e31cdbeda4b8', 'LastModifiedDate', '0'), + + ('4bc4f8c2-66d4-4421-a7b4-4be9d8be8614', 'PrimaryEmail', 'test5@com.invalid'), + ('4bc4f8c2-66d4-4421-a7b4-4be9d8be8614', 'LowercasePrimaryEmail', 'test5@com.invalid'), + ('4bc4f8c2-66d4-4421-a7b4-4be9d8be8614', 'PreferMailFormat', '2'), + ('4bc4f8c2-66d4-4421-a7b4-4be9d8be8614', 'PopularityIndex', '0'), + ('4bc4f8c2-66d4-4421-a7b4-4be9d8be8614', 'AllowRemoteContent', '0'), + ('4bc4f8c2-66d4-4421-a7b4-4be9d8be8614', 'LastModifiedDate', '0'); + +INSERT INTO lists (uid, localId, name, nickName, description) VALUES + ('df79d3c0-5976-4279-851c-a8814f17ef30', 1, 'ListTest1', '', ''), + ('cad38149-925a-4159-8c34-20ac74ae7a17', 2, 'ListTest2', '', ''), + ('c069dd7a-408f-4440-9fc0-67643fbe5777', 3, 'ListTest3', '', ''); + +INSERT INTO list_cards (list, card) VALUES + ('df79d3c0-5976-4279-851c-a8814f17ef30', '420a2534-7e35-45e3-88b1-104e92608faa'), + ('df79d3c0-5976-4279-851c-a8814f17ef30', '3291e9a7-cbd9-4146-9c4e-e1afe5e25085'), + ('df79d3c0-5976-4279-851c-a8814f17ef30', 'fcc46367-7081-487d-bbd3-f8f8e03e5262'), + ('cad38149-925a-4159-8c34-20ac74ae7a17', 'e62f6ec2-8248-478e-8f6d-e31cdbeda4b8'), + ('c069dd7a-408f-4440-9fc0-67643fbe5777', '4bc4f8c2-66d4-4421-a7b4-4be9d8be8614'); diff --git a/mailnews/test/data/tb2hexpopularity.sql b/mailnews/test/data/tb2hexpopularity.sql index 576d5ef2ca..2ab6bd2c68 100644 --- a/mailnews/test/data/tb2hexpopularity.sql +++ b/mailnews/test/data/tb2hexpopularity.sql @@ -1,3 +1,4 @@ +-- Address book data for use in various tests. PRAGMA user_version = 1; CREATE TABLE cards (uid TEXT PRIMARY KEY, localId INTEGER); diff --git a/mailnews/test/resources/abSetup.js b/mailnews/test/resources/abSetup.js index 6b9dd51fde..24a1cd31c5 100644 --- a/mailnews/test/resources/abSetup.js +++ b/mailnews/test/resources/abSetup.js @@ -19,10 +19,10 @@ var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); // Personal Address Book configuration items. var kPABData = { - URI: "moz-abmdbdirectory://abook.mab", - fileName: "abook.mab", + URI: "jsaddrbook://abook.sqlite", + fileName: "abook.sqlite", dirName: "Personal Address Book", - dirType: 2, + dirType: 101, dirPrefID: "ldap_2.servers.pab", readOnly: false, position: 1, @@ -30,10 +30,10 @@ var kPABData = { // Collected Address Book configuration items. var kCABData = { - URI: "moz-abmdbdirectory://history.mab", - fileName: "history.mab", + URI: "jsaddrbook://history.sqlite", + fileName: "history.sqlite", dirName: "Collected Addresses", - dirType: 2, + dirType: 101, dirPrefID: "ldap_2.servers.history", readOnly: false, position: 2, @@ -48,3 +48,41 @@ Services.prefs.deleteBranch("ldap_2.servers.osx."); // This currently applies to all address books of local type. var kNormalPropertiesURI = "chrome://messenger/content/addressbook/abAddressBookNameDialog.xul"; + +/** + * Installs a pre-prepared address book file into the profile directory. + * This version is for JS/SQLite address books, if you create a new type, + * replace this function to test them. + * + * @param {String} source Path to the source data, without extension + * @param {String} dest Final file name in the profile, with extension + */ +function loadABFile(source, dest) { + let sourceFile = do_get_file(`${source}.sql`); + let destFile = do_get_profile(); + destFile.append(dest); + + info(`Creating ${destFile.path} from ${sourceFile.path}`); + + let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance( + Ci.nsIConverterInputStream + ); + fstream.init(sourceFile, -1, 0, 0); + cstream.init(fstream, "UTF-8", 0, 0); + + let data = ""; + let read = 0; + do { + let str = {}; + read = cstream.readString(0xffffffff, str); + data += str.value; + } while (read != 0); + cstream.close(); + + let conn = Services.storage.openDatabase(destFile); + conn.executeSimpleSQL(data); + conn.close(); +}