#include #include #include #include "Event.h" #include "RoomEvent.h" #include "StateEvent.h" #include "AliasesEventContent.h" #include "AvatarEventContent.h" #include "CanonicalAliasEventContent.h" #include "CreateEventContent.h" #include "HistoryVisibilityEventContent.h" #include "JoinRulesEventContent.h" #include "MemberEventContent.h" #include "NameEventContent.h" #include "PowerLevelsEventContent.h" #include "TopicEventContent.h" using namespace matrix::events; TEST(BaseEvent, Deserialization) { // NameEventContent auto data = QJsonObject{ { "content", QJsonObject{ { "name", "Room Name" } } }, { "type", "m.room.name" } }; Event name_event; name_event.deserialize(data); EXPECT_EQ(name_event.content().name(), "Room Name"); EXPECT_EQ(name_event.serialize(), data); // TopicEventContent data = QJsonObject{ { "content", QJsonObject{ { "topic", "Room Topic" } } }, { "type", "m.room.topic" } }; Event topic_event; topic_event.deserialize(data); EXPECT_EQ(topic_event.content().topic(), "Room Topic"); EXPECT_EQ(topic_event.serialize(), data); // AvatarEventContent data = QJsonObject{ { "content", QJsonObject{ { "url", "https://matrix.org" } } }, { "type", "m.room.avatar" } }; Event avatar_event; avatar_event.deserialize(data); EXPECT_EQ(avatar_event.content().url().toString(), "https://matrix.org"); EXPECT_EQ(avatar_event.serialize(), data); // AliasesEventContent data = QJsonObject{ { "content", QJsonObject{ { "aliases", QJsonArray{ "#test:matrix.org", "#test2:matrix.org" } } } }, { "type", "m.room.aliases" } }; Event aliases_event; aliases_event.deserialize(data); EXPECT_EQ(aliases_event.content().aliases().size(), 2); EXPECT_EQ(aliases_event.serialize(), data); // CreateEventContent data = QJsonObject{ { "content", QJsonObject{ { "creator", "@alice:matrix.org" } } }, { "type", "m.room.create" } }; Event create_event; create_event.deserialize(data); EXPECT_EQ(create_event.content().creator(), "@alice:matrix.org"); EXPECT_EQ(create_event.serialize(), data); // JoinRulesEventContent data = QJsonObject{ { "content", QJsonObject{ { "join_rule", "private" } } }, { "type", "m.room.join_rules" } }; Event join_rules_event; join_rules_event.deserialize(data); EXPECT_EQ(join_rules_event.content().joinRule(), JoinRule::Private); EXPECT_EQ(join_rules_event.serialize(), data); } TEST(BaseEvent, DeserializationException) { auto data = QJsonObject{ { "content", QJsonObject{ { "rule", "private" } } }, { "type", "m.room.join_rules" } }; Event event1; ASSERT_THROW(event1.deserialize(data), DeserializationException); data = QJsonObject{ { "contents", QJsonObject{ { "join_rule", "private" } } }, { "type", "m.room.join_rules" } }; Event event2; ASSERT_THROW(event2.deserialize(data), DeserializationException); } TEST(RoomEvent, Deserialization) { auto data = QJsonObject{ { "content", QJsonObject{ { "name", "Name" } } }, { "event_id", "$asdfafdf8af:matrix.org" }, { "room_id", "!aasdfaeae23r9:matrix.org" }, { "sender", "@alice:matrix.org" }, { "origin_server_ts", 1323238293289323LL }, { "type", "m.room.name" } }; RoomEvent event; event.deserialize(data); EXPECT_EQ(event.eventId(), "$asdfafdf8af:matrix.org"); EXPECT_EQ(event.roomId(), "!aasdfaeae23r9:matrix.org"); EXPECT_EQ(event.sender(), "@alice:matrix.org"); EXPECT_EQ(event.timestamp(), 1323238293289323); EXPECT_EQ(event.content().name(), "Name"); EXPECT_EQ(event.serialize(), data); } TEST(RoomEvent, DeserializationException) { auto data = QJsonObject{ { "content", QJsonObject{ { "name", "Name" } } }, { "event_id", "$asdfafdf8af:matrix.org" }, { "room_id", "!aasdfaeae23r9:matrix.org" }, { "origin_server_ts", 1323238293289323LL }, { "type", "m.room.name" } }; RoomEvent event; try { event.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("sender key is missing", e.what()); } } TEST(StateEvent, Deserialization) { auto data = QJsonObject{ { "content", QJsonObject{ { "name", "Name" } } }, { "event_id", "$asdfafdf8af:matrix.org" }, { "state_key", "some_state_key" }, { "prev_content", QJsonObject{ { "name", "Previous Name" } } }, { "room_id", "!aasdfaeae23r9:matrix.org" }, { "sender", "@alice:matrix.org" }, { "origin_server_ts", 1323238293289323LL }, { "type", "m.room.name" } }; StateEvent event; event.deserialize(data); EXPECT_EQ(event.eventId(), "$asdfafdf8af:matrix.org"); EXPECT_EQ(event.roomId(), "!aasdfaeae23r9:matrix.org"); EXPECT_EQ(event.sender(), "@alice:matrix.org"); EXPECT_EQ(event.timestamp(), 1323238293289323); EXPECT_EQ(event.content().name(), "Name"); EXPECT_EQ(event.stateKey(), "some_state_key"); EXPECT_EQ(event.previousContent().name(), "Previous Name"); EXPECT_EQ(event.serialize(), data); } TEST(StateEvent, DeserializationException) { auto data = QJsonObject{ { "content", QJsonObject{ { "name", "Name" } } }, { "event_id", "$asdfafdf8af:matrix.org" }, { "prev_content", QJsonObject{ { "name", "Previous Name" } } }, { "room_id", "!aasdfaeae23r9:matrix.org" }, { "sender", "@alice:matrix.org" }, { "origin_server_ts", 1323238293289323LL }, { "type", "m.room.name" } }; StateEvent event; try { event.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("state_key key is missing", e.what()); } } TEST(EventType, Mapping) { EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.aliases" } }), EventType::RoomAliases); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.avatar" } }), EventType::RoomAvatar); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.canonical_alias" } }), EventType::RoomCanonicalAlias); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.create" } }), EventType::RoomCreate); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.history_visibility" } }), EventType::RoomHistoryVisibility); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.join_rules" } }), EventType::RoomJoinRules); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.member" } }), EventType::RoomMember); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.message" } }), EventType::RoomMessage); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.name" } }), EventType::RoomName); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.power_levels" } }), EventType::RoomPowerLevels); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.topic" } }), EventType::RoomTopic); EXPECT_EQ(extractEventType(QJsonObject{ { "type", "m.room.unknown" } }), EventType::Unsupported); } TEST(AliasesEventContent, Deserialization) { auto data = QJsonObject{ { "aliases", QJsonArray{ "#test:matrix.org", "#test2:matrix.org" } } }; AliasesEventContent content; content.deserialize(data); EXPECT_EQ(content.aliases().size(), 2); EXPECT_EQ(content.serialize(), data); } TEST(AliasesEventContent, NotAnObject) { auto data = QJsonArray{ "#test:matrix.org", "#test2:matrix.org" }; AliasesEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(AliasesEventContent, MissingKey) { auto data = QJsonObject{ { "key", QJsonArray{ "#test:matrix.org", "#test2:matrix.org" } } }; AliasesEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("aliases key is missing", e.what()); } } TEST(AvatarEventContent, Deserialization) { auto data = QJsonObject{ { "url", "https://matrix.org/avatar.png" } }; AvatarEventContent content; content.deserialize(data); EXPECT_EQ(content.url().toString(), "https://matrix.org/avatar.png"); EXPECT_EQ(content.serialize(), data); } TEST(AvatarEventContent, NotAnObject) { auto data = QJsonArray{ "key", "url" }; AvatarEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(AvatarEventContent, MissingKey) { auto data = QJsonObject{ { "key", "https://matrix.org" } }; AvatarEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("url key is missing", e.what()); } } TEST(CreateEventContent, Deserialization) { auto data = QJsonObject{ { "creator", "@alice:matrix.org" } }; CreateEventContent content; content.deserialize(data); EXPECT_EQ(content.creator(), "@alice:matrix.org"); EXPECT_EQ(content.serialize(), data); } TEST(CreateEventContent, NotAnObject) { auto data = QJsonArray{ "creator", "alice" }; CreateEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(CreateEventContent, MissingKey) { auto data = QJsonObject{ { "key", "@alice:matrix.org" } }; CreateEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("creator key is missing", e.what()); } } TEST(HistoryVisibilityEventContent, Deserialization) { auto data = QJsonObject{ { "history_visibility", "invited" } }; HistoryVisibilityEventContent content; content.deserialize(data); EXPECT_EQ(content.historyVisibility(), HistoryVisibility::Invited); data = QJsonObject{ { "history_visibility", "joined" } }; content.deserialize(data); EXPECT_EQ(content.historyVisibility(), HistoryVisibility::Joined); data = QJsonObject{ { "history_visibility", "shared" } }; content.deserialize(data); EXPECT_EQ(content.historyVisibility(), HistoryVisibility::Shared); data = QJsonObject{ { "history_visibility", "world_readable" } }; content.deserialize(data); EXPECT_EQ(content.historyVisibility(), HistoryVisibility::WorldReadable); } TEST(HistoryVisibilityEventContent, NotAnObject) { auto data = QJsonArray{ "history_visibility", "alice" }; HistoryVisibilityEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(HistoryVisibilityEventContent, InvalidHistoryVisibility) { auto data = QJsonObject{ { "history_visibility", "wrong" } }; HistoryVisibilityEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("Unknown history_visibility value: wrong", e.what()); } } TEST(HistoryVisibilityEventContent, MissingKey) { auto data = QJsonObject{ { "key", "joined" } }; HistoryVisibilityEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("history_visibility key is missing", e.what()); } } TEST(JoinRulesEventContent, Deserialization) { auto data = QJsonObject{ { "join_rule", "invite" } }; JoinRulesEventContent content; content.deserialize(data); EXPECT_EQ(content.joinRule(), JoinRule::Invite); data = QJsonObject{ { "join_rule", "knock" } }; content.deserialize(data); EXPECT_EQ(content.joinRule(), JoinRule::Knock); data = QJsonObject{ { "join_rule", "private" } }; content.deserialize(data); EXPECT_EQ(content.joinRule(), JoinRule::Private); data = QJsonObject{ { "join_rule", "public" } }; content.deserialize(data); EXPECT_EQ(content.joinRule(), JoinRule::Public); } TEST(JoinRulesEventContent, NotAnObject) { auto data = QJsonArray{ "rule", "alice" }; JoinRulesEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(JoinRulesEventContent, InvalidHistoryVisibility) { auto data = QJsonObject{ { "join_rule", "wrong" } }; JoinRulesEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("Unknown join_rule value: wrong", e.what()); } } TEST(JoinRulesEventContent, MissingKey) { auto data = QJsonObject{ { "key", "invite" } }; JoinRulesEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("join_rule key is missing", e.what()); } } TEST(CanonicalAliasEventContent, Deserialization) { auto data = QJsonObject{ { "alias", "Room Alias" } }; CanonicalAliasEventContent content; content.deserialize(data); EXPECT_EQ(content.alias(), "Room Alias"); EXPECT_EQ(content.serialize(), data); } TEST(CanonicalAliasEventContent, NotAnObject) { auto data = QJsonArray{ "alias", "Room Alias" }; CanonicalAliasEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(CanonicalAliasEventContent, MissingKey) { auto data = QJsonObject{ { "key", "alias" } }; CanonicalAliasEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("alias key is missing", e.what()); } } TEST(MemberEventContent, Deserialization) { MemberEventContent content; auto data = QJsonObject{ { "membership", "join" } }; content.deserialize(data); EXPECT_EQ(content.membershipState(), Membership::Join); data = QJsonObject{ { "membership", "invite" }, { "displayname", "Username" } }; content.deserialize(data); EXPECT_EQ(content.membershipState(), Membership::Invite); EXPECT_EQ(content.displayName(), "Username"); data = QJsonObject{ { "membership", "leave" }, { "avatar_url", "https://matrix.org" } }; content.deserialize(data); EXPECT_EQ(content.membershipState(), Membership::Leave); EXPECT_EQ(content.avatarUrl().toString(), "https://matrix.org"); data = QJsonObject{ { "membership", "ban" } }; content.deserialize(data); EXPECT_EQ(content.membershipState(), Membership::Ban); data = QJsonObject{ { "membership", "knock" } }; content.deserialize(data); EXPECT_EQ(content.membershipState(), Membership::Knock); } TEST(MemberEventContent, InvalidMembership) { auto data = QJsonObject{ { "membership", "wrong" } }; MemberEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("Unknown membership value: wrong", e.what()); } } TEST(MemberEventContent, NotAnObject) { auto data = QJsonArray{ "name", "join" }; MemberEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(MemberEventContent, MissingName) { auto data = QJsonObject{ { "key", "random" } }; MemberEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("membership key is missing", e.what()); } } TEST(NameEventContent, Deserialization) { auto data = QJsonObject{ { "name", "Room Name" } }; NameEventContent content; content.deserialize(data); EXPECT_EQ(content.name(), "Room Name"); EXPECT_EQ(content.serialize(), data); } TEST(NameEventContent, NotAnObject) { auto data = QJsonArray{ "name", "Room Name" }; NameEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(NameEventContent, MissingName) { auto data = QJsonObject{ { "key", "Room Name" } }; NameEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("name key is missing", e.what()); } } TEST(PowerLevelsEventContent, DefaultValues) { PowerLevelsEventContent power_levels; EXPECT_EQ(power_levels.banLevel(), static_cast(PowerLevels::Moderator)); EXPECT_EQ(power_levels.inviteLevel(), static_cast(PowerLevels::Moderator)); EXPECT_EQ(power_levels.kickLevel(), static_cast(PowerLevels::Moderator)); EXPECT_EQ(power_levels.redactLevel(), static_cast(PowerLevels::Moderator)); EXPECT_EQ(power_levels.eventsDefaultLevel(), static_cast(PowerLevels::User)); EXPECT_EQ(power_levels.usersDefaultLevel(), static_cast(PowerLevels::User)); EXPECT_EQ(power_levels.stateDefaultLevel(), static_cast(PowerLevels::Moderator)); // Default levels. EXPECT_EQ(power_levels.userLevel("@joe:matrix.org"), static_cast(PowerLevels::User)); EXPECT_EQ(power_levels.eventLevel("m.room.message"), static_cast(PowerLevels::User)); } TEST(PowerLevelsEventContent, FullDeserialization) { auto data = QJsonObject{ { "ban", 1 }, { "invite", 2 }, { "kick", 3 }, { "redact", 4 }, { "events_default", 5 }, { "state_default", 6 }, { "users_default", 7 }, { "events", QJsonObject{ { "m.message.text", 8 }, { "m.message.image", 9 } } }, { "users", QJsonObject{ { "@alice:matrix.org", 10 }, { "@bob:matrix.org", 11 } } }, }; PowerLevelsEventContent power_levels; power_levels.deserialize(data); EXPECT_EQ(power_levels.banLevel(), 1); EXPECT_EQ(power_levels.inviteLevel(), 2); EXPECT_EQ(power_levels.kickLevel(), 3); EXPECT_EQ(power_levels.redactLevel(), 4); EXPECT_EQ(power_levels.eventsDefaultLevel(), 5); EXPECT_EQ(power_levels.stateDefaultLevel(), 6); EXPECT_EQ(power_levels.usersDefaultLevel(), 7); EXPECT_EQ(power_levels.userLevel("@alice:matrix.org"), 10); EXPECT_EQ(power_levels.userLevel("@bob:matrix.org"), 11); EXPECT_EQ(power_levels.userLevel("@carl:matrix.org"), 7); EXPECT_EQ(power_levels.eventLevel("m.message.text"), 8); EXPECT_EQ(power_levels.eventLevel("m.message.image"), 9); EXPECT_EQ(power_levels.eventLevel("m.message.gif"), 5); EXPECT_EQ(power_levels.serialize(), data); } TEST(PowerLevelsEventContent, PartialDeserialization) { auto data = QJsonObject{ { "ban", 1 }, { "invite", 2 }, { "events_default", 5 }, { "users_default", 7 }, { "users", QJsonObject{ { "@alice:matrix.org", 10 }, { "@bob:matrix.org", 11 } } }, }; PowerLevelsEventContent power_levels; power_levels.deserialize(data); EXPECT_EQ(power_levels.banLevel(), 1); EXPECT_EQ(power_levels.inviteLevel(), 2); EXPECT_EQ(power_levels.kickLevel(), static_cast(PowerLevels::Moderator)); EXPECT_EQ(power_levels.redactLevel(), static_cast(PowerLevels::Moderator)); EXPECT_EQ(power_levels.eventsDefaultLevel(), 5); EXPECT_EQ(power_levels.stateDefaultLevel(), static_cast(PowerLevels::Moderator)); EXPECT_EQ(power_levels.usersDefaultLevel(), 7); EXPECT_EQ(power_levels.userLevel("@alice:matrix.org"), 10); EXPECT_EQ(power_levels.userLevel("@bob:matrix.org"), 11); EXPECT_EQ(power_levels.userLevel("@carl:matrix.org"), 7); EXPECT_EQ(power_levels.eventLevel("m.message.text"), 5); EXPECT_EQ(power_levels.eventLevel("m.message.image"), 5); EXPECT_EQ(power_levels.eventLevel("m.message.gif"), 5); } TEST(PowerLevelsEventContent, NotAnObject) { auto data = QJsonArray{ "test", "test2" }; PowerLevelsEventContent power_levels; ASSERT_THROW(power_levels.deserialize(data), DeserializationException); } TEST(TopicEventContent, Deserialization) { auto data = QJsonObject{ { "topic", "Room Topic" } }; TopicEventContent content; content.deserialize(data); EXPECT_EQ(content.topic(), "Room Topic"); EXPECT_EQ(content.serialize(), data); } TEST(TopicEventContent, NotAnObject) { auto data = QJsonArray{ "topic", "Room Topic" }; TopicEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); } TEST(TopicEventContent, MissingName) { auto data = QJsonObject{ { "key", "Room Name" } }; TopicEventContent content; ASSERT_THROW(content.deserialize(data), DeserializationException); try { content.deserialize(data); } catch (const DeserializationException &e) { ASSERT_STREQ("topic key is missing", e.what()); } }