Newer
Older
#include <boost/algorithm/string.hpp>
#include "mtx/events/collections.hpp"
#include "mtx/events/encrypted.hpp"
#include "mtx/requests.hpp"
#include "mtx/responses.hpp"
#include "mtxclient/http/client.hpp"
#include "test_helpers.hpp"
using namespace mtx::http;
using namespace mtx::events::collections;
using namespace mtx::requests;
TEST(ClientAPI, Register)
{
auto user = std::make_shared<Client>("localhost");
user->registration("alice", "secret", [](const mtx::responses::Register &, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_USER_IN_USE");
});
auto username = utils::random_token(10, false);
// Synapse converts the username to lowercase.
boost::algorithm::to_lower(username);
user->registration(
username, "secret", [user, username](const mtx::responses::Register &, RequestErr err) {
if (!err || err->matrix_error.unauthorized.flows.size() == 0)
EXPECT_EQ(err->matrix_error.unauthorized.flows.size(), 1);
EXPECT_EQ(err->matrix_error.unauthorized.flows[0].stages[0], "m.login.dummy");
{err->matrix_error.unauthorized.session, mtx::user_interactive::auth::Dummy{}},
[username](const mtx::responses::Register &res, RequestErr err) {
const auto user_id = "@" + username + ":localhost";
check_error(err);
EXPECT_EQ(res.user_id.to_string(), user_id);
});
TEST(ClientAPI, LoginSuccess)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login("alice", "secret", [](const mtx::responses::Login &res, RequestErr err) {
mtx_client->login("bob", "secret", [](const mtx::responses::Login &res, RequestErr err) {
mtx_client->login("carl", "secret", [](const mtx::responses::Login &res, RequestErr err) {
validate_login("@carl:localhost", res);
});
mtx_client->close();
}
TEST(ClientAPI, LoginWrongPassword)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login(
"alice", "wrong_password", [](const mtx::responses::Login &res, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_FORBIDDEN");
EXPECT_EQ(err->status_code, boost::beast::http::status::forbidden);
EXPECT_EQ(res.device_id, "");
EXPECT_EQ(res.access_token, "");
});
mtx_client->close();
}
TEST(ClientAPI, LoginWrongUsername)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login("john", "secret", [](const mtx::responses::Login &res, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_FORBIDDEN");
EXPECT_EQ(err->status_code, boost::beast::http::status::forbidden);
EXPECT_EQ(res.device_id, "");
EXPECT_EQ(res.access_token, "");
});
mtx_client->close();
}
TEST(ClientAPI, LoginFlows)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->get_login([](const mtx::responses::LoginFlows &res, RequestErr err) {
ASSERT_FALSE(err);
EXPECT_EQ(res.flows[0].type, mtx::user_interactive::auth_types::password);
});
mtx_client->close();
}
TEST(ClientAPI, SSORedirect)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
EXPECT_EQ(mtx_client->login_sso_redirect("http://aaa:555/sso"),
"https://localhost:443/_matrix/client/r0/login/sso/"
"redirect?redirectUrl=http%3A%2F%2Faaa%3A555%2Fsso");
TEST(ClientAPI, EmptyUserAvatar)
{
auto alice = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &res, RequestErr err) {
ASSERT_FALSE(err);
auto const alice_id = res.user_id;
alice->set_avatar_url("", [alice, alice_id](RequestErr err) {
ASSERT_FALSE(err);
auto done = false;
alice->get_profile(
alice_id.to_string(),
[&done](const mtx::responses::Profile &res, RequestErr err) {
ASSERT_FALSE(err);
ASSERT_TRUE(res.avatar_url.size() == 0);
done = true;
});
while (!done)
alice->get_avatar_url(
alice_id.to_string(),
[](const mtx::responses::AvatarUrl &res, RequestErr err) {
ASSERT_FALSE(err);
ASSERT_TRUE(res.avatar_url.size() == 0);
});
});
});
alice->close();
}
TEST(ClientAPI, RealUserAvatar)
{
auto alice = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &res, RequestErr err) {
ASSERT_FALSE(err);
auto const alice_id = res.user_id;
auto const avatar_url = "mxc://matrix.org/wefh34uihSDRGhw34";
alice->set_avatar_url(avatar_url, [alice, alice_id, avatar_url](RequestErr err) {
ASSERT_FALSE(err);
auto done = false;
alice->get_profile(
[avatar_url, &done](const mtx::responses::Profile &res, RequestErr err) {
ASSERT_FALSE(err);
ASSERT_TRUE(res.avatar_url == avatar_url);
done = true;
});
while (!done)
alice->get_avatar_url(
[avatar_url](const mtx::responses::AvatarUrl &res, RequestErr err) {
ASSERT_FALSE(err);
ASSERT_TRUE(res.avatar_url == avatar_url);
});
});
});
alice->close();
}
TEST(ClientAPI, ChangeDisplayName)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login(
"alice", "secret", [mtx_client](const mtx::responses::Login &, RequestErr err) {
// Change the display name to Arthur Dent and verify its success through the lack
// of an error
mtx_client->set_displayname("Arthur Dent",
[](RequestErr err) { check_error(err); });
});
mtx_client->close();
}
TEST(ClientAPI, EmptyDisplayName)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login(
"alice", "secret", [mtx_client](const mtx::responses::Login &, RequestErr err) {
// Change the display name to an empty string and verify its success through the
// lack of an error
mtx_client->set_displayname("", [](RequestErr err) { check_error(err); });
});
mtx_client->close();
}
TEST(ClientAPI, CreateRoom)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login(
"alice", "secret", [mtx_client](const mtx::responses::Login &, RequestErr err) {
while (mtx_client->access_token().empty())
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
mtx_client->create_room(req, [](const mtx::responses::CreateRoom &res, RequestErr err) {
ASSERT_TRUE(res.room_id.localpart().size() > 10);
EXPECT_EQ(res.room_id.hostname(), "localhost");
});
mtx_client->close();
}
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
TEST(ClientAPI, TagRoom)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login(
"alice", "secret", [mtx_client](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (mtx_client->access_token().empty())
sleep();
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
mtx_client->create_room(
req, [mtx_client](const mtx::responses::CreateRoom &res, RequestErr err) {
auto room_id = res.room_id;
check_error(err);
mtx_client->put_tag(
room_id.to_string(), "u.Test", {0.5}, [mtx_client, room_id](RequestErr err) {
check_error(err);
mtx_client->get_tags(
room_id.to_string(),
[mtx_client, room_id](mtx::events::account_data::Tags tags,
RequestErr err) {
check_error(err);
EXPECT_EQ(tags.tags.at("u.Test").order, 0.5);
mtx_client->delete_tag(
room_id.to_string(),
"u.Test",
[mtx_client, room_id](RequestErr err) {
check_error(err);
mtx_client->get_tags(
room_id.to_string(),
[mtx_client,
room_id](mtx::events::account_data::Tags tags,
RequestErr err) {
check_error(err);
EXPECT_EQ(tags.tags.count("u.Test"), 0);
});
});
});
});
});
mtx_client->close();
}
TEST(ClientAPI, LogoutSuccess)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
std::string token;
// Login and prove that login was successful by creating a room
mtx_client->login(
"alice", "secret", [&token](const mtx::responses::Login &res, RequestErr err) {
while (token.empty())
sleep();
mtx_client->set_access_token(token);
mtx::requests::CreateRoom req;
req.name = "Test1";
req.topic = "Topic1";
req, [](const mtx::responses::CreateRoom &, RequestErr err) { check_error(err); });
// Logout and prove that logout was successful and deleted the access_token_ for the client
mtx_client->logout([mtx_client, &token](const mtx::responses::Logout &, RequestErr err) {
while (token.size())
sleep();
// Verify that sending requests with this mtx_client fails after logout
mtx::requests::CreateRoom failReq;
failReq.name = "42";
failReq.topic = "LifeUniverseEverything";
mtx_client->create_room(failReq, [](const mtx::responses::CreateRoom &, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_MISSING_TOKEN");
});
mtx_client->close();
}
TEST(ClientAPI, LogoutInvalidatesTokenOnServer)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
std::string token;
// Login and prove that login was successful by creating a room
mtx_client->login(
"alice", "secret", [&token](const mtx::responses::Login &res, RequestErr err) {
while (token.empty())
sleep();
mtx_client->set_access_token(token);
mtx::requests::CreateRoom req;
req.name = "Test1";
req.topic = "Topic1";
req, [](const mtx::responses::CreateRoom &, RequestErr err) { check_error(err); });
// Logout and prove that logout was successful by verifying the old access_token_ is no
// longer valid
mtx_client->logout([mtx_client, &token](const mtx::responses::Logout &, RequestErr err) {
mtx_client->set_access_token(token);
token.clear();
});
while (token.size())
sleep();
// Verify that creating a room with the old access_token_ no longer succeeds after logout
mtx::requests::CreateRoom failReq;
failReq.name = "42";
failReq.topic = "LifeUniverseEverything";
mtx_client->create_room(failReq, [](const mtx::responses::CreateRoom &, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_UNKNOWN_TOKEN");
});
mtx_client->close();
}
TEST(ClientAPI, CreateRoomInvites)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
auto carl = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
carl->login("carl", "secret", [carl](const mtx::responses::Login &, RequestErr err) {
while (alice->access_token().empty() || bob->access_token().empty() ||
carl->access_token().empty())
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
req.invite = {"@bob:localhost", "@carl:localhost"};
alice->create_room(req, [bob, carl](const mtx::responses::CreateRoom &res, RequestErr err) {
auto room_id = res.room_id.to_string();
bob->join_room(room_id,
[](const nlohmann::json &, RequestErr err) { check_error(err); });
carl->join_room(room_id,
[](const nlohmann::json &, RequestErr err) { check_error(err); });
});
alice->close();
bob->close();
carl->close();
}
TEST(ClientAPI, JoinRoom)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
// Creating a random room alias.
// TODO: add a type for room aliases.
const auto alias = utils::random_token(20, false);
req.name = "Name";
req.topic = "Topic";
req.invite = {"@bob:localhost"};
req.room_alias_name = alias;
alice->create_room(
req, [bob, alias](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id.to_string();
bob->join_room(room_id,
[](const nlohmann::json &, RequestErr err) { check_error(err); });
using namespace mtx::identifiers;
bob->join_room(
"!random_room_id:localhost", [](const nlohmann::json &, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode),
"M_UNRECOGNIZED");
});
// Join the room using an alias.
bob->join_room("#" + alias + ":localhost",
[](const nlohmann::json &, RequestErr err) { check_error(err); });
});
TEST(ClientAPI, LeaveRoom)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
req.invite = {"@bob:localhost"};
alice->create_room(req, [bob](const mtx::responses::CreateRoom &res, RequestErr err) {
bob->join_room(res.room_id.to_string(),
[room_id, bob](const nlohmann::json &, RequestErr err) {
check_error(err);
bob->leave_room(room_id.to_string(),
[](const nlohmann::json &, RequestErr err) {
check_error(err);
});
});
});
// Trying to leave a non-existent room should fail.
bob->leave_room("!random_room_id:localhost", [](const nlohmann::json &, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_UNRECOGNIZED");
EXPECT_EQ(err->matrix_error.error, "Not a known room");
});
alice->close();
bob->close();
}
TEST(ClientAPI, InviteRoom)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
req.invite = {};
alice->create_room(
req, [alice, bob](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id.to_string();
alice->invite_user(room_id,
"@bob:localhost",
[room_id, bob](const mtx::responses::Empty &, RequestErr err) {
check_error(err);
bob->join_room(
room_id, [](const nlohmann::json &, RequestErr err) {
check_error(err);
});
});
});
alice->close();
bob->close();
}
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
TEST(ClientAPI, KickRoom)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
sleep();
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
req.invite = {};
alice->create_room(
req, [alice, bob](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id.to_string();
alice->invite_user(
room_id,
"@bob:localhost",
[room_id, alice, bob](const mtx::responses::Empty &, RequestErr err) {
check_error(err);
bob->join_room(
room_id, [alice, room_id](const nlohmann::json &, RequestErr err) {
check_error(err);
alice->kick_user(room_id,
"@bob:localhost",
[](const mtx::responses::Empty &,
RequestErr err) { check_error(err); });
});
});
});
alice->close();
bob->close();
}
TEST(ClientAPI, BanRoom)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
sleep();
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
req.invite = {};
alice->create_room(
req, [alice, bob](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id.to_string();
alice->invite_user(
room_id,
"@bob:localhost",
[room_id, alice, bob](const mtx::responses::Empty &, RequestErr err) {
check_error(err);
bob->join_room(
room_id, [alice, room_id](const nlohmann::json &, RequestErr err) {
check_error(err);
alice->ban_user(
room_id,
"@bob:localhost",
[alice, room_id](const mtx::responses::Empty &,
RequestErr err) {
check_error(err);
alice->unban_user(
room_id,
"@bob:localhost",
[](const mtx::responses::Empty &,
RequestErr err) { check_error(err); },
"You not bad anymore!");
},
"You bad!");
});
});
});
alice->close();
bob->close();
}
TEST(ClientAPI, InvalidInvite)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
req.invite = {};
alice->create_room(
req, [alice, bob](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id.to_string();
bob->invite_user(room_id,
"@carl:localhost",
[room_id, bob](const mtx::responses::Empty &, RequestErr err) {
ASSERT_TRUE(err);
EXPECT_EQ(
mtx::errors::to_string(err->matrix_error.errcode),
"M_FORBIDDEN");
});
});
alice->close();
bob->close();
}
TEST(ClientAPI, Sync)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->login(
"alice", "secret", [mtx_client](const mtx::responses::Login &, RequestErr err) {
while (mtx_client->access_token().empty())
mtx::requests::CreateRoom req;
req.name = "Name";
req.topic = "Topic";
mtx_client->create_room(
req, [mtx_client](const mtx::responses::CreateRoom &, RequestErr err) {
check_error(err);
SyncOpts opts;
opts.timeout = 0;
mtx_client->sync(opts, [](const mtx::responses::Sync &res, RequestErr err) {
check_error(err);
ASSERT_TRUE(res.rooms.join.size() > 0);
ASSERT_TRUE(res.next_batch.size() > 0);
});
TEST(ClientAPI, Versions)
{
std::shared_ptr<Client> mtx_client = std::make_shared<Client>("localhost");
mtx_client->versions([](const mtx::responses::Versions &res, RequestErr err) {
EXPECT_EQ(res.versions.size(), 6);
EXPECT_EQ(res.versions.at(0), "r0.0.1");
EXPECT_EQ(res.versions.at(1), "r0.1.0");
EXPECT_EQ(res.versions.at(2), "r0.2.0");
EXPECT_EQ(res.versions.at(3), "r0.3.0");
EXPECT_EQ(res.versions.at(4), "r0.4.0");
EXPECT_EQ(res.versions.at(5), "r0.5.0");
TEST(ClientAPI, Typing)
{
auto alice = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty())
mtx::requests::CreateRoom req;
alice->create_room(req, [alice](const mtx::responses::CreateRoom &res, RequestErr err) {
alice->start_typing(res.room_id.to_string(), 10000, [alice, res](RequestErr err) {
const auto room_id = res.room_id.to_string();
SyncOpts opts;
opts.timeout = 0;
alice->sync(opts,
[room_id, &can_continue](const mtx::responses::Sync &res,
RequestErr err) {
check_error(err);
auto room = res.rooms.join.at(room_id);
EXPECT_EQ(room.ephemeral.typing.size(), 1);
EXPECT_EQ(room.ephemeral.typing.front(),
"@alice:localhost");
});
while (!can_continue)
alice->stop_typing(
res.room_id.to_string(), [alice, room_id](RequestErr err) {
check_error(err);
SyncOpts opts;
opts.timeout = 0;
alice->sync(
opts,
[room_id](const mtx::responses::Sync &res, RequestErr err) {
check_error(err);
auto room = res.rooms.join.at(room_id);
EXPECT_EQ(room.ephemeral.typing.size(), 0);
});
});
});
});
alice->close();
}
TEST(ClientAPI, SendMessages)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
mtx::requests::CreateRoom req;
req.invite = {"@bob:localhost"};
alice->create_room(
req, [alice, bob](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id.to_string();
room_id, [alice, bob, room_id](const nlohmann::json &, RequestErr err) {
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
// Flag to indicate when those messages would be ready to be read by
// alice.
vector<string> event_ids;
mtx::events::msg::Text text;
text.body = "hello alice!";
bob->send_room_message<mtx::events::msg::Text,
mtx::events::EventType::RoomMessage>(
room_id,
text,
[&event_ids](const mtx::responses::EventId &res, RequestErr err) {
event_ids.push_back(res.event_id.to_string());
check_error(err);
});
mtx::events::msg::Emote emote;
emote.body = "*bob tests";
bob->send_room_message<mtx::events::msg::Emote,
mtx::events::EventType::RoomMessage>(
room_id,
emote,
[&event_ids](const mtx::responses::EventId &res, RequestErr err) {
event_ids.push_back(res.event_id.to_string());
check_error(err);
});
while (event_ids.size() != 2)
SyncOpts opts;
opts.timeout = 0;
alice->sync(opts,
[room_id, event_ids](const mtx::responses::Sync &res,
RequestErr err) {
check_error(err);
auto ids = get_event_ids<TimelineEvents>(
res.rooms.join.at(room_id).timeline.events);
// The sent event ids should be visible in the
// timeline.
for (const auto &event_id : event_ids)
ASSERT_TRUE(std::find(ids.begin(),
ids.end(),
event_id) !=
std::end(ids));
});
alice->close();
bob->close();
}
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
TEST(ClientAPI, RedactEvent)
{
auto alice = std::make_shared<Client>("localhost");
alice->login("alice", "secret", check_login);
while (alice->access_token().empty())
sleep();
mtx::requests::CreateRoom req;
alice->create_room(req, [alice](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id.to_string();
mtx::events::msg::Text text;
text.body = "hello alice!";
alice
->send_room_message<mtx::events::msg::Text, mtx::events::EventType::RoomMessage>(
room_id,
text,
[room_id, alice](const mtx::responses::EventId &res, RequestErr err) {
check_error(err);
alice->redact_event(
room_id,
res.event_id.to_string(),
[](const mtx::responses::EventId &res, RequestErr err) {
check_error(err);
ASSERT_FALSE(res.event_id.to_string().empty());
});
});
});
alice->close();
}
TEST(ClientAPI, SendStateEvents)
{
auto alice = std::make_shared<Client>("localhost");
auto bob = std::make_shared<Client>("localhost");
alice->login("alice", "secret", [alice](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
bob->login("bob", "secret", [bob](const mtx::responses::Login &, RequestErr err) {
check_error(err);
});
while (alice->access_token().empty() || bob->access_token().empty())
mtx::requests::CreateRoom req;
req.invite = {"@bob:localhost"};
alice->create_room(
req, [alice, bob](const mtx::responses::CreateRoom &res, RequestErr err) {
check_error(err);
auto room_id = res.room_id;
// Flag to indicate when those messages would be ready to be read by
// alice.
vector<string> event_ids;
mtx::events::state::Name event;
event.name = "Bob's room";
bob->send_state_event<mtx::events::state::Name, mtx::events::EventType::RoomName>(
room_id.to_string(),