From cebb5834eb4c928843949bc70e4a5129b7f9da80 Mon Sep 17 00:00:00 2001 From: John Bieling Date: Thu, 6 Jun 2019 18:27:02 +0200 Subject: [PATCH] Bug 1555294 - Adding addrbook-list-member-removed observer notification (test by darktrojan). r=mkmelin --- mailnews/addrbook/src/nsAddrDatabase.cpp | 56 ++++++++++++--- mailnews/addrbook/src/nsAddrDatabase.h | 5 +- .../addrbook/test/unit/test_notifications.js | 70 ++++++++++++++++++- 3 files changed, 117 insertions(+), 14 deletions(-) diff --git a/mailnews/addrbook/src/nsAddrDatabase.cpp b/mailnews/addrbook/src/nsAddrDatabase.cpp index ca04bc4fd0..743509aa51 100644 --- a/mailnews/addrbook/src/nsAddrDatabase.cpp +++ b/mailnews/addrbook/src/nsAddrDatabase.cpp @@ -1436,9 +1436,15 @@ NS_IMETHODIMP nsAddrDatabase::CreateMailListAndAddToDB( return NS_ERROR_FAILURE; } -void nsAddrDatabase::DeleteCardFromAllMailLists(mdb_id cardRowID) { +void nsAddrDatabase::DeleteCardFromAllMailLists(nsIAbCard *aCard) { if (!m_mdbEnv) return; + mdb_id cardRowID; + nsresult rv = aCard->GetPropertyAsUint32(kRowIDProperty, &cardRowID); + if (NS_FAILED(rv)) { + return; + } + nsCOMPtr rowCursor; m_mdbPabTable->GetTableRowCursor(m_mdbEnv, -1, getter_AddRefs(rowCursor)); @@ -1446,15 +1452,28 @@ void nsAddrDatabase::DeleteCardFromAllMailLists(mdb_id cardRowID) { nsCOMPtr pListRow; mdb_pos rowPos; do { - nsresult err = - rowCursor->NextRow(m_mdbEnv, getter_AddRefs(pListRow), &rowPos); + rv = rowCursor->NextRow(m_mdbEnv, getter_AddRefs(pListRow), &rowPos); - if (NS_SUCCEEDED(err) && pListRow) { + if (NS_SUCCEEDED(rv) && pListRow) { mdbOid rowOid; if (NS_SUCCEEDED(pListRow->GetOid(m_mdbEnv, &rowOid))) { - if (IsListRowScopeToken(rowOid.mOid_Scope)) - DeleteCardFromListRow(pListRow, cardRowID); + if (IsListRowScopeToken(rowOid.mOid_Scope)) { + bool cardFound = false; + DeleteCardFromListRow(pListRow, cardRowID, &cardFound); + if (cardFound) { + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + nsAutoString listUID; + GetStringColumn(pListRow, m_UIDColumnToken, listUID); + if (!listUID.IsEmpty()) { + observerService->NotifyObservers( + aCard, "addrbook-list-member-removed", listUID.get()); + } + } + } + } } } } while (pListRow); @@ -1483,6 +1502,9 @@ NS_IMETHODIMP nsAddrDatabase::DeleteCard(nsIAbCard *aCard, bool aNotify, NS_ENSURE_SUCCESS(err, err); if (!pCardRow) return NS_OK; + // Delete the person card from all mailing list. + if (!bIsMailList) DeleteCardFromAllMailLists(aCard); + // Reset the directory id aCard->SetDirectoryId(EmptyCString()); @@ -1505,9 +1527,6 @@ NS_IMETHODIMP nsAddrDatabase::DeleteCard(nsIAbCard *aCard, bool aNotify, err = DeleteRow(m_mdbPabTable, pCardRow); - // delete the person card from all mailing list - if (!bIsMailList) DeleteCardFromAllMailLists(rowOid.mOid_Id); - if (NS_SUCCEEDED(err)) { if (aNotify) NotifyCardEntryChange(AB_NotifyDeleted, aCard, aParent); } @@ -1517,7 +1536,8 @@ NS_IMETHODIMP nsAddrDatabase::DeleteCard(nsIAbCard *aCard, bool aNotify, } nsresult nsAddrDatabase::DeleteCardFromListRow(nsIMdbRow *pListRow, - mdb_id cardRowID) { + mdb_id cardRowID, + bool *cardFound) { NS_ENSURE_ARG_POINTER(pListRow); if (!m_mdbStore || !m_mdbEnv) return NS_ERROR_NULL_POINTER; @@ -1537,6 +1557,7 @@ nsresult nsAddrDatabase::DeleteCardFromListRow(nsIMdbRow *pListRow, err = GetIntColumn(pListRow, listAddressColumnToken, (uint32_t *)&rowID, 0); if (cardRowID == rowID) { + *cardFound = true; if (pos == totalAddress) err = pListRow->CutColumn(m_mdbEnv, listAddressColumnToken); else { @@ -1594,9 +1615,22 @@ NS_IMETHODIMP nsAddrDatabase::DeleteCardFromMailList(nsIAbDirectory *mailList, err = card->GetPropertyAsUint32(kRowIDProperty, &cardRowID); if (NS_FAILED(err)) return NS_ERROR_NULL_POINTER; - err = DeleteCardFromListRow(pListRow, cardRowID); + bool cardFound = false; + err = DeleteCardFromListRow(pListRow, cardRowID, &cardFound); if (NS_SUCCEEDED(err) && aNotify) { NotifyCardEntryChange(AB_NotifyDeleted, card, mailList); + // Notify the addrbook-list-member-removed observer if the card was found + // and removed. + if (cardFound) { + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + nsAutoCString listUID; + mailList->GetUID(listUID); + observerService->NotifyObservers(card, "addrbook-list-member-removed", + NS_ConvertUTF8toUTF16(listUID).get()); + } + } } NS_RELEASE(pListRow); return NS_OK; diff --git a/mailnews/addrbook/src/nsAddrDatabase.h b/mailnews/addrbook/src/nsAddrDatabase.h index 5651a429c9..899c68eaad 100644 --- a/mailnews/addrbook/src/nsAddrDatabase.h +++ b/mailnews/addrbook/src/nsAddrDatabase.h @@ -388,8 +388,9 @@ class nsAddrDatabase : public nsIAddrDatabase { nsresult CreateCard(nsIMdbRow *cardRow, mdb_id listRowID, nsIAbCard **result); nsresult CreateCardFromDeletedCardsTable(nsIMdbRow *cardRow, mdb_id listRowID, nsIAbCard **result); - nsresult DeleteCardFromListRow(nsIMdbRow *pListRow, mdb_id cardRowID); - void DeleteCardFromAllMailLists(mdb_id cardRowID); + nsresult DeleteCardFromListRow(nsIMdbRow *pListRow, mdb_id cardRowID, + bool *cardFound); + void DeleteCardFromAllMailLists(nsIAbCard *aCard); nsresult NotifyListEntryChange(uint32_t abCode, nsIAbDirectory *dir); nsresult AddLowercaseColumn(nsIMdbRow *row, mdb_token columnToken, diff --git a/mailnews/addrbook/test/unit/test_notifications.js b/mailnews/addrbook/test/unit/test_notifications.js index 4b741cb8f5..229c931b87 100644 --- a/mailnews/addrbook/test/unit/test_notifications.js +++ b/mailnews/addrbook/test/unit/test_notifications.js @@ -25,11 +25,24 @@ var abListener = { }, }; +var abObserver = { + result: [], + maxResults: 1, + observe(subject, topic, data) { + Assert.ok(this.result.length < this.maxResults); + this.result.push([subject, topic, data]); + }, +}; + function run_test() { // XXX Getting all directories ensures we create all ABs because the // address collecter can't currently create ABs itself (bug 314448). MailServices.ab.directories; + run_next_test(); +} + +add_test(function() { // Add a listener MailServices.ab.addAddressBookListener(abListener, Ci.nsIAbListener.all); @@ -147,4 +160,59 @@ function run_test() { // Remove listener MailServices.ab.removeAddressBookListener(abListener); -} + + run_next_test(); +}); + +add_test(function() { + let dirName = MailServices.ab.newAddressBook("TestBook", "", kPABData.dirType); + let AB = MailServices.ab.getDirectoryFromId(dirName); + + let mailList = Cc["@mozilla.org/addressbook/directoryproperty;1"] + .createInstance(Ci.nsIAbDirectory); + mailList.isMailList = true; + mailList.dirName = "TestList"; + mailList = AB.addMailList(mailList); + + let card1 = Cc["@mozilla.org/addressbook/cardproperty;1"] + .createInstance(Ci.nsIAbCard); + card1.firstName = "test1"; + card1.primaryEmail = "test1@foo.invalid"; + card1 = AB.addCard(card1); + + let card2 = Cc["@mozilla.org/addressbook/cardproperty;1"] + .createInstance(Ci.nsIAbCard); + card2.firstName = "test2"; + card2.primaryEmail = "test2@foo.invalid"; + card2 = AB.addCard(card2); + mailList.addCard(card2); + + // Test: remove one card that ISN'T in the mailing list + + Services.obs.addObserver(abObserver, "addrbook-list-member-removed"); + abObserver.maxResults = 0; + abObserver.result = []; + + let cardsToDelete = Cc["@mozilla.org/array;1"] + .createInstance(Ci.nsIMutableArray); + cardsToDelete.appendElement(card1); + AB.deleteCards(cardsToDelete); + + // Test: remove one card that IS in the mailing list + + abObserver.maxResults = 1; + abObserver.result = []; + + cardsToDelete.clear(); + cardsToDelete.appendElement(card2); + AB.deleteCards(cardsToDelete); + + Assert.equal(abObserver.result.length, 1); + Assert.equal(abObserver.result[0][0], card2); + Assert.equal(abObserver.result[0][1], "addrbook-list-member-removed"); + Assert.equal(abObserver.result[0][2], mailList.UID); + + Services.obs.removeObserver(abObserver, "addrbook-list-member-removed"); + + run_next_test(); +});