Bug 1520737 - Ensure UID property is persistent for mailing list cards; r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Tue, 22 Jan 2019 17:09:03 +1300
changeset 33410 9945bbe9adaf
parent 33409 21ddeb46254b
child 33411 ab66eaf0f575
push id2368
push userclokep@gmail.com
push dateMon, 28 Jan 2019 21:12:50 +0000
treeherdercomm-beta@56d23c07d815 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1520737
Bug 1520737 - Ensure UID property is persistent for mailing list cards; r=mkmelin
mailnews/addrbook/src/nsAbDirProperty.cpp
mailnews/addrbook/src/nsAbMDBDirectory.cpp
mailnews/addrbook/test/unit/test_uid.js
--- a/mailnews/addrbook/src/nsAbDirProperty.cpp
+++ b/mailnews/addrbook/src/nsAbDirProperty.cpp
@@ -277,16 +277,20 @@ NS_IMETHODIMP nsAbDirProperty::CopyMailL
   nsString str;
   srcList->GetDirName(str);
   SetDirName(str);
   srcList->GetListNickName(str);
   SetListNickName(str);
   srcList->GetDescription(str);
   SetDescription(str);
 
+  nsAutoCString uid;
+  srcList->GetUID(uid);
+  SetUID(uid);
+
   nsCOMPtr<nsIMutableArray> pAddressLists;
   srcList->GetAddressLists(getter_AddRefs(pAddressLists));
   SetAddressLists(pAddressLists);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAbDirProperty::GetIsQuery(bool *aResult)
 {
--- a/mailnews/addrbook/src/nsAbMDBDirectory.cpp
+++ b/mailnews/addrbook/src/nsAbMDBDirectory.cpp
@@ -692,16 +692,41 @@ NS_IMETHODIMP nsAbMDBDirectory::ModifyCa
   {
     rv = GetAbDatabase();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   rv = mDatabase->EditCard(aModifiedCard, true, this);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // If it's a mailing list's card, ensure the related nsIAbDirectory has the same UID.
+  bool isMailList;
+  rv = aModifiedCard->GetIsMailList(&isMailList);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (isMailList)
+  {
+    nsCOMPtr<nsIAbManager> abManager = do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsAutoCString uri;
+    rv = aModifiedCard->GetMailListURI(getter_Copies(uri));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIAbDirectory> directory;
+    rv = abManager->GetDirectory(uri, getter_AddRefs(directory));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsAutoCString uid;
+    rv = aModifiedCard->GetUID(uid);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    rv = directory->SetUID(uid);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
   if (observerService) {
     nsAutoCString thisUID;
     this->GetUID(thisUID);
     observerService->NotifyObservers(aModifiedCard, "addrbook-contact-updated", NS_ConvertUTF8toUTF16(thisUID).get());
   }
 
   return mDatabase->Commit(nsAddrDBCommitType::kLargeCommit);
--- a/mailnews/addrbook/test/unit/test_uid.js
+++ b/mailnews/addrbook/test/unit/test_uid.js
@@ -1,91 +1,121 @@
 /*
  * Test to check that pre-existing cards are given a UID,
  * and that the UID remains the same after a shutdown.
  */
 Cu.importGlobalProperties(["fetch"]);
 
 var profD = do_get_profile();
 
-// Installs an address book with some existing objects.
-function run_test() {
-  let testAB = do_get_file("data/existing.mab");
-  testAB.copyTo(profD, kPABData.fileName);
-
-  run_next_test();
-}
-
 // Tests that directories have UIDs.
 add_test(function directoryUID() {
+  newAddressBookFile();
+
   for (let book of MailServices.ab.directories) {
     equal(36, book.UID.length, "Existing directory has a UID");
   }
 
   let dirName = MailServices.ab.newAddressBook("test", "", kPABData.dirType);
   let directory = MailServices.ab.getDirectoryFromId(dirName);
   equal(36, directory.UID.length, "New directory has a UID");
 
   run_next_test();
 });
 
 // Tests that an existing contact has a UID generated, and that that UID is
 // saved to the database so that the same UID is used next time.
 add_task(async function existingContactUID() {
-  let book = MailServices.ab.getDirectory(kPABData.URI);
-  let bookCards = [...book.childCards];
-  equal(2, bookCards.length, "Loaded test address book");
+  let book = newAddressBookFile();
 
-  let card = bookCards[0];
-  if (card.isMailList) {
-    card = bookCards[1];
-  }
+  let card = [...book.childCards].find(c => !c.isMailList);
   equal(36, card.UID.length, "Existing contact has a UID");
 
   let existingUID = card.UID;
-  bookCards = [...book.childCards];
-  card = bookCards[0];
-  if (card.isMailList) {
-    card = bookCards[1];
-  }
+  card = [...book.childCards].find(c => !c.isMailList);
   equal(existingUID, card.UID, "New reference to contact has the same UID");
 
-  let abFile = profD.clone();
-  abFile.append(kPABData.fileName);
-  let response = await fetch(Services.io.newFileURI(abFile).spec);
-  let text = await response.text();
-
-  ok(text.includes(card.UID), "UID has been saved to file");
+  await checkFileForUID(card.UID, book.fileName);
 });
 
 // Tests that new contacts have UIDs. Do this test last so we don't muck up
 // the others by adding new things to the address book.
-add_test(function newContactUID() {
-  let book = MailServices.ab.getDirectory(kPABData.URI);
+add_task(async function newContactUID() {
+  let book = newAddressBookFile();
+
   let contact = Cc["@mozilla.org/addressbook/cardproperty;1"].createInstance(Ci.nsIAbCard);
   let newContact = book.addCard(contact);
   equal(36, newContact.UID.length, "New contact has a UID");
 
-  run_next_test();
+  await checkFileForUID(newContact.UID, book.fileName);
+});
+
+// Tests that existing lists have UIDs. Reference the nsIAbCard first.
+add_task(async function existingListUID1() {
+  let book = newAddressBookFile();
+
+  let card = [...book.childCards].find(c => c.isMailList);
+  equal(36, card.UID.length, "Existing list's card has a UID");
+
+  let directory = MailServices.ab.getDirectory(card.mailListURI);
+  equal(36, directory.UID.length, "Existing list's directory has a UID");
+
+  equal(card.UID, directory.UID, "Existing list's card and directory UIDs match");
+
+  await checkFileForUID(card.UID, book.fileName);
+});
+
+// Tests that existing lists have UIDs. Reference the nsIAbDirectory first.
+add_task(async function existingListUID2() {
+  let book = newAddressBookFile();
+
+  let directory = MailServices.ab.getDirectory(`${book.URI}/MailList1`);
+  equal(36, directory.UID.length, "Existing list's directory has a UID");
+
+  let card = [...book.childCards].find(c => c.isMailList);
+  equal(36, card.UID.length, "Existing list's card has a UID");
+
+  equal(card.UID, directory.UID, "Existing list's card and directory UIDs match");
+
+  await checkFileForUID(card.UID, book.fileName);
 });
 
 // Tests that new lists have UIDs.
-add_test(function listUID() {
-  let book = MailServices.ab.getDirectory(kPABData.URI);
-  let lists = book.addressLists;
-  equal(1, lists.length);
+add_task(async function newListUID() {
+  let book = newAddressBookFile();
+
+  let list = Cc["@mozilla.org/addressbook/directoryproperty;1"].createInstance(Ci.nsIAbDirectory);
+  list = book.addMailList(list);
+
+  equal(36, list.UID.length, "New list's directory has a UID");
+  equal(list.UID, MailServices.ab.getDirectory(list.URI).UID, "New reference to list's directory has the same UID");
 
-  let directory = lists.GetElementAt(0);
-  directory.QueryInterface(Ci.nsIAbDirectory);
-  equal(36, directory.UID.length, "Existing list's directory has a UID");
+  let bookCards = [...book.childNodes];
+  ok(!!bookCards.find(c => c.UID == list.UID, "New reference to list has the same UID"));
+
+  await checkFileForUID(list.UID, book.fileName);
+});
+
+// 3 seems to be the lowest number that works here. I don't know why.
+var count = 3;
+function newAddressBookFile() {
+  let foo = MailServices.ab.newAddressBook(`book${count}`, `moz-abmdbdirectory://abook-${count}.mab`, 2);
 
-  let list = Cc["@mozilla.org/addressbook/directoryproperty;1"].createInstance();
-  list.QueryInterface(Ci.nsIAbDirectory);
-  list.isMailList = true;
-  book.addMailList(list);
-  equal(2, lists.length);
+  let testAB = do_get_file("data/existing.mab");
+  testAB.copyTo(profD, `abook-${count}.mab`);
+
+  Services.prefs.setCharPref(`ldap_2.servers.book${count}.filename`, `abook-${count}.mab`);
+
+  let book = MailServices.ab.getDirectory(`moz-abmdbdirectory://abook-${count}.mab`);
+  equal(2, [...book.childCards].length);
 
-  let newDirectory = lists.GetElementAt(1);
-  newDirectory.QueryInterface(Ci.nsIAbDirectory);
-  equal(36, newDirectory.UID.length, "New list's directory has a UID");
+  count++;
+  return book;
+}
 
-  run_next_test();
-});
+async function checkFileForUID(needle, bookFileName) {
+  let abFile = profD.clone();
+  abFile.append(bookFileName);
+  let response = await fetch(Services.io.newFileURI(abFile).spec);
+  let text = await response.text();
+
+  ok(text.includes(needle), "UID has been saved to file");
+}