conversation_module: return swarm's profile to the client for requests

Conversation's requests also have metadata attached which clients
must be able to access.

https://git.jami.net/savoirfairelinux/jami-client-qt/-/issues/670

Change-Id: If02fffb5646074e993c090846ff998e83ab79d78
This commit is contained in:
Sébastien Blin
2022-02-22 16:22:55 -05:00
parent 4b2cc45f96
commit ab3e52316c
2 changed files with 177 additions and 150 deletions

View File

@ -1484,6 +1484,12 @@ ConversationModule::updateConversationInfos(const std::string& conversationId,
std::map<std::string, std::string>
ConversationModule::conversationInfos(const std::string& conversationId) const
{
{
std::lock_guard<std::mutex> lk(pimpl_->conversationsRequestsMtx_);
auto itReq = pimpl_->conversationsRequests_.find(conversationId);
if (itReq != pimpl_->conversationsRequests_.end())
return itReq->second.metadatas;
}
std::lock_guard<std::mutex> lk(pimpl_->conversationsMtx_);
// Add a new member in the conversation
auto it = pimpl_->conversations_.find(conversationId);

View File

@ -40,6 +40,7 @@
#include "security/certstore.h"
using namespace std::string_literals;
using namespace std::literals::chrono_literals;
using namespace DRing::Account;
struct ConvInfoTest
@ -102,6 +103,7 @@ private:
void testETooBigFetch();
void testUnknownModeDetected();
void testUpdateProfile();
void testGetProfileRequest();
void testCheckProfileInConversationRequest();
void testCheckProfileInTrustRequest();
void testMemberCannotUpdateProfile();
@ -136,6 +138,7 @@ private:
CPPUNIT_TEST(testETooBigFetch);
CPPUNIT_TEST(testUnknownModeDetected);
CPPUNIT_TEST(testUpdateProfile);
CPPUNIT_TEST(testGetProfileRequest);
CPPUNIT_TEST(testCheckProfileInConversationRequest);
CPPUNIT_TEST(testCheckProfileInTrustRequest);
CPPUNIT_TEST(testMemberCannotUpdateProfile);
@ -205,7 +208,7 @@ ConversationTest::testCreateConversation()
// Start conversation
auto convId = DRing::startConversation(aliceId);
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; });
cv.wait_for(lk, 30s, [&]() { return conversationReady; });
CPPUNIT_ASSERT(conversationReady);
ConversationRepository repo(aliceAccount, convId);
CPPUNIT_ASSERT(repo.mode() == ConversationMode::INVITES_ONLY);
@ -266,7 +269,7 @@ ConversationTest::testGetConversationsAfterRm()
// Start conversation
auto convId = DRing::startConversation(aliceId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
auto conversations = DRing::getConversations(aliceId);
CPPUNIT_ASSERT(conversations.size() == 1);
@ -297,7 +300,7 @@ ConversationTest::testRemoveInvalidConversation()
// Start conversation
auto convId = DRing::startConversation(aliceId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
auto conversations = DRing::getConversations(aliceId);
CPPUNIT_ASSERT(conversations.size() == 1);
@ -351,20 +354,20 @@ ConversationTest::testSendMessage()
auto convId = DRing::startConversation(aliceId);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
// Assert that repository exists
auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
+ DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
// Wait that alice sees Bob
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageAliceReceived == 2; });
cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; });
DRing::sendMessage(aliceId, convId, "hi"s, "");
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageBobReceived == 1; });
cv.wait_for(lk, 30s, [&]() { return messageBobReceived == 1; });
}
void
@ -422,13 +425,13 @@ ConversationTest::testReplaceWithBadCertificate()
auto convId = DRing::startConversation(aliceId);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
// Wait that alice sees Bob
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageAliceReceived == 2; });
cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; });
// Replace alice's certificate with a bad one.
auto repoPath = fmt::format("{}/{}/conversations/{}",
@ -457,7 +460,7 @@ ConversationTest::testReplaceWithBadCertificate()
// now we need to sync!
DRing::sendMessage(aliceId, convId, "trigger sync!"s, "");
// We should detect the incorrect commit!
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; });
cv.wait_for(lk, 30s, [&]() { return errorDetected; });
}
void
@ -485,10 +488,10 @@ ConversationTest::testSendMessageTriggerMessageReceived()
DRing::registerSignalHandlers(confHandlers);
auto convId = DRing::startConversation(aliceId);
cv.wait_for(lk, std::chrono::seconds(30), [&] { return conversationReady; });
cv.wait_for(lk, 30s, [&] { return conversationReady; });
DRing::sendMessage(aliceId, convId, "hi"s, "");
cv.wait_for(lk, std::chrono::seconds(30), [&] { return messageReceived == 1; });
cv.wait_for(lk, 30s, [&] { return messageReceived == 1; });
CPPUNIT_ASSERT(messageReceived == 1);
DRing::unregisterSignalHandlers();
}
@ -550,7 +553,7 @@ ConversationTest::testMergeTwoDifferentHeads()
// Start Carla, should merge and all messages should be there
Manager::instance().sendRegister(carlaId, true);
carlaGotMessage = false;
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&] { return carlaGotMessage; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&] { return carlaGotMessage; }));
DRing::unregisterSignalHandlers();
}
@ -583,7 +586,7 @@ ConversationTest::testSendMessageToMultipleParticipants()
DRing::registerSignalHandlers(confHandlers);
Manager::instance().sendRegister(carlaId, true);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&] { return carlaConnected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&] { return carlaConnected; }));
confHandlers.clear();
DRing::unregisterSignalHandlers();
@ -625,14 +628,13 @@ ConversationTest::testSendMessageToMultipleParticipants()
DRing::addConversationMember(aliceId, convId, bobUri);
DRing::addConversationMember(aliceId, convId, carlaUri);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(60), [&]() { return requestReceived == 2; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&]() { return requestReceived == 2; }));
messageReceivedAlice = 0;
DRing::acceptConversationRequest(bobId, convId);
DRing::acceptConversationRequest(carlaId, convId);
// >= because we can have merges cause the accept commits
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&]() {
return conversationReady == 3 && messageReceivedAlice >= 2;
}));
@ -645,7 +647,7 @@ ConversationTest::testSendMessageToMultipleParticipants()
CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
DRing::sendMessage(aliceId, convId, "hi"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&]() {
return messageReceivedBob >= 1 && messageReceivedCarla >= 1;
}));
DRing::unregisterSignalHandlers();
@ -692,12 +694,11 @@ ConversationTest::testPingPongMessages()
DRing::registerSignalHandlers(confHandlers);
auto convId = DRing::startConversation(aliceId);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
messageAliceReceived = 0;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&]() {
return conversationReady && messageAliceReceived == 1;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 60s, [&]() { return conversationReady && messageAliceReceived == 1; }));
// Assert that repository exists
auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
+ DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
@ -705,19 +706,19 @@ ConversationTest::testPingPongMessages()
messageBobReceived = 0;
messageAliceReceived = 0;
DRing::sendMessage(aliceId, convId, "ping"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return messageBobReceived == 1 && messageAliceReceived == 1;
}));
DRing::sendMessage(bobId, convId, "pong"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return messageBobReceived == 2 && messageAliceReceived == 2;
}));
DRing::sendMessage(bobId, convId, "ping"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return messageBobReceived == 3 && messageAliceReceived == 3;
}));
DRing::sendMessage(aliceId, convId, "pong"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return messageBobReceived == 4 && messageAliceReceived == 4;
}));
DRing::unregisterSignalHandlers();
@ -774,8 +775,7 @@ ConversationTest::testIsComposing()
}));
DRing::registerSignalHandlers(confHandlers);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
// Assert that repository exists
auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
+ DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
@ -783,17 +783,16 @@ ConversationTest::testIsComposing()
// Check created files
auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
memberMessageGenerated = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
aliceAccount->setIsComposing("swarm:" + convId, true);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return aliceComposing; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return aliceComposing; }));
aliceAccount->setIsComposing("swarm:" + convId, false);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return !aliceComposing; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return !aliceComposing; }));
}
void
@ -854,9 +853,8 @@ ConversationTest::testSetMessageDisplayed()
DRing::registerSignalHandlers(confHandlers);
aliceLastMsg = "";
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return memberMessageGenerated && !aliceLastMsg.empty();
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated && !aliceLastMsg.empty(); }));
// Assert that repository exists
auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
+ DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
@ -864,11 +862,10 @@ ConversationTest::testSetMessageDisplayed()
// Check created files
auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
memberMessageGenerated = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
// Last displayed messages should not be set yet
auto membersInfos = DRing::getConversationMembers(bobId, convId);
@ -889,7 +886,7 @@ ConversationTest::testSetMessageDisplayed()
!= membersInfos.end());
aliceAccount->setMessageDisplayed("swarm:" + convId, convId, 3);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return msgDisplayed; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return msgDisplayed; }));
// Now, the last displayed message should be updated in member's infos (both sides)
membersInfos = DRing::getConversationMembers(bobId, convId);
@ -982,17 +979,16 @@ ConversationTest::testSetMessageDisplayedPreference()
CPPUNIT_ASSERT(details[ConfProperties::SENDREADRECEIPT] == "true");
details[ConfProperties::SENDREADRECEIPT] = "false";
DRing::setAccountDetails(aliceId, details);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return aliceRegistered; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return aliceRegistered; }));
aliceLastMsg = "";
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return requestReceived && memberMessageGenerated && !aliceLastMsg.empty();
}));
memberMessageGenerated = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
// Last displayed messages should not be set yet
auto membersInfos = DRing::getConversationMembers(aliceId, convId);
@ -1007,7 +1003,7 @@ ConversationTest::testSetMessageDisplayedPreference()
aliceAccount->setMessageDisplayed("swarm:" + convId, convId, 3);
// Bob should not receive anything here, as sendMessageDisplayed is disabled for Alice
CPPUNIT_ASSERT(!cv.wait_for(lk, std::chrono::seconds(10), [&]() { return msgDisplayed; }));
CPPUNIT_ASSERT(!cv.wait_for(lk, 10s, [&]() { return msgDisplayed; }));
// Assert that message is set as displayed for self (for the read status)
membersInfos = DRing::getConversationMembers(aliceId, convId);
@ -1069,13 +1065,13 @@ ConversationTest::testBanDevice()
}));
DRing::registerSignalHandlers(confHandlers);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return requestReceived && memberMessageGenerated;
}));
memberMessageGenerated = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
// Add second device for Bob
auto bobArchive = std::filesystem::current_path().string() + "/bob.gz";
@ -1105,7 +1101,7 @@ ConversationTest::testBanDevice()
DRing::registerSignalHandlers(confHandlers);
conversationReady = false;
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&]() { return conversationReady; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&]() { return conversationReady; }));
// Now check that alice, has the only admin, can remove bob
memberMessageGenerated = false;
@ -1114,7 +1110,7 @@ ConversationTest::testBanDevice()
auto members = DRing::getConversationMembers(aliceId, convId);
CPPUNIT_ASSERT(members.size() == 2);
DRing::removeConversationMember(aliceId, convId, bobDeviceId, true);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return memberMessageGenerated && voteMessageGenerated;
}));
@ -1127,7 +1123,7 @@ ConversationTest::testBanDevice()
CPPUNIT_ASSERT(members.size() == 2);
// Assert that bob2 get the message, not Bob
CPPUNIT_ASSERT(!cv.wait_for(lk, std::chrono::seconds(10), [&]() { return bobGetMessage; }));
CPPUNIT_ASSERT(!cv.wait_for(lk, 10s, [&]() { return bobGetMessage; }));
CPPUNIT_ASSERT(bob2GetMessage && !bobGetMessage);
DRing::unregisterSignalHandlers();
}*/
@ -1368,32 +1364,28 @@ ConversationTest::testVoteNonEmpty()
}));
DRing::registerSignalHandlers(confHandlers);
Manager::instance().sendRegister(carlaId, true);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&] { return carlaConnected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&] { return carlaConnected; }));
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return requestReceived && memberMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return requestReceived && memberMessageGenerated; }));
memberMessageGenerated = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
requestReceived = false;
DRing::addConversationMember(aliceId, convId, carlaUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return requestReceived && memberMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return requestReceived && memberMessageGenerated; }));
memberMessageGenerated = false;
messageBobReceived = false;
DRing::acceptConversationRequest(carlaId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return memberMessageGenerated && messageBobReceived;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated && messageBobReceived; }));
// Now Alice removes Carla with a non empty file
errorDetected = false;
addVote(aliceAccount, convId, carlaUri, "CONTENT");
simulateRemoval(aliceAccount, convId, carlaUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
}
void
@ -1455,12 +1447,12 @@ ConversationTest::testNoBadFileInInitialCommit()
DRing::registerSignalHandlers(confHandlers);
Manager::instance().sendRegister(carlaId, true);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return carlaConnected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return carlaConnected; }));
DRing::addConversationMember(carlaId, convId, aliceUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
DRing::acceptConversationRequest(aliceId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
}
void
@ -1528,12 +1520,12 @@ ConversationTest::testNoBadCertInInitialCommit()
DRing::registerSignalHandlers(confHandlers);
Manager::instance().sendRegister(carlaId, true);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return carlaConnected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return carlaConnected; }));
DRing::addConversationMember(carlaId, convId, aliceUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
DRing::acceptConversationRequest(aliceId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
}
void
@ -1592,15 +1584,12 @@ ConversationTest::testPlainTextNoBadFile()
DRing::registerSignalHandlers(confHandlers);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return requestReceived && memberMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return requestReceived && memberMessageGenerated; }));
memberMessageGenerated = false;
DRing::acceptConversationRequest(bobId, convId);
cv.wait_for(lk, std::chrono::seconds(30), [&] {
return conversationReady && memberMessageGenerated;
});
cv.wait_for(lk, 30s, [&] { return conversationReady && memberMessageGenerated; });
addFile(aliceAccount, convId, "BADFILE");
Json::Value root;
@ -1610,7 +1599,7 @@ ConversationTest::testPlainTextNoBadFile()
errorDetected = false;
DRing::sendMessage(aliceId, convId, "hi"s, "");
// Check not received due to the unwanted file
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
DRing::unregisterSignalHandlers();
}
@ -1682,40 +1671,34 @@ ConversationTest::testVoteNoBadFile()
}));
DRing::registerSignalHandlers(confHandlers);
Manager::instance().sendRegister(carlaId, true);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return carlaConnected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return carlaConnected; }));
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return requestReceived && memberMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return requestReceived && memberMessageGenerated; }));
memberMessageGenerated = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
requestReceived = false;
DRing::addConversationMember(aliceId, convId, carlaUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return requestReceived && memberMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return requestReceived && memberMessageGenerated; }));
memberMessageGenerated = false;
messageBobReceived = false;
DRing::acceptConversationRequest(carlaId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return memberMessageGenerated && messageBobReceived;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated && messageBobReceived; }));
// Now Alice remove Carla without a vote. Bob will not receive the message
messageBobReceived = false;
addFile(aliceAccount, convId, "BADFILE");
DRing::removeConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return memberMessageGenerated && voteMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated && voteMessageGenerated; }));
messageCarlaReceived = false;
DRing::sendMessage(bobId, convId, "final"s, "");
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageCarlaReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return messageCarlaReceived; }));
}
void
@ -1784,11 +1767,11 @@ ConversationTest::testETooBigClone()
addAll(aliceAccount, convId);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
errorDetected = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
DRing::unregisterSignalHandlers();
}
@ -1847,13 +1830,13 @@ ConversationTest::testETooBigFetch()
auto convId = DRing::startConversation(aliceId);
DRing::addConversationMember(aliceId, convId, bobUri);
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; });
cv.wait_for(lk, 30s, [&]() { return requestReceived; });
DRing::acceptConversationRequest(bobId, convId);
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; });
cv.wait_for(lk, 30s, [&]() { return conversationReady; });
// Wait that alice sees Bob
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageAliceReceived == 2; });
cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; });
auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
+ DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
@ -1871,7 +1854,7 @@ ConversationTest::testETooBigFetch()
commit(aliceAccount, convId, json);
DRing::sendMessage(aliceId, convId, "hi"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
DRing::unregisterSignalHandlers();
}
@ -1931,10 +1914,10 @@ ConversationTest::testUnknownModeDetected()
}));
DRing::registerSignalHandlers(confHandlers);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
errorDetected = false;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
}
void
@ -1982,18 +1965,63 @@ ConversationTest::testUpdateProfile()
auto convId = DRing::startConversation(aliceId);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
messageAliceReceived = 0;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return conversationReady && messageAliceReceived == 1;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return conversationReady && messageAliceReceived == 1; }));
messageBobReceived = 0;
aliceAccount->convModule()->updateConversationInfos(convId, {{"title", "My awesome swarm"}});
CPPUNIT_ASSERT(
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageBobReceived == 1; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return messageBobReceived == 1; }));
auto infos = DRing::conversationInfos(bobId, convId);
CPPUNIT_ASSERT(infos["title"] == "My awesome swarm");
CPPUNIT_ASSERT(infos["description"].empty());
DRing::unregisterSignalHandlers();
}
void
ConversationTest::testGetProfileRequest()
{
auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
auto bobUri = bobAccount->getUsername();
std::mutex mtx;
std::unique_lock<std::mutex> lk {mtx};
std::condition_variable cv;
std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> confHandlers;
auto messageAliceReceived = 0;
confHandlers.insert(DRing::exportable_callback<DRing::ConversationSignal::MessageReceived>(
[&](const std::string& accountId,
const std::string& /* conversationId */,
std::map<std::string, std::string> /*message*/) {
if (accountId == aliceId)
messageAliceReceived += 1;
cv.notify_one();
}));
bool requestReceived = false;
confHandlers.insert(
DRing::exportable_callback<DRing::ConversationSignal::ConversationRequestReceived>(
[&](const std::string& /*accountId*/,
const std::string& /* conversationId */,
std::map<std::string, std::string> /*metadatas*/) {
requestReceived = true;
cv.notify_one();
}));
DRing::registerSignalHandlers(confHandlers);
auto convId = DRing::startConversation(aliceId);
messageAliceReceived = 0;
aliceAccount->convModule()->updateConversationInfos(convId, {{"title", "My awesome swarm"}});
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 1; }));
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
auto infos = DRing::conversationInfos(bobId, convId);
CPPUNIT_ASSERT(infos["title"] == "My awesome swarm");
@ -2048,7 +2076,7 @@ ConversationTest::testCheckProfileInConversationRequest()
aliceAccount->convModule()->updateConversationInfos(convId, {{"title", "My awesome swarm"}});
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
auto requests = DRing::getConversationRequests(bobId);
CPPUNIT_ASSERT(requests.size() == 1);
CPPUNIT_ASSERT(requests.front()["title"] == "My awesome swarm");
@ -2108,9 +2136,7 @@ END:VCARD";
aliceAccount->addContact(bobUri);
std::vector<uint8_t> payload(vcard.begin(), vcard.end());
aliceAccount->sendTrustRequest(bobUri, payload);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&]() {
return !convId.empty() && requestReceived;
}));
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&]() { return !convId.empty() && requestReceived; }));
}
void
@ -2168,17 +2194,16 @@ ConversationTest::testMemberCannotUpdateProfile()
DRing::registerSignalHandlers(confHandlers);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
messageAliceReceived = 0;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return conversationReady && messageAliceReceived == 1;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return conversationReady && messageAliceReceived == 1; }));
messageBobReceived = 0;
bobAccount->convModule()->updateConversationInfos(convId, {{"title", "My awesome swarm"}});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(5), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 5s, [&]() { return errorDetected; }));
DRing::unregisterSignalHandlers();
}
@ -2237,13 +2262,12 @@ ConversationTest::testUpdateProfileWithBadFile()
DRing::registerSignalHandlers(confHandlers);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
messageAliceReceived = 0;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return conversationReady && messageAliceReceived == 1;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return conversationReady && messageAliceReceived == 1; }));
// Update profile but with bad file
addFile(aliceAccount, convId, "BADFILE");
@ -2258,7 +2282,7 @@ END:VCARD";
commit(aliceAccount, convId, root);
errorDetected = false;
DRing::sendMessage(aliceId, convId, "hi"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
DRing::unregisterSignalHandlers();
}
@ -2317,13 +2341,12 @@ ConversationTest::testFetchProfileUnauthorized()
DRing::registerSignalHandlers(confHandlers);
DRing::addConversationMember(aliceId, convId, bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
messageAliceReceived = 0;
DRing::acceptConversationRequest(bobId, convId);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return conversationReady && messageAliceReceived == 1;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return conversationReady && messageAliceReceived == 1; }));
// Fake realist profile update
std::string vcard = "BEGIN:VCARD\n\
@ -2337,7 +2360,7 @@ END:VCARD";
commit(bobAccount, convId, root);
errorDetected = false;
DRing::sendMessage(bobId, convId, "hi"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return errorDetected; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return errorDetected; }));
DRing::unregisterSignalHandlers();
}
@ -2403,7 +2426,7 @@ ConversationTest::testSyncingWhileAccepting()
DRing::registerSignalHandlers(confHandlers);
aliceAccount->addContact(bobUri);
aliceAccount->sendTrustRequest(bobUri, {});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
Manager::instance().sendRegister(aliceId, false); // This avoid to sync immediately
CPPUNIT_ASSERT(bobAccount->acceptTrustRequest(aliceUri));
@ -2412,7 +2435,7 @@ ConversationTest::testSyncingWhileAccepting()
CPPUNIT_ASSERT(convInfos["syncing"] == "true");
Manager::instance().sendRegister(aliceId, true); // This avoid to sync immediately
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
convInfos = DRing::conversationInfos(bobId, convId);
CPPUNIT_ASSERT(convInfos.find("syncing") == convInfos.end());
@ -2433,19 +2456,19 @@ ConversationTest::testCountInteractions()
msgId1 = commitId;
cv.notify_one();
});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return !msgId1.empty(); }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return !msgId1.empty(); }));
aliceAccount->convModule()
->sendMessage(convId, "2"s, "", "text/plain", true, [&](bool, std::string commitId) {
msgId2 = commitId;
cv.notify_one();
});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return !msgId2.empty(); }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return !msgId2.empty(); }));
aliceAccount->convModule()
->sendMessage(convId, "3"s, "", "text/plain", true, [&](bool, std::string commitId) {
msgId3 = commitId;
cv.notify_one();
});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&] { return !msgId3.empty(); }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return !msgId3.empty(); }));
CPPUNIT_ASSERT(DRing::countInteractions(aliceId, convId, "", "", "") == 4 /* 3 + initial */);
CPPUNIT_ASSERT(DRing::countInteractions(aliceId, convId, "", "", aliceAccount->getUsername())
@ -2511,31 +2534,30 @@ ConversationTest::testReplayConversation()
requestReceived = false;
aliceAccount->addContact(bobUri);
aliceAccount->sendTrustRequest(bobUri, {});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
CPPUNIT_ASSERT(bobAccount->acceptTrustRequest(aliceUri));
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return conversationReady && memberMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return conversationReady && memberMessageGenerated; }));
// removeContact
aliceAccount->removeContact(bobUri, false);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationRemoved; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationRemoved; }));
// re-add
CPPUNIT_ASSERT(convId != "");
auto oldConvId = convId;
convId = "";
aliceAccount->addContact(bobUri);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return !convId.empty(); }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return !convId.empty(); }));
messageReceived = false;
DRing::sendMessage(aliceId, convId, "foo"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return messageReceived; }));
messageReceived = false;
DRing::sendMessage(aliceId, convId, "bar"s, "");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return messageReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return messageReceived; }));
convId = "";
bobMessages.clear();
aliceAccount->sendTrustRequest(bobUri, {});
// Should retrieve previous conversation
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
return bobMessages.size() == 2 && bobMessages[0] == "foo" && bobMessages[1] == "bar";
}));
}
@ -2622,34 +2644,33 @@ ConversationTest::testSyncWithoutPinnedCert()
bob2Id = Manager::instance().addAccount(details);
// Disconnect bob2, to create a valid conv betwen Alice and Bob1
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return bob2Started; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bob2Started; }));
bob2Stopped = false;
Manager::instance().sendRegister(bob2Id, false);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return bob2Stopped; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bob2Stopped; }));
// Alice adds bob
requestReceived = false;
aliceAccount->addContact(bobUri);
aliceAccount->sendTrustRequest(bobUri, {});
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
CPPUNIT_ASSERT(bobAccount->acceptTrustRequest(aliceUri));
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() {
return conversationReady && memberMessageGenerated;
}));
CPPUNIT_ASSERT(
cv.wait_for(lk, 30s, [&]() { return conversationReady && memberMessageGenerated; }));
// Bob send a message
DRing::sendMessage(bobId, convId, "hi"s, "");
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return aliceMessageReceived; });
cv.wait_for(lk, 30s, [&]() { return aliceMessageReceived; });
// Alice off, bob2 On
conversationReady = false;
aliceStopped = false;
Manager::instance().sendRegister(aliceId, false);
cv.wait_for(lk, std::chrono::seconds(10), [&]() { return aliceStopped; });
cv.wait_for(lk, 10s, [&]() { return aliceStopped; });
Manager::instance().sendRegister(bob2Id, true);
// Sync + validate
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return conversationReady; }));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
}
void