Page MenuHomePhorge

D245.1777850350.diff
No OneTemporary

Size
24 KB
Referenced Files
None
Subscribers
None

D245.1777850350.diff

diff --git a/src/client/room/local-draft.hpp b/src/client/room/local-draft.hpp
new file mode 100644
--- /dev/null
+++ b/src/client/room/local-draft.hpp
@@ -0,0 +1,41 @@
+/*
+ * This file is part of libkazv.
+ * SPDX-FileCopyrightText: 2026 nannanko <nannankokazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#pragma once
+#include <libkazv-config.hpp>
+
+#include <cstdint>
+#include <string>
+
+#include <boost/serialization/split_free.hpp>
+#include <boost/serialization/version.hpp>
+
+namespace Kazv
+{
+ /**
+ * Local draft.
+ */
+ struct LocalDraft
+ {
+ std::string text;
+ std::string relType;
+ std::string relatedEventId;
+ friend bool operator==(const LocalDraft &a, const LocalDraft &b) = default;
+ friend bool operator!=(const LocalDraft &a, const LocalDraft &b) = default;
+ };
+
+ template<class Archive>
+ void serialize(Archive &ar, LocalDraft &draft, std::uint32_t const /*version*/)
+ {
+ ar
+ & draft.relType
+ & draft.relatedEventId
+ & draft.text
+ ;
+ }
+}
+
+BOOST_CLASS_VERSION(Kazv::LocalDraft, 0)
diff --git a/src/client/room/room-model.hpp b/src/client/room/room-model.hpp
--- a/src/client/room/room-model.hpp
+++ b/src/client/room/room-model.hpp
@@ -27,6 +27,7 @@
#include "push-rules-desc.hpp"
#include "local-echo.hpp"
#include "clientutil.hpp"
+#include "local-draft.hpp"
namespace Kazv
{
@@ -115,11 +116,35 @@
EventList events;
};
- struct SetLocalDraftAction
+ struct SetLocalDraftTextAction
{
std::string localDraft;
};
+ struct SetLocalDraftRelAction
+ {
+ std::string relType;
+ std::string relatedEventId;
+ };
+
+ struct SetLocalDraftAction
+ {
+ std::string text;
+ std::string relType;
+ std::string relatedEventId;
+ };
+
+ struct PushLocalDraftAction
+ {
+ std::string text;
+ std::string relType;
+ std::string relatedEventId;
+ };
+
+ struct PopLocalDraftAction
+ {
+ };
+
struct SetRoomEncryptionAction
{
};
@@ -256,7 +281,9 @@
immer::map<std::string, Event> ephemeral;
- std::string localDraft;
+ immer::flex_vector<LocalDraft> localDrafts{
+ Kazv::LocalDraft{"", "", ""}
+ };
bool encrypted{false};
/// a marker to indicate whether we need to rotate
@@ -386,7 +413,11 @@
ChangeMembershipAction,
ChangeInviteStateAction,
AddEphemeralAction,
+ SetLocalDraftTextAction,
+ SetLocalDraftRelAction,
SetLocalDraftAction,
+ PushLocalDraftAction,
+ PopLocalDraftAction,
SetRoomEncryptionAction,
MarkMembersFullyLoadedAction,
SetHeroIdsAction,
@@ -450,9 +481,13 @@
& r.timelineGaps
& r.ephemeral
-
- & r.localDraft
-
+ ;
+ if (version < 10) {
+ std::string oldVerLocalDraft;
+ ar & oldVerLocalDraft;
+ r.localDrafts = {LocalDraft{oldVerLocalDraft, "", ""}};
+ }
+ ar
& r.encrypted
& r.shouldRotateSessionKey
@@ -501,6 +536,9 @@
if (version >= 9) {
ar & r.nonTimelineEvents;
}
+ if (version >= 10) {
+ ar & r.localDrafts;
+ }
}
template<class Archive>
@@ -512,5 +550,5 @@
BOOST_CLASS_VERSION(Kazv::PendingRoomKeyEvent, 1)
BOOST_CLASS_VERSION(Kazv::ReadReceipt, 0)
-BOOST_CLASS_VERSION(Kazv::RoomModel, 9)
+BOOST_CLASS_VERSION(Kazv::RoomModel, 10)
BOOST_CLASS_VERSION(Kazv::RoomListModel, 0)
diff --git a/src/client/room/room-model.cpp b/src/client/room/room-model.cpp
--- a/src/client/room/room-model.cpp
+++ b/src/client/room/room-model.cpp
@@ -276,8 +276,55 @@
r.ephemeral = merge(std::move(r.ephemeral), a.events, keyOfEphemeral);
return r;
},
+ [&](SetLocalDraftTextAction a) {
+ r.localDrafts = r.localDrafts.update(0,
+ [&a](auto localDraft) {
+ localDraft.text = a.localDraft;
+ return localDraft;
+ });
+ return r;
+ },
+ [&](SetLocalDraftRelAction a) {
+ r.localDrafts = r.localDrafts.update(0,
+ [&a](auto localDraft) {
+ localDraft.relType = a.relType;
+ localDraft.relatedEventId = a.relatedEventId;
+ return localDraft;
+ });
+ return r;
+ },
[&](SetLocalDraftAction a) {
- r.localDraft = a.localDraft;
+ r.localDrafts = r.localDrafts.update(0,
+ [&a](auto localDraft) {
+ localDraft.text = a.text;
+ localDraft.relType = a.relType;
+ localDraft.relatedEventId = a.relatedEventId;
+ return localDraft;
+ });
+ return r;
+ },
+ [&](PushLocalDraftAction a) {
+ r.localDrafts = r.localDrafts.push_front({
+ a.text,
+ a.relType,
+ a.relatedEventId
+ });
+ return r;
+ },
+ [&](PopLocalDraftAction) {
+ r.localDrafts = r.localDrafts.drop(1);
+ if (r.localDrafts.size() == 0) {
+ r.localDrafts = r.localDrafts.push_back(LocalDraft {
+ "", "", ""
+ });
+ }
+ // If the current draft is not associated with any event,
+ // kazv cannot continue to pop the remaining drafts.
+ // Clear the remaining drafts here to avoid accumulation.
+ auto draft = r.localDrafts[0];
+ if (draft.relType == "" || draft.relatedEventId == "") {
+ r.localDrafts = {draft};
+ }
return r;
},
[&](SetRoomEncryptionAction) {
diff --git a/src/client/room/room.hpp b/src/client/room/room.hpp
--- a/src/client/room/room.hpp
+++ b/src/client/room/room.hpp
@@ -335,8 +335,8 @@
KAZV_WRAP_ATTR(RoomModel, roomCursor(), roomId);
/*lager::reader<RoomMembership>*/
KAZV_WRAP_ATTR(RoomModel, roomCursor(), membership);
- /*lager::reader<std::string>*/
- KAZV_WRAP_ATTR(RoomModel, roomCursor(), localDraft);
+ /*lager::reader<immer::flex_vector<Kazv::LocalDraft>>*/
+ KAZV_WRAP_ATTR(RoomModel, roomCursor(), localDrafts);
/* lager::reader<bool> */
KAZV_WRAP_ATTR(RoomModel, roomCursor(), membersFullyLoaded);
@@ -375,7 +375,7 @@
* Set local draft for this room.
*
* After the returned Promise is resolved,
- * @c localDraft() will contain @c localDraft .
+ * @c localDrafts() will contain @c localDrafts.
*
* @param localDraft The local draft to send.
* @return A Promise that resolves when the local draft
@@ -383,6 +383,61 @@
*/
PromiseT setLocalDraft(std::string localDraft) const;
+ /**
+ * Set current local draft and related event for this room.
+ *
+ * After the returned Promise is resolved,
+ * @c localDrafts() will contain @c localDrafts.
+ *
+ * @param text The local draft to send.
+ * @param relType Such as m.in_reply_to, refer to https://spec.matrix.org/
+ * @param relatedEventId The eventId related to the local draft.
+ * @return A Promise that resolves when the local draft
+ * has been set, or when there is an error.
+ */
+ PromiseT setLocalDraft(std::string text,
+ std::string relType, std::string relatedEventId) const;
+
+ /**
+ * Set event related to local draft for this room.
+ *
+ * After the returned Promise is resolved,
+ * @c localDrafts() will contain @c localDrafts.
+ *
+ * @param relType Such as m.in_reply_to, refer to https://spec.matrix.org/
+ * @param relatedEventId The eventId related to the local draft.
+ * @return A Promise that resolves when the event
+ * has been set, or when there is an error.
+ */
+ PromiseT setLocalDraftRel(std::string relType,
+ std::string relatedEventId) const;
+
+ /**
+ * Push a local draft and related event for this room.
+ *
+ * After the returned Promise is resolved,
+ * @c localDrafts() will contain @c localDrafts.
+ *
+ * @param text The local draft to send.
+ * @param relType Such as m.in_reply_to, refer to https://spec.matrix.org/
+ * @param relatedEventId The eventId related to the local draft.
+ * @return A Promise that resolves when the local draft
+ * has been set, or when there is an error.
+ */
+ PromiseT pushLocalDraft(std::string text,
+ std::string relType, std::string relatedEventId) const;
+
+ /**
+ * Pop a Kazv::LocalDraft in RoomModel::localDrafts.
+ *
+ * After the returned Promise is resolved,
+ * @c localDrafts() will contain @c localDrafts.
+ *
+ * @return A Promise that resolves when the local drafts
+ * has been popped, or when there is an error.
+ */
+ PromiseT popLocalDraft() const;
+
/**
* Send an event to this room.
*
diff --git a/src/client/room/room.cpp b/src/client/room/room.cpp
--- a/src/client/room/room.cpp
+++ b/src/client/room/room.cpp
@@ -11,6 +11,7 @@
#include <debug.hpp>
#include "room.hpp"
+#include "sdk-model-cursor-tag.hpp"
namespace Kazv
{
@@ -320,7 +321,40 @@
-> PromiseT
{
using namespace CursorOp;
- return m_ctx.dispatch(UpdateRoomAction{+roomId(), SetLocalDraftAction{localDraft}});
+ return m_ctx.dispatch(UpdateRoomAction{
+ +roomId(), SetLocalDraftTextAction{localDraft}});
+ }
+
+ auto Room::setLocalDraft(std::string text,
+ std::string relType, std::string relatedEventId) const -> PromiseT
+ {
+ using namespace CursorOp;
+ return m_ctx.dispatch(UpdateRoomAction(
+ +roomId(), SetLocalDraftAction{text, relType, relatedEventId}
+ ));
+ }
+
+ auto Room::setLocalDraftRel(std::string relType,
+ std::string relatedEventId) const -> PromiseT
+ {
+ using namespace CursorOp;
+ return m_ctx.dispatch(UpdateRoomAction(
+ +roomId(), SetLocalDraftRelAction{relType, relatedEventId}));
+ }
+
+ auto Room::pushLocalDraft(std::string text,
+ std::string relType, std::string relatedEventId) const -> PromiseT
+ {
+ using namespace CursorOp;
+ return m_ctx.dispatch(UpdateRoomAction{+roomId(), PushLocalDraftAction{
+ text, relType, relatedEventId}});
+ }
+
+ auto Room::popLocalDraft() const -> PromiseT
+ {
+ using namespace CursorOp;
+ return m_ctx.dispatch(
+ UpdateRoomAction{+roomId(), PopLocalDraftAction{}});
}
auto Room::sendMessage(Event msg) const
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -94,6 +94,7 @@
client/encode-test.cpp
client/maybe-add-save-events-trigger-benchmark-test.cpp
client/verification-processing-test.cpp
+ client/room/local-draft.cpp
EXTRA_LINK_LIBRARIES kazvclient kazveventemitter kazvjob client-test-lib kazvtestfixtures
EXTRA_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/client
)
diff --git a/src/tests/client/room/local-draft.cpp b/src/tests/client/room/local-draft.cpp
new file mode 100644
--- /dev/null
+++ b/src/tests/client/room/local-draft.cpp
@@ -0,0 +1,268 @@
+/*
+ * This file is part of libkazv.
+ * SPDX-FileCopyrightText: 2026 nannanko <nannanko@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libkazv-config.hpp>
+
+#include "client/action-mock-utils.hpp"
+
+#include <promise-interface.hpp>
+#include <context.hpp>
+#include <asio-promise-handler.hpp>
+#include <cprjobhandler.hpp>
+#include <lagerstoreeventemitter.hpp>
+#include <factory.hpp>
+#include <sdk.hpp>
+#include <sdk-model.hpp>
+#include <client-model.hpp>
+#include <room/room-model.hpp>
+
+#include <catch2/catch_test_macros.hpp>
+#include <lager/event_loop/boost_asio.hpp>
+#include <boost/asio/io_context.hpp>
+
+#include <variant>
+
+TEST_CASE("Room::setLocalDraft(std::string)", "[client][room]")
+{
+ boost::asio::io_context io;
+ Kazv::SingleTypePromiseInterface<Kazv::EffectStatus> sgph{
+ Kazv::AsioPromiseHandler{io.get_executor()}
+ };
+
+ auto roomModel = Kazv::Factory::makeRoom();
+ auto clientModel = Kazv::Factory::makeClient(
+ Kazv::Factory::withRoom(roomModel));
+
+ auto jh = Kazv::CprJobHandler{io.get_executor()};
+ auto ee = Kazv::LagerStoreEventEmitter(
+ lager::with_boost_asio_event_loop{io.get_executor()});
+
+ auto sdk = Kazv::makeSdk(Kazv::SdkModel{clientModel}, jh, ee,
+ Kazv::AsioPromiseHandler{io.get_executor()}, zug::identity);
+ auto ctx = sdk.context();
+ auto dispatcher = getMockDispatcher(
+ sgph,
+ ctx,
+ passDown<Kazv::RoomListAction>()
+ );
+ auto mockContext = getMockContext(sgph, dispatcher);
+ auto client = Kazv::Client(Kazv::Client::InEventLoopTag{},
+ mockContext, sdk.context());
+ auto room = client.room(roomModel.roomId);
+
+ room.setLocalDraft("some draft")
+ .then([&](auto stat) {
+ REQUIRE(stat.success());
+ REQUIRE(dispatcher.template calledTimes<
+ Kazv::RoomListAction>() == 1);
+ auto action = dispatcher.template of<Kazv::RoomListAction>()[0];
+ REQUIRE(std::holds_alternative<Kazv::UpdateRoomAction>(action));
+ auto updateRoomAction = std::get<Kazv::UpdateRoomAction>(action);
+ REQUIRE(std::holds_alternative<Kazv::SetLocalDraftTextAction>(
+ updateRoomAction.roomAction));
+ REQUIRE(updateRoomAction.roomId == roomModel.roomId);
+ auto setLocalDraftTextAction = std::get<
+ Kazv::SetLocalDraftTextAction>(updateRoomAction.roomAction);
+ REQUIRE(setLocalDraftTextAction.localDraft == "some draft");
+ io.stop();
+ });
+
+ io.run();
+}
+
+TEST_CASE("Room::setLocalDraft(std::string, std::string, std::string)", "[client][room]")
+{
+ boost::asio::io_context io;
+ Kazv::SingleTypePromiseInterface<Kazv::EffectStatus> sgph{
+ Kazv::AsioPromiseHandler{io.get_executor()}
+ };
+
+ auto roomModel = Kazv::Factory::makeRoom();
+ auto clientModel = Kazv::Factory::makeClient(
+ Kazv::Factory::withRoom(roomModel));
+
+ auto jh = Kazv::CprJobHandler{io.get_executor()};
+ auto ee = Kazv::LagerStoreEventEmitter(
+ lager::with_boost_asio_event_loop{io.get_executor()});
+
+ auto sdk = Kazv::makeSdk(Kazv::SdkModel{clientModel}, jh, ee,
+ Kazv::AsioPromiseHandler{io.get_executor()}, zug::identity);
+ auto ctx = sdk.context();
+ auto dispatcher = getMockDispatcher(
+ sgph,
+ ctx,
+ passDown<Kazv::RoomListAction>()
+ );
+ auto mockContext = getMockContext(sgph, dispatcher);
+ auto client = Kazv::Client(Kazv::Client::InEventLoopTag{},
+ mockContext, sdk.context());
+ auto room = client.room(roomModel.roomId);
+
+ room.setLocalDraft("some draft", "m.reply", "$0")
+ .then([&](auto stat) {
+ REQUIRE(stat.success());
+ REQUIRE(dispatcher.template calledTimes<
+ Kazv::RoomListAction>() == 1);
+ auto action = dispatcher.template of<Kazv::RoomListAction>()[0];
+ REQUIRE(std::holds_alternative<Kazv::UpdateRoomAction>(action));
+ auto updateRoomAction = std::get<Kazv::UpdateRoomAction>(action);
+ REQUIRE(updateRoomAction.roomId == roomModel.roomId);
+ REQUIRE(std::holds_alternative<Kazv::SetLocalDraftAction>(
+ updateRoomAction.roomAction));
+ auto setLocalDraftAction = std::get<
+ Kazv::SetLocalDraftAction>(updateRoomAction.roomAction);
+ REQUIRE(setLocalDraftAction.text == "some draft");
+ REQUIRE(setLocalDraftAction.relType == "m.reply");
+ REQUIRE(setLocalDraftAction.relatedEventId == "$0");
+ io.stop();
+ });
+
+ io.run();
+}
+
+TEST_CASE("Room::setLocalDraftRel(std::string, std::string)", "[client][room]")
+{
+ boost::asio::io_context io;
+ Kazv::SingleTypePromiseInterface<Kazv::EffectStatus> sgph{
+ Kazv::AsioPromiseHandler{io.get_executor()}
+ };
+
+ auto roomModel = Kazv::Factory::makeRoom();
+ auto clientModel = Kazv::Factory::makeClient(
+ Kazv::Factory::withRoom(roomModel));
+
+ auto jh = Kazv::CprJobHandler{io.get_executor()};
+ auto ee = Kazv::LagerStoreEventEmitter(
+ lager::with_boost_asio_event_loop{io.get_executor()});
+
+ auto sdk = Kazv::makeSdk(Kazv::SdkModel{clientModel}, jh, ee,
+ Kazv::AsioPromiseHandler{io.get_executor()}, zug::identity);
+ auto ctx = sdk.context();
+ auto dispatcher = getMockDispatcher(
+ sgph,
+ ctx,
+ passDown<Kazv::RoomListAction>()
+ );
+ auto mockContext = getMockContext(sgph, dispatcher);
+ auto client = Kazv::Client(Kazv::Client::InEventLoopTag{},
+ mockContext, sdk.context());
+ auto room = client.room(roomModel.roomId);
+
+ room.setLocalDraftRel("m.reply", "$0")
+ .then([&](auto stat) {
+ REQUIRE(stat.success());
+ REQUIRE(dispatcher.template calledTimes<
+ Kazv::RoomListAction>() == 1);
+ auto action = dispatcher.template of<Kazv::RoomListAction>()[0];
+ REQUIRE(std::holds_alternative<Kazv::UpdateRoomAction>(action));
+ auto updateRoomAction = std::get<Kazv::UpdateRoomAction>(action);
+ REQUIRE(updateRoomAction.roomId == roomModel.roomId);
+ REQUIRE(std::holds_alternative<Kazv::SetLocalDraftRelAction>(
+ updateRoomAction.roomAction));
+ auto setLocalDraftRelAction = std::get<
+ Kazv::SetLocalDraftRelAction>(updateRoomAction.roomAction);
+ REQUIRE(setLocalDraftRelAction.relType == "m.reply");
+ REQUIRE(setLocalDraftRelAction.relatedEventId == "$0");
+ io.stop();
+ });
+
+ io.run();
+}
+
+TEST_CASE("Room::pushLocalDraft(std::string, std::string, std::string)", "[client][room]")
+{
+ boost::asio::io_context io;
+ Kazv::SingleTypePromiseInterface<Kazv::EffectStatus> sgph{
+ Kazv::AsioPromiseHandler{io.get_executor()}
+ };
+
+ auto roomModel = Kazv::Factory::makeRoom();
+ auto clientModel = Kazv::Factory::makeClient(
+ Kazv::Factory::withRoom(roomModel));
+
+ auto jh = Kazv::CprJobHandler{io.get_executor()};
+ auto ee = Kazv::LagerStoreEventEmitter(
+ lager::with_boost_asio_event_loop{io.get_executor()});
+
+ auto sdk = Kazv::makeSdk(Kazv::SdkModel{clientModel}, jh, ee,
+ Kazv::AsioPromiseHandler{io.get_executor()}, zug::identity);
+ auto ctx = sdk.context();
+ auto dispatcher = getMockDispatcher(
+ sgph,
+ ctx,
+ passDown<Kazv::RoomListAction>()
+ );
+ auto mockContext = getMockContext(sgph, dispatcher);
+ auto client = Kazv::Client(Kazv::Client::InEventLoopTag{},
+ mockContext, sdk.context());
+ auto room = client.room(roomModel.roomId);
+
+ room.pushLocalDraft("some draft", "m.reply", "$0")
+ .then([&](auto stat) {
+ REQUIRE(stat.success());
+ REQUIRE(dispatcher.template calledTimes<
+ Kazv::RoomListAction>() == 1);
+ auto action = dispatcher.template of<Kazv::RoomListAction>()[0];
+ REQUIRE(std::holds_alternative<Kazv::UpdateRoomAction>(action));
+ auto updateRoomAction = std::get<Kazv::UpdateRoomAction>(action);
+ REQUIRE(updateRoomAction.roomId == roomModel.roomId);
+ REQUIRE(std::holds_alternative<Kazv::PushLocalDraftAction>(
+ updateRoomAction.roomAction));
+ auto pushLocalDraftAction = std::get<
+ Kazv::PushLocalDraftAction>(updateRoomAction.roomAction);
+ REQUIRE(pushLocalDraftAction.text == "some draft");
+ REQUIRE(pushLocalDraftAction.relType == "m.reply");
+ REQUIRE(pushLocalDraftAction.relatedEventId == "$0");
+ io.stop();
+ });
+
+ io.run();
+}
+
+TEST_CASE("Room::popLocalDraft()", "[client][room]")
+{
+ boost::asio::io_context io;
+ Kazv::SingleTypePromiseInterface<Kazv::EffectStatus> sgph{
+ Kazv::AsioPromiseHandler{io.get_executor()}
+ };
+
+ auto roomModel = Kazv::Factory::makeRoom();
+ auto clientModel = Kazv::Factory::makeClient(
+ Kazv::Factory::withRoom(roomModel));
+
+ auto jh = Kazv::CprJobHandler{io.get_executor()};
+ auto ee = Kazv::LagerStoreEventEmitter(
+ lager::with_boost_asio_event_loop{io.get_executor()});
+
+ auto sdk = Kazv::makeSdk(Kazv::SdkModel{clientModel}, jh, ee,
+ Kazv::AsioPromiseHandler{io.get_executor()}, zug::identity);
+ auto ctx = sdk.context();
+ auto dispatcher = getMockDispatcher(
+ sgph,
+ ctx,
+ passDown<Kazv::RoomListAction>()
+ );
+ auto mockContext = getMockContext(sgph, dispatcher);
+ auto client = Kazv::Client(Kazv::Client::InEventLoopTag{},
+ mockContext, sdk.context());
+ auto room = client.room(roomModel.roomId);
+
+ room.popLocalDraft()
+ .then([&](auto stat) {
+ REQUIRE(stat.success());
+ REQUIRE(dispatcher.template calledTimes<
+ Kazv::RoomListAction>() == 1);
+ auto action = dispatcher.template of<Kazv::RoomListAction>()[0];
+ REQUIRE(std::holds_alternative<Kazv::UpdateRoomAction>(action));
+ auto updateRoomAction = std::get<Kazv::UpdateRoomAction>(action);
+ REQUIRE(updateRoomAction.roomId == roomModel.roomId);
+ REQUIRE(std::holds_alternative<Kazv::PopLocalDraftAction>(
+ updateRoomAction.roomAction));
+ io.stop();
+ });
+
+ io.run();
+}
diff --git a/src/tests/client/room/room-actions-test.cpp b/src/tests/client/room/room-actions-test.cpp
--- a/src/tests/client/room/room-actions-test.cpp
+++ b/src/tests/client/room/room-actions-test.cpp
@@ -141,3 +141,72 @@
REQUIRE(next.stateEvents.count(KeyOfState{"m.room.member", "@bar:example.com"}));
REQUIRE(next.stateEvents[KeyOfState{"m.room.member", "@bar:example.com"}].content().get()["membership"] == "join");
}
+
+TEST_CASE("SetLocalDraftTextAction", "[client][room]")
+{
+ RoomModel r;
+
+ auto res = RoomModel::update(r, SetLocalDraftTextAction("some draft"));
+
+ REQUIRE(res.localDrafts.front().text == "some draft");
+}
+
+TEST_CASE("SetLocalDraftRelAction", "[client][room]")
+{
+ RoomModel r;
+
+ auto res = RoomModel::update(r,
+ SetLocalDraftRelAction("m.replace", "$eventid"));
+
+ REQUIRE(res.localDrafts.front().text == "");
+ REQUIRE(res.localDrafts.front().relType == "m.replace");
+ REQUIRE(res.localDrafts.front().relatedEventId == "$eventid");
+}
+
+TEST_CASE("SetLocalDraftAction", "[client][room]")
+{
+ RoomModel r;
+
+ auto res = RoomModel::update(r,
+ SetLocalDraftAction("some draft", "m.replace", "$eventid"));
+
+ REQUIRE(res.localDrafts.front().text == "some draft");
+ REQUIRE(res.localDrafts.front().relType == "m.replace");
+ REQUIRE(res.localDrafts.front().relatedEventId == "$eventid");
+}
+
+TEST_CASE("pushLocalDraftAction", "[client][room]")
+{
+ RoomModel r;
+
+ auto res = RoomModel::update(r,
+ PushLocalDraftAction("some draft", "m.replace", "$eventid"));
+
+ REQUIRE(res.localDrafts.size() == 2);
+ REQUIRE(res.localDrafts.front().text == "some draft");
+ REQUIRE(res.localDrafts.front().relType == "m.replace");
+ REQUIRE(res.localDrafts.front().relatedEventId == "$eventid");
+}
+
+TEST_CASE("popLocalDraftAction", "[client][room]")
+{
+ RoomModel r;
+
+ auto res = RoomModel::update(r,
+ PushLocalDraftAction("some draft", "m.replace", "$eventid"));
+
+ REQUIRE(res.localDrafts.size() == 2);
+ REQUIRE(res.localDrafts.front().text == "some draft");
+ REQUIRE(res.localDrafts.front().relType == "m.replace");
+ REQUIRE(res.localDrafts.front().relatedEventId == "$eventid");
+
+ res = RoomModel::update(r, PopLocalDraftAction{});
+ REQUIRE(res.localDrafts.size() == 1);
+ REQUIRE(res.localDrafts.front().text == "");
+ REQUIRE(res.localDrafts.front().relType == "");
+ REQUIRE(res.localDrafts.front().relatedEventId == "");
+
+ // The size of localDrafts is at least 1
+ res = RoomModel::update(r, PopLocalDraftAction{});
+ REQUIRE(res.localDrafts.size() == 1);
+}

File Metadata

Mime Type
text/plain
Expires
Sun, May 3, 4:19 PM (12 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1437959
Default Alt Text
D245.1777850350.diff (24 KB)

Event Timeline