From 6c0a79eb50deadceeffed1918bb60e19671eba05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Fri, 11 May 2018 10:56:40 -0400
Subject: [PATCH] conversationmodel: update lastMessageUid when removing last
 interaction

Actually, conversation.lastMessageUid still has the removed last
interaction uid. If this interaction is removed, this attribute must
be updated.

+ Add a unit test

Change-Id: Icfce0a54d7a88fdf71469127392460048f491ba8
Reviewed-by: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
---
 src/conversationmodel.cpp        | 17 +++++++++-
 test/conversationmodeltester.cpp | 53 ++++++++++++++++++++++++++++++++
 test/conversationmodeltester.h   |  6 ++++
 3 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp
index ac38251e..5e2b3748 100644
--- a/src/conversationmodel.cpp
+++ b/src/conversationmodel.cpp
@@ -725,20 +725,35 @@ ConversationModel::clearInteractionFromConversation(const std::string& convId, c
         return;
 
     auto erased_keys = 0;
+    bool lastInteractionUpdated = false;
     {
         std::lock_guard<std::mutex> lk(pimpl_->interactionsLocks[convId]);
         try
         {
             auto& conversation = pimpl_->conversations.at(conversationIdx);
             database::clearInteractionFromConversation(pimpl_->db, convId, interactionId);
-
             erased_keys = conversation.interactions.erase(interactionId);
+
+            if (conversation.lastMessageUid == interactionId) {
+                // Update lastMessageUid
+                auto newLastId = 0;
+                if (!conversation.interactions.empty())
+                    newLastId = conversation.interactions.rbegin()->first;
+                conversation.lastMessageUid = newLastId;
+                lastInteractionUpdated = true;
+            }
+
         } catch (const std::out_of_range& e) {
             qDebug() << "can't clear interaction from conversation: " << e.what();
         }
     }
     if (erased_keys > 0)
         emit interactionRemoved(convId, interactionId);
+    if (lastInteractionUpdated) {
+        // last interaction as changed, so the order can changes.
+        pimpl_->sortConversations();
+        emit modelSorted();
+    }
 }
 
 void
diff --git a/test/conversationmodeltester.cpp b/test/conversationmodeltester.cpp
index 336b8fcc..81216a86 100644
--- a/test/conversationmodeltester.cpp
+++ b/test/conversationmodeltester.cpp
@@ -410,6 +410,59 @@ ConversationModelTester::testSendMessagesAndClearInteraction()
     CPPUNIT_ASSERT(conversationExists);
 }
 
+void
+ConversationModelTester::testSendMessagesAndClearLastInteraction()
+{
+    accInfo_.conversationModel->setFilter("");
+    auto conversations = accInfo_.conversationModel->allFilteredConversations();
+    CPPUNIT_ASSERT(conversations.size() != 0);
+    auto firstConversation = accInfo_.conversationModel->filteredConversation(0);
+    auto firstConversationUid = firstConversation.uid;
+
+    // HACK reinit the conversation here (without these line, Hello World! will not be in interactions)
+    // FIXME
+    accInfo_.conversationModel->clearHistory(firstConversationUid);
+    firstConversation = accInfo_.conversationModel->filteredConversation(0);
+
+    // Send 3 messages (will be added to conversation.interactions)
+    int baseInteractionsSize = firstConversation.interactions.size();
+    accInfo_.conversationModel->sendMessage(firstConversationUid, "Hello World!");
+    accInfo_.conversationModel->sendMessage(firstConversationUid, "It's been a long time");
+    accInfo_.conversationModel->sendMessage(firstConversationUid, "How have you been?");
+
+    conversations = accInfo_.conversationModel->allFilteredConversations();
+    auto conversationExists = false;
+    uint64_t lastInteractionId = {};
+    uint64_t secondInterId = {};
+    for (const auto& conversation : conversations) {
+        if (conversation.uid == firstConversationUid) {
+            conversationExists = true;
+            CPPUNIT_ASSERT_EQUAL((int)conversation.interactions.size(), baseInteractionsSize + 3);
+            auto it = conversation.interactions.rbegin();
+            lastInteractionId = it->first;
+            it++;
+            secondInterId = it->first;
+            break;
+        }
+    }
+    CPPUNIT_ASSERT(conversationExists);
+
+    accInfo_.conversationModel->clearInteractionFromConversation(firstConversationUid, lastInteractionId);
+    WaitForSignalHelper(*accInfo_.conversationModel,
+        SIGNAL(interactionRemoved(const std::string& convUid, uint64_t interactionId))).wait(1000);
+    conversations = accInfo_.conversationModel->allFilteredConversations();
+    conversationExists = false;
+    for (const auto& conversation : conversations) {
+        if (conversation.uid == firstConversationUid) {
+            conversationExists = true;
+            // lastMessageUid should be equals to the new last interaction's id.
+            CPPUNIT_ASSERT_EQUAL(conversation.lastMessageUid, secondInterId);
+            break;
+        }
+    }
+    CPPUNIT_ASSERT(conversationExists);
+}
+
 void
 ConversationModelTester::testReceiveMessageAndSetRead()
 {
diff --git a/test/conversationmodeltester.h b/test/conversationmodeltester.h
index 2aac71ff..2bab3ee1 100644
--- a/test/conversationmodeltester.h
+++ b/test/conversationmodeltester.h
@@ -47,6 +47,7 @@ class ConversationModelTester :  public CppUnit::TestFixture {
     CPPUNIT_TEST(testFilterAndGetConversations);
     CPPUNIT_TEST(testSendMessageAndClearHistory);
     CPPUNIT_TEST(testSendMessagesAndClearInteraction);
+    CPPUNIT_TEST(testSendMessagesAndClearLastInteraction);
     CPPUNIT_TEST(testReceiveMessageAndSetRead);
     CPPUNIT_TEST(testPlaceCall);
     CPPUNIT_TEST(testCreateConference);
@@ -99,6 +100,11 @@ public:
      * Send multiple messages to the first conversation and clear one interaction
      */
     void testSendMessagesAndClearInteraction();
+    /**
+     * Send multiple messages to the first conversation and clear the last interaction
+     * lastMessageUid should be updated
+     */
+    void testSendMessagesAndClearLastInteraction();
     /**
      * Receives a message from a conversation and set this message READ
      */
-- 
GitLab