From eb628406188ff8c96c0116c092cd68d18f6e39a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Thu, 15 Jun 2023 13:59:28 -0400
Subject: [PATCH] conversation_module: loadConversations should set removing
 flag

This fix the error "No conversation detected for..."

Change-Id: I95769b89ceac6c03bc8abab87978e154500a6319
---
 src/jamidht/conversation_module.cpp         |  4 ++
 test/unitTest/conversation/conversation.cpp | 65 +++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/src/jamidht/conversation_module.cpp b/src/jamidht/conversation_module.cpp
index 59175593d9..81f8343ece 100644
--- a/src/jamidht/conversation_module.cpp
+++ b/src/jamidht/conversation_module.cpp
@@ -1173,6 +1173,10 @@ ConversationModule::loadConversations()
                 info.members = std::move(members);
                 info.lastDisplayed = conv->infos()[ConversationMapKeys::LAST_DISPLAYED];
                 addConvInfo(info);
+            } else if (convInfo->second.removed) {
+                // A conversation was removed, but repository still exists
+                conv->setRemovingFlag();
+                toRm.insert(repository);
             }
             auto commits = conv->refreshActiveCalls();
             if (!commits.empty()) {
diff --git a/test/unitTest/conversation/conversation.cpp b/test/unitTest/conversation/conversation.cpp
index ad0cbe052e..b9cd39146c 100644
--- a/test/unitTest/conversation/conversation.cpp
+++ b/test/unitTest/conversation/conversation.cpp
@@ -127,6 +127,7 @@ private:
     void testRemoveOneToOneNotInDetails();
     void testMessageEdition();
     void testMessageReaction();
+    void testLoadPartiallyRemovedConversation();
 
     CPPUNIT_TEST_SUITE(ConversationTest);
     CPPUNIT_TEST(testCreateConversation);
@@ -179,6 +180,7 @@ private:
     CPPUNIT_TEST(testRemoveOneToOneNotInDetails);
     CPPUNIT_TEST(testMessageEdition);
     CPPUNIT_TEST(testMessageReaction);
+    CPPUNIT_TEST(testLoadPartiallyRemovedConversation);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -3967,6 +3969,69 @@ ConversationTest::testMessageReaction()
     CPPUNIT_ASSERT(messageAliceReceived.rbegin()->at("body") == "👋");
 }
 
+void
+ConversationTest::testLoadPartiallyRemovedConversation()
+{
+    std::cout << "\nRunning test: " << __func__ << std::endl;
+
+    auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
+    auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
+    auto bobUri = bobAccount->getUsername();
+    auto aliceUri = aliceAccount->getUsername();
+    std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers;
+    bool requestReceived = false;
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConfigurationSignal::IncomingTrustRequest>(
+            [&](const std::string& account_id,
+                const std::string& /*from*/,
+                const std::string& /*conversationId*/,
+                const std::vector<uint8_t>& /*payload*/,
+                time_t /*received*/) {
+                if (account_id == bobId)
+                    requestReceived = true;
+                cv.notify_one();
+            }));
+    std::string convId = "";
+    confHandlers.insert(libjami::exportable_callback<libjami::ConversationSignal::ConversationReady>(
+        [&](const std::string& accountId, const std::string& conversationId) {
+            if (accountId == aliceId) {
+                convId = conversationId;
+            }
+            cv.notify_one();
+        }));
+    bool conversationRemoved = false;
+    confHandlers.insert(
+        libjami::exportable_callback<libjami::ConversationSignal::ConversationRemoved>(
+            [&](const std::string& accountId, const std::string&) {
+                if (accountId == aliceId)
+                    conversationRemoved = true;
+                cv.notify_one();
+            }));
+    libjami::registerSignalHandlers(confHandlers);
+    aliceAccount->addContact(bobUri);
+    aliceAccount->sendTrustRequest(bobUri, {});
+    CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
+
+    // Copy alice's conversation temporary
+    auto repoPathAlice = fmt::format("{}/{}/conversations/{}", fileutils::get_data_dir(),
+                                     aliceAccount->getAccountID(), convId);
+    std::filesystem::copy(repoPathAlice, fmt::format("./{}", convId), std::filesystem::copy_options::recursive);
+
+    // removeContact
+    aliceAccount->removeContact(bobUri, false);
+    CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationRemoved; }));
+    std::this_thread::sleep_for(10s); // Wait for connection to close and async tasks to finish
+
+    // Copy back alice's conversation
+    std::filesystem::copy(fmt::format("./{}", convId), repoPathAlice, std::filesystem::copy_options::recursive);
+    std::filesystem::remove_all(fmt::format("./{}", convId));
+
+    // Reloading conversation should remove directory
+    CPPUNIT_ASSERT(fileutils::isDirectory(repoPathAlice));
+    aliceAccount->convModule()->loadConversations();
+    CPPUNIT_ASSERT(!fileutils::isDirectory(repoPathAlice));
+}
+
 } // namespace test
 } // namespace jami
 
-- 
GitLab