Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F140543
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/changelogs/28.fix b/changelogs/28.fix
new file mode 100644
index 0000000..7d294c9
--- /dev/null
+++ b/changelogs/28.fix
@@ -0,0 +1 @@
+Fix joining room with room alias
diff --git a/src/client/actions/membership.cpp b/src/client/actions/membership.cpp
index cc612d1..23aece4 100644
--- a/src/client/actions/membership.cpp
+++ b/src/client/actions/membership.cpp
@@ -1,287 +1,293 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2020 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <csapi/create_room.hpp>
#include <csapi/inviting.hpp>
#include <csapi/joining.hpp>
#include <debug.hpp>
#include "client-model.hpp"
#include "clientutil.hpp"
#include "cursorutil.hpp"
#include "status-utils.hpp"
#include "membership.hpp"
namespace Kazv
{
static std::string visibilityToStr(CreateRoomAction::Visibility v)
{
using V = CreateRoomAction::Visibility;
switch (v) {
case V::Private:
return "private";
case V::Public:
return "public";
default:
// should not happen
return "";
}
}
static std::string presetToStr(CreateRoomAction::Preset p)
{
using P = CreateRoomAction::Preset;
switch (p) {
case P::PrivateChat:
return "private_chat";
case P::PublicChat:
return "public_chat";
case P::TrustedPrivateChat:
return "trusted_private_chat";
default:
// should not happen
return "";
}
}
ClientResult updateClient(ClientModel m, CreateRoomAction a)
{
auto visibility = visibilityToStr(a.visibility);
std::optional<std::string> preset = a.preset
? std::optional<std::string>(presetToStr(a.preset.value()))
: std::nullopt;
using StateEvT = Kazv::CreateRoomJob::StateEvent;
auto initialState = intoImmer(
immer::array<StateEvT>{},
zug::map(
[](Event e) {
return StateEvT{e.type(), e.stateKey(), e.content()};
}),
a.initialState);
auto job = m.job<CreateRoomJob>().make(
visibility,
a.roomAliasName,
a.name,
a.topic,
a.invite,
DEFVAL, // invite3pid, not supported yet
a.roomVersion,
a.creationContent,
initialState,
preset,
a.isDirect,
a.powerLevelContentOverride);
m.addJob(std::move(job));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, CreateRoomResponse r)
{
if (! r.success()) {
kzo.client.dbg() << "Create room failed" << std::endl;
m.addTrigger(CreateRoomFailed{r.errorCode(), r.errorMessage()});
return { std::move(m), failWithResponse(r) };
}
m.addTrigger(CreateRoomSuccessful{r.roomId()});
return { std::move(m), lager::noop };
}
ClientResult updateClient(ClientModel m, InviteToRoomAction a)
{
auto job = m.job<InviteUserJob>()
.make(a.roomId, a.userId)
.withData(json{
{"roomId", a.roomId},
{"userId", a.userId},
});
m.addJob(std::move(job));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, InviteUserResponse r)
{
auto roomId = r.dataStr("roomId");
auto userId = r.dataStr("userId");
if (! r.success()) {
// Error
kzo.client.warn() << "Error inviting user " << r.errorCode() << r.errorMessage() << std::endl;
m.addTrigger(InviteUserFailed{roomId, userId, r.errorCode(), r.errorMessage()});
return { std::move(m), failWithResponse(r) };
}
kzo.client.info() << "Inviting user successful" << std::endl;
m.addTrigger(InviteUserSuccessful{roomId, userId});
return { std::move(m), lager::noop };
}
ClientResult updateClient(ClientModel m, JoinRoomAction a)
{
+ /// HACK: wait for real boost::url
+ auto encodedId = a.roomIdOrAlias;
+ if (!encodedId.empty() && encodedId[0] == '#') {
+ encodedId.replace(0, 1, "%23");
+ }
+
auto job = m.job<JoinRoomJob>()
- .make(a.roomIdOrAlias, a.serverName)
+ .make(encodedId, a.serverName)
.withData(json{{"roomIdOrAlias", a.roomIdOrAlias}});
m.addJob(std::move(job));
return { m, lager::noop };
}
ClientResult processResponse(ClientModel m, JoinRoomResponse r)
{
auto roomIdOrAlias = r.dataStr("roomIdOrAlias");
if (! r.success()) {
m.addTrigger(JoinRoomFailed{
roomIdOrAlias,
r.errorCode(),
r.errorMessage()
});
kzo.client.warn() << "Error joining room" << r.errorCode() << r.errorMessage() << std::endl;
return { std::move(m), failWithResponse(r) };
}
kzo.client.info() << "Successfully joined room" << std::endl;
m.addTrigger(JoinRoomSuccessful{roomIdOrAlias});
return { std::move(m), lager::noop};
}
ClientResult updateClient(ClientModel m, JoinRoomByIdAction a)
{
auto job = m.job<JoinRoomByIdJob>()
.make(a.roomId)
.withData(json{{"roomIdOrAlias", a.roomId}});
m.addJob(std::move(job));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, JoinRoomByIdResponse r)
{
auto roomIdOrAlias = r.dataStr("roomIdOrAlias");
if (! r.success()) {
m.addTrigger(JoinRoomFailed{
roomIdOrAlias,
r.errorCode(),
r.errorMessage()
});
kzo.client.warn() << "Error joining room" << r.errorCode() << r.errorMessage() << std::endl;
return { std::move(m), failWithResponse(r) };
}
kzo.client.info() << "Successfully joined room" << std::endl;
m.addTrigger(JoinRoomSuccessful{roomIdOrAlias});
return { std::move(m), lager::noop};
}
ClientResult updateClient(ClientModel m, LeaveRoomAction a)
{
auto job = m.job<LeaveRoomJob>()
.make(a.roomId)
.withData(json{{"roomId", a.roomId}});
m.addJob(std::move(job));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, LeaveRoomResponse r)
{
auto roomId = r.dataStr("roomId");
if (! r.success()) {
m.addTrigger(LeaveRoomFailed{
roomId,
r.errorCode(),
r.errorMessage()
});
kzo.client.warn() << "Error leaving room" << r.errorCode() << r.errorMessage() << std::endl;
return { std::move(m), failWithResponse(r) };
}
kzo.client.info() << "Successfully left room" << std::endl;
m.addTrigger(LeaveRoomSuccessful{roomId});
return { std::move(m), lager::noop};
}
ClientResult updateClient(ClientModel m, ForgetRoomAction a)
{
auto job = m.job<ForgetRoomJob>()
.make(a.roomId)
.withData(json{{"roomId", a.roomId}});
m.addJob(std::move(job));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, ForgetRoomResponse r)
{
auto roomId = r.dataStr("roomId");
if (! r.success()) {
m.addTrigger(ForgetRoomFailed{
roomId,
r.errorCode(),
r.errorMessage()
});
kzo.client.warn() << "Error forgetting room" << r.errorCode() << r.errorMessage() << std::endl;
return { std::move(m), failWithResponse(r) };
}
kzo.client.info() << "Successfully forgot room" << std::endl;
m.addTrigger(ForgetRoomSuccessful{roomId});
return { std::move(m), lager::noop};
}
ClientResult updateClient(ClientModel m, KickAction a)
{
m.addJob(m.job<KickJob>().make(a.roomId, a.userId, a.reason));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, KickResponse r)
{
if (!r.success()) {
kzo.client.warn() << "Error kicking" << r.errorCode() << r.errorMessage() << std::endl;
return { std::move(m), failWithResponse(r) };
}
return { std::move(m), lager::noop };
}
ClientResult updateClient(ClientModel m, BanAction a)
{
m.addJob(m.job<BanJob>().make(a.roomId, a.userId, a.reason));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, BanResponse r)
{
if (!r.success()) {
kzo.client.warn() << "Error banning" << r.errorCode() << r.errorMessage() << std::endl;
return { std::move(m), failWithResponse(r) };
}
return { std::move(m), lager::noop };
}
ClientResult updateClient(ClientModel m, UnbanAction a)
{
m.addJob(m.job<UnbanJob>().make(a.roomId, a.userId));
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, UnbanResponse r)
{
if (!r.success()) {
kzo.client.warn() << "Error unbanning" << r.errorCode() << r.errorMessage() << std::endl;
return { std::move(m), failWithResponse(r) };
}
return { std::move(m), lager::noop };
}
};
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 5bc1d5c..82922e4 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -1,55 +1,56 @@
include(CTest)
set(KAZVTEST_RESPATH ${CMAKE_CURRENT_SOURCE_DIR}/resources)
configure_file(kazvtest-respath.hpp.in kazvtest-respath.hpp)
add_executable(kazvtest
testmain.cpp
basejobtest.cpp
event-test.cpp
cursorutiltest.cpp
base/serialization-test.cpp
base/types-test.cpp
client/client-test-util.cpp
client/discovery-test.cpp
client/sync-test.cpp
client/content-test.cpp
client/paginate-test.cpp
client/util-test.cpp
client/serialization-test.cpp
client/encrypted-file-test.cpp
client/sdk-test.cpp
client/thread-safety-test.cpp
client/room-test.cpp
client/random-generator-test.cpp
client/profile-test.cpp
client/kick-test.cpp
client/ban-test.cpp
+ client/join-test.cpp
client/keys-test.cpp
client/room/room-actions-test.cpp
kazvjobtest.cpp
event-emitter-test.cpp
crypto-test.cpp
crypto/deterministic-test.cpp
promise-test.cpp
store-test.cpp
file-desc-test.cpp
)
target_include_directories(
kazvtest
PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(kazvtest
PRIVATE Catch2::Catch2WithMain
PRIVATE kazv
PRIVATE kazveventemitter
PRIVATE kazvjob
PRIVATE nlohmann_json::nlohmann_json
PRIVATE immer
PRIVATE lager
PRIVATE zug)
diff --git a/src/tests/client/join-test.cpp b/src/tests/client/join-test.cpp
new file mode 100644
index 0000000..ac17766
--- /dev/null
+++ b/src/tests/client/join-test.cpp
@@ -0,0 +1,42 @@
+/*
+ * This file is part of libkazv.
+ * SPDX-FileCopyrightText: 2021-2023 tusooa <tusooa@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libkazv-config.hpp>
+
+#include <catch2/catch_all.hpp>
+#include <boost/asio.hpp>
+#include <asio-promise-handler.hpp>
+#include <cursorutil.hpp>
+#include <sdk-model.hpp>
+#include <client/client.hpp>
+
+#include "client-test-util.hpp"
+
+TEST_CASE("Send join job with alias", "[client][membership]")
+{
+ ClientModel loggedInModel = createTestClientModel();
+ auto [resModel, dontCareEffect] = ClientModel::update(
+ loggedInModel, JoinRoomAction{"#room:example.com", {}});
+
+ assert1Job(resModel);
+ for1stJob(resModel, [] (const auto &job) {
+ REQUIRE(job.jobId() == "JoinRoom");
+ REQUIRE(job.url().find("%23room:example.com") != std::string::npos);
+ });
+}
+
+TEST_CASE("Send join job with id", "[client][membership]")
+{
+ ClientModel loggedInModel = createTestClientModel();
+ auto [resModel, dontCareEffect] = ClientModel::update(
+ loggedInModel, JoinRoomAction{"!room:example.com", {}});
+
+ assert1Job(resModel);
+ for1stJob(resModel, [] (const auto &job) {
+ REQUIRE(job.jobId() == "JoinRoom");
+ REQUIRE(job.url().find("!room:example.com") != std::string::npos);
+ });
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Jan 20, 12:02 AM (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55535
Default Alt Text
(12 KB)
Attached To
Mode
rL libkazv
Attached
Detach File
Event Timeline
Log In to Comment