Skip to content
Snippets Groups Projects
Verified Commit 1f91a792 authored by Nicolas Werner's avatar Nicolas Werner
Browse files

Add space types

parent 585e9401
No related branches found
No related tags found
No related merge requests found
Pipeline #1198 passed
......@@ -166,6 +166,7 @@ target_sources(matrix_client
lib/structs/events/presence.cpp
lib/structs/events/reaction.cpp
lib/structs/events/redaction.cpp
lib/structs/events/spaces.cpp
lib/structs/events/tag.cpp
lib/structs/events/tombstone.cpp
lib/structs/events/topic.cpp
......
......@@ -27,6 +27,7 @@
#include "mtx/events/presence.hpp"
#include "mtx/events/reaction.hpp"
#include "mtx/events/redaction.hpp"
#include "mtx/events/spaces.hpp"
#include "mtx/events/tag.hpp"
#include "mtx/events/tombstone.hpp"
#include "mtx/events/topic.hpp"
......@@ -94,6 +95,8 @@ using StateEvents = std::variant<events::StateEvent<states::Aliases>,
events::StateEvent<states::Name>,
events::StateEvent<states::PinnedEvents>,
events::StateEvent<states::PowerLevels>,
events::StateEvent<states::space::Child>,
events::StateEvent<states::space::Parent>,
events::StateEvent<states::Tombstone>,
events::StateEvent<states::Topic>,
events::StateEvent<msgs::Redacted>,
......@@ -112,6 +115,8 @@ using StrippedEvents = std::variant<events::StrippedEvent<states::Aliases>,
events::StrippedEvent<states::Name>,
events::StrippedEvent<states::PinnedEvents>,
events::StrippedEvent<states::PowerLevels>,
events::StrippedEvent<states::space::Child>,
events::StrippedEvent<states::space::Parent>,
events::StrippedEvent<states::Tombstone>,
events::StrippedEvent<states::Topic>,
events::StrippedEvent<Unknown>>;
......@@ -130,6 +135,8 @@ using TimelineEvents = std::variant<events::StateEvent<states::Aliases>,
events::StateEvent<states::Name>,
events::StateEvent<states::PinnedEvents>,
events::StateEvent<states::PowerLevels>,
events::StateEvent<states::space::Child>,
events::StateEvent<states::space::Parent>,
events::StateEvent<states::Tombstone>,
events::StateEvent<states::Topic>,
events::StateEvent<msc2545::ImagePack>,
......@@ -262,6 +269,14 @@ constexpr inline EventType state_content_to_type<mtx::events::state::PowerLevels
template<>
constexpr inline EventType state_content_to_type<mtx::events::state::Tombstone> =
EventType::RoomTombstone;
template<>
constexpr inline EventType state_content_to_type<mtx::events::state::space::Child> =
EventType::SpaceChild;
template<>
constexpr inline EventType state_content_to_type<mtx::events::state::space::Parent> =
EventType::SpaceParent;
template<>
constexpr inline EventType state_content_to_type<mtx::events::state::Topic> = EventType::RoomTopic;
template<>
......
......@@ -23,6 +23,12 @@ struct PreviousRoom
std::string event_id;
};
//! Definitions of different room types.
namespace room_type {
//! The room type for a space.
constexpr std::string_view space = "m.space";
}
//! Content of the `m.room.create` event.
//
//! This is the first event in a room and cannot be changed.
......@@ -32,6 +38,9 @@ struct Create
//! The `user_id` of the room creator. This is set by the homeserver.
std::string creator;
//! The room type, for example `m.space` for spaces.
std::optional<std::string> type;
//! Whether users on other servers can join this room.
//! Defaults to **true** if key does not exist.
bool federate = true;
......
......@@ -82,6 +82,12 @@ enum class EventType
Presence,
// m.push_rules
PushRules,
// m.space.child
SpaceChild,
// m.space.parent
SpaceParent,
// m.call.invite
CallInvite,
// m.call.candidates
......
#pragma once
/// @file
/// @brief Space related events to make child and parent relations
#include <optional>
#if __has_include(<nlohmann/json_fwd.hpp>)
#include <nlohmann/json_fwd.hpp>
#else
#include <nlohmann/json.hpp>
#endif
namespace mtx {
namespace events {
namespace state {
//! Namespace for space related state events.
namespace space {
/// @brief Event to point at a parent space from a room or space
///
/// To avoid abuse where a room admin falsely claims that a room is part of a space that it
/// should not be, clients could ignore such m.space.parent events unless either (a) there
/// is a corresponding m.space.child event in the claimed parent, or (b) the sender of the
/// m.space.child event has a sufficient power-level to send such an m.space.child event in
/// the parent. (It is not necessarily required that that user currently be a member of the
/// parent room - only the m.room.power_levels event is inspected.)
struct Parent
{
/// @brief Servers to join the parent space via.
///
/// Needs to contain at least one server.
std::optional<std::vector<std::string>> via;
/// @brief Determines whether this is the main parent for the space.
///
/// When a user joins a room with a canonical parent, clients may switch to view the room in
/// the context of that space, peeking into it in order to find other rooms and group them
/// together. In practice, well behaved rooms should only have one canonical parent, but
/// given this is not enforced: if multiple are present the client should select the one
/// with the lowest room ID, as determined via a lexicographic ordering of the Unicode
/// code-points.
bool canonical = false;
};
void
from_json(const nlohmann::json &obj, Parent &child);
void
to_json(nlohmann::json &obj, const Parent &child);
/// @brief Event to point at a child room or space from a parent space
///
/// The admins of a space can advertise rooms and subspaces for their space by setting m.space.child
/// state events. The state_key is the ID of a child room or space, and the content must contain a
/// via key which gives a list of candidate servers that can be used to join the room.
struct Child
{
/// @brief Servers to join the child room/space via.
///
/// Needs to contain at least one server.
std::optional<std::vector<std::string>> via;
/// @brief A string which is used to provide a default ordering of siblings in the room
/// list.
///
/// Rooms are sorted based on a lexicographic ordering of the Unicode codepoints of the
/// characters in order values. Rooms with no order come last, in ascending numeric order of
/// the origin_server_ts of their m.room.create events, or ascending lexicographic order of
/// their room_ids in case of equal origin_server_ts. orders which are not strings, or do
/// not consist solely of ascii characters in the range \x20 (space) to \x7E (~), or consist
/// of more than 50 characters, are forbidden and the field should be ignored if received.
std::optional<std::string> order;
};
void
from_json(const nlohmann::json &obj, Child &child);
void
to_json(nlohmann::json &obj, const Child &child);
}
}
}
}
......@@ -698,6 +698,8 @@ MTXCLIENT_SEND_STATE_EVENT_FWD(state::PinnedEvents)
MTXCLIENT_SEND_STATE_EVENT_FWD(state::PowerLevels)
MTXCLIENT_SEND_STATE_EVENT_FWD(state::Tombstone)
MTXCLIENT_SEND_STATE_EVENT_FWD(state::Topic)
MTXCLIENT_SEND_STATE_EVENT_FWD(state::space::Child)
MTXCLIENT_SEND_STATE_EVENT_FWD(state::space::Parent)
MTXCLIENT_SEND_STATE_EVENT_FWD(msc2545::ImagePack)
#define MTXCLIENT_SEND_ROOM_MESSAGE_FWD(Content) \
......
......@@ -1449,6 +1449,8 @@ MTXCLIENT_SEND_STATE_EVENT(state::PinnedEvents)
MTXCLIENT_SEND_STATE_EVENT(state::PowerLevels)
MTXCLIENT_SEND_STATE_EVENT(state::Tombstone)
MTXCLIENT_SEND_STATE_EVENT(state::Topic)
MTXCLIENT_SEND_STATE_EVENT(state::space::Child)
MTXCLIENT_SEND_STATE_EVENT(state::space::Parent)
MTXCLIENT_SEND_STATE_EVENT(msc2545::ImagePack)
#define MTXCLIENT_SEND_ROOM_MESSAGE(Content) \
......
......@@ -72,6 +72,12 @@ getEventType(const std::string &type)
return EventType::RoomTombstone;
else if (type == "m.sticker")
return EventType::Sticker;
else if (type == "m.space.child")
return EventType::SpaceChild;
else if (type == "m.space.parent")
return EventType::SpaceParent;
else if (type == "m.tag")
return EventType::Tag;
else if (type == "m.presence")
......@@ -174,6 +180,12 @@ to_string(EventType type)
return "m.room.tombstone";
case EventType::Sticker:
return "m.sticker";
case EventType::SpaceChild:
return "m.space.child";
case EventType::SpaceParent:
return "m.space.parent";
case EventType::Tag:
return "m.tag";
case EventType::Presence:
......
......@@ -25,6 +25,8 @@ MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, states::PinnedEvents)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, states::PowerLevels)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, states::Tombstone)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, states::Topic)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, states::space::Child)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, states::space::Parent)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, msgs::Redacted)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, msc2545::ImagePack)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, Unknown)
......@@ -68,6 +70,8 @@ MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, states::PinnedEvents
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, states::PowerLevels)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, states::Tombstone)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, states::Topic)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, states::space::Child)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, states::space::Parent)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, Unknown)
MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, msgs::Encrypted)
......@@ -185,6 +189,14 @@ from_json(const json &obj, TimelineEvent &e)
e.data = events::StateEvent<Topic>(obj);
break;
}
case events::EventType::SpaceChild: {
e.data = events::StateEvent<space::Child>(obj);
break;
}
case events::EventType::SpaceParent: {
e.data = events::StateEvent<space::Parent>(obj);
break;
}
case events::EventType::ImagePackInRoom: {
e.data = events::StateEvent<msc2545::ImagePack>(obj);
break;
......
......@@ -28,6 +28,9 @@ from_json(const json &obj, Create &create)
{
create.creator = obj.at("creator");
if (obj.contains("type") && obj.at("type").is_string())
create.type = obj.at("type");
if (obj.find("m.federate") != obj.end())
create.federate = obj.at("m.federate").get<bool>();
......@@ -51,6 +54,8 @@ to_json(json &obj, const Create &create)
else
obj["room_version"] = create.room_version;
if (create.type)
obj["type"] = create.type.value();
if (create.predecessor)
obj["predecessor"] = *create.predecessor;
}
......
#include "mtx/events/spaces.hpp"
#include <string>
#include <nlohmann/json.hpp>
namespace mtx {
namespace events {
namespace state {
namespace space {
void
from_json(const nlohmann::json &obj, Parent &parent)
{
if (obj.contains("canonical") && obj.at("canonical").is_boolean())
parent.canonical = obj.at("canonical").get<bool>();
if (obj.contains("via") && obj.at("via").is_array() && !obj.at("via").empty())
parent.via = obj.at("via").get<std::vector<std::string>>();
}
void
to_json(nlohmann::json &obj, const Parent &parent)
{
// event without via is invalid.
if (!parent.via.has_value() || parent.via.value().empty())
return;
obj["via"] = parent.via.value();
if (parent.canonical)
obj["canonical"] = true;
}
static bool
is_valid_order_str(std::string_view order)
{
if (order.size() > 50)
return false;
for (auto c : order)
if (c < '\x20' || c > '\x7E')
return false;
return true;
}
void
from_json(const nlohmann::json &obj, Child &child)
{
if (obj.contains("via") && obj.at("via").is_array() && !obj.at("via").empty())
child.via = obj.at("via").get<std::vector<std::string>>();
if (obj.contains("order") && obj.at("order").is_string() &&
is_valid_order_str(obj.at("order").get<std::string>()))
child.order = obj.at("order").get<std::string>();
}
void
to_json(nlohmann::json &obj, const Child &child)
{
// event without via is invalid.
if (!child.via.has_value() || child.via.value().empty())
return;
obj["via"] = child.via.value();
if (child.order && is_valid_order_str(child.order.value()))
obj["order"] = child.order.value();
}
}
} // namespace state
} // namespace events
} // namespace mtx
......@@ -176,6 +176,8 @@ parse_room_account_data_events(
case events::EventType::RoomRedaction:
case events::EventType::RoomTombstone:
case events::EventType::RoomTopic:
case events::EventType::SpaceChild:
case events::EventType::SpaceParent:
case events::EventType::Sticker:
case events::EventType::CallInvite:
case events::EventType::CallCandidates:
......@@ -354,6 +356,24 @@ parse_timeline_events(const json &events,
break;
}
case events::EventType::SpaceChild: {
try {
container.emplace_back(events::StateEvent<space::Child>(e));
} catch (json::exception &err) {
log_error(err, e);
}
break;
}
case events::EventType::SpaceParent: {
try {
container.emplace_back(events::StateEvent<space::Parent>(e));
} catch (json::exception &err) {
log_error(err, e);
}
break;
}
case events::EventType::ImagePackInRoom: {
try {
container.emplace_back(
......@@ -930,6 +950,24 @@ parse_state_events(const json &events,
break;
}
case events::EventType::SpaceChild: {
try {
container.emplace_back(events::StateEvent<space::Child>(e));
} catch (json::exception &err) {
log_error(err, e);
}
break;
}
case events::EventType::SpaceParent: {
try {
container.emplace_back(events::StateEvent<space::Parent>(e));
} catch (json::exception &err) {
log_error(err, e);
}
break;
}
case events::EventType::ImagePackInRoom: {
try {
container.emplace_back(
......@@ -1106,6 +1144,24 @@ parse_stripped_events(const json &events,
break;
}
case events::EventType::SpaceChild: {
try {
container.emplace_back(events::StrippedEvent<space::Child>(e));
} catch (json::exception &err) {
log_error(err, e);
}
break;
}
case events::EventType::SpaceParent: {
try {
container.emplace_back(events::StrippedEvent<space::Parent>(e));
} catch (json::exception &err) {
log_error(err, e);
}
break;
}
case events::EventType::Unsupported: {
try {
container.emplace_back(events::StrippedEvent<events::Unknown>(e));
......
......@@ -108,6 +108,8 @@ TEST(Events, Conversions)
EXPECT_EQ("m.room.tombstone", ns::to_string(ns::EventType::RoomTombstone));
EXPECT_EQ("m.room.redaction", ns::to_string(ns::EventType::RoomRedaction));
EXPECT_EQ("m.room.pinned_events", ns::to_string(ns::EventType::RoomPinnedEvents));
EXPECT_EQ("m.space.child", ns::to_string(ns::EventType::SpaceChild));
EXPECT_EQ("m.space.parent", ns::to_string(ns::EventType::SpaceParent));
EXPECT_EQ("m.tag", ns::to_string(ns::EventType::Tag));
}
......@@ -276,6 +278,71 @@ TEST(StateEvents, Create)
EXPECT_EQ(event.content.predecessor->event_id, "$something:example.org");
}
TEST(StateEvents, CreateWithType)
{
json data = R"({
"origin_server_ts": 1506761923948,
"sender": "@mujx:matrix.org",
"event_id": "$15067619231414398jhvQC:matrix.org",
"unsigned": {
"age": 3715756343
},
"state_key": "",
"content": {
"creator": "@mujx:matrix.org",
"type": "m.space"
},
"type": "m.room.create"
})"_json;
ns::StateEvent<ns::state::Create> event = data;
EXPECT_EQ(event.type, ns::EventType::RoomCreate);
EXPECT_EQ(event.event_id, "$15067619231414398jhvQC:matrix.org");
EXPECT_EQ(event.sender, "@mujx:matrix.org");
EXPECT_EQ(event.unsigned_data.age, 3715756343L);
EXPECT_EQ(event.origin_server_ts, 1506761923948L);
EXPECT_EQ(event.state_key, "");
EXPECT_EQ(event.content.creator, "@mujx:matrix.org");
EXPECT_TRUE(event.content.type.has_value());
EXPECT_EQ(event.content.type.value(), ns::state::room_type::space);
json example_from_spec = R"({
"content": {
"creator": "@example:example.org",
"m.federate": true,
"predecessor": {
"event_id": "$something:example.org",
"room_id": "!oldroom:example.org"
},
"room_version": "1"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1432735824653,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"state_key": "",
"type": "m.room.create",
"unsigned": {
"age": 1234
}
})"_json;
event = example_from_spec;
EXPECT_EQ(event.type, ns::EventType::RoomCreate);
EXPECT_EQ(event.event_id, "$143273582443PhrSn:example.org");
EXPECT_EQ(event.sender, "@example:example.org");
EXPECT_EQ(event.unsigned_data.age, 1234);
EXPECT_EQ(event.origin_server_ts, 1432735824653L);
EXPECT_EQ(event.state_key, "");
EXPECT_EQ(event.content.creator, "@example:example.org");
EXPECT_EQ(event.content.federate, true);
EXPECT_EQ(event.content.room_version, "1");
EXPECT_EQ(event.content.predecessor->room_id, "!oldroom:example.org");
EXPECT_EQ(event.content.predecessor->event_id, "$something:example.org");
}
TEST(StateEvents, GuestAccess)
{
json data = R"({
......@@ -717,6 +784,302 @@ TEST(StateEvents, Topic)
EXPECT_EQ(event.content.topic, "Test topic");
}
TEST(StateEvents, SpaceChild)
{
json data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!abcd:example.com",
"content": {
"via": ["example.com", "test.org"]
}
}
)"_json;
ns::StateEvent<ns::state::space::Child> event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceChild);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!abcd:example.com");
ASSERT_TRUE(event.content.via.has_value());
std::vector<std::string> via{"example.com", "test.org"};
EXPECT_EQ(event.content.via, via);
EXPECT_FALSE(event.content.order.has_value());
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!efgh:example.com",
"content": {
"via": ["example.com"],
"order": "abcd"
}
}
)"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceChild);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!efgh:example.com");
ASSERT_TRUE(event.content.via.has_value());
std::vector<std::string> via2{"example.com"};
EXPECT_EQ(event.content.via, via2);
ASSERT_TRUE(event.content.order.has_value());
ASSERT_EQ(event.content.order, "abcd");
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!jklm:example.com",
"content": {}
}
)"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceChild);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!jklm:example.com");
ASSERT_FALSE(event.content.via.has_value());
ASSERT_FALSE(event.content.order.has_value());
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!efgh:example.com",
"content": {
"via": ["example.com"],
"order": "01234567890123456789012345678901234567890123456789_"
}
}
)"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceChild);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!efgh:example.com");
EXPECT_TRUE(event.content.via.has_value());
ASSERT_FALSE(event.content.order.has_value());
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!efgh:example.com",
"content": {
"via": [],
"order": "01234567890123456789012345678901234567890123456789_"
}
}
)"_json;
event = data;
EXPECT_FALSE(event.content.via.has_value());
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!efgh:example.com",
"content": {
"via": 5,
"order": "01234567890123456789012345678901234567890123456789_"
}
}
)"_json;
event = data;
EXPECT_FALSE(event.content.via.has_value());
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!efgh:example.com",
"content": {
"via": null,
"order": "01234567890123456789012345678901234567890123456789_"
}
}
)"_json;
event = data;
EXPECT_FALSE(event.content.via.has_value());
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.child",
"state_key": "!efgh:example.com",
"content": {
"order": "01234567890123456789012345678901234567890123456789_"
}
}
)"_json;
event = data;
EXPECT_FALSE(event.content.via.has_value());
}
TEST(StateEvents, SpaceParent)
{
json data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.parent",
"state_key": "!space:example.com",
"content": {
"via": ["example.com"],
"canonical": true
}
})"_json;
ns::StateEvent<ns::state::space::Parent> event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceParent);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!space:example.com");
ASSERT_TRUE(event.content.via.has_value());
std::vector<std::string> via{"example.com"};
EXPECT_EQ(event.content.via, via);
EXPECT_TRUE(event.content.canonical);
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.parent",
"state_key": "!space:example.com",
"content": {
"via": ["example.org"]
}
})"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceParent);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!space:example.com");
EXPECT_TRUE(event.content.via.has_value());
EXPECT_FALSE(event.content.canonical);
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.parent",
"state_key": "!space:example.com",
"content": {
"via": [],
"canonical": true
}
})"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceParent);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!space:example.com");
EXPECT_FALSE(event.content.via.has_value());
EXPECT_TRUE(event.content.canonical);
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.parent",
"state_key": "!space:example.com",
"content": {
"via": null,
"canonical": true
}
})"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceParent);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!space:example.com");
EXPECT_FALSE(event.content.via.has_value());
EXPECT_TRUE(event.content.canonical);
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.parent",
"state_key": "!space:example.com",
"content": {
"via": 5,
"canonical": true
}
})"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceParent);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!space:example.com");
EXPECT_FALSE(event.content.via.has_value());
EXPECT_TRUE(event.content.canonical);
data = R"({
"origin_server_ts": 1510476064445,
"sender": "@nheko_test:matrix.org",
"event_id": "$15104760642668662QICBu:matrix.org",
"type": "m.space.parent",
"state_key": "!space:example.com",
"content": {
"via": "adjsa",
"canonical": true
}
})"_json;
event = data;
EXPECT_EQ(event.type, ns::EventType::SpaceParent);
EXPECT_EQ(event.event_id, "$15104760642668662QICBu:matrix.org");
EXPECT_EQ(event.sender, "@nheko_test:matrix.org");
EXPECT_EQ(event.origin_server_ts, 1510476064445);
EXPECT_EQ(event.state_key, "!space:example.com");
EXPECT_FALSE(event.content.via.has_value());
EXPECT_TRUE(event.content.canonical);
}
TEST(StateEvents, ImagePack)
{
json data = R"({
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment