Skip to content

Commit

Permalink
WiP2
Browse files Browse the repository at this point in the history
  • Loading branch information
Premwoik committed Feb 15, 2022
1 parent 1cbc9f2 commit e407f89
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 27 deletions.
1 change: 1 addition & 0 deletions big_tests/default.spec
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
{suites, "tests", graphql_SUITE}.
{suites, "tests", graphql_account_SUITE}.
{suites, "tests", graphql_domain_SUITE}.
{suites, "tests", graphql_muc_light_SUITE}.
{suites, "tests", graphql_session_SUITE}.
{suites, "tests", graphql_stanza_SUITE}.
{suites, "tests", inbox_SUITE}.
Expand Down
4 changes: 2 additions & 2 deletions big_tests/dynamic_domains.spec
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@

{suites, "tests", graphql_SUITE}.
{suites, "tests", graphql_account_SUITE}.
{suites, "tests", graphql_domain_SUITE}.
{suites, "tests", graphql_muc_light_SUITE}.
{suites, "tests", graphql_session_SUITE}.
{suites, "tests", graphql_stanza_SUITE}.

{suites, "tests", graphql_domain_SUITE}.

{suites, "tests", inbox_SUITE}.

{suites, "tests", inbox_extensions_SUITE}.
Expand Down
154 changes: 153 additions & 1 deletion big_tests/tests/graphql_muc_light_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("jid/include/jid.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("exml/include/exml.hrl").

suite() ->
require_rpc_nodes([mim]) ++ escalus:suite().
Expand All @@ -30,7 +31,12 @@ admin_muc_light_handler() ->
admin_change_room_configuration,
admin_invite_user,
admin_delete_room,
admin_kick_user
admin_kick_user,
admin_send_message_to_room,
admin_get_room_messages,
admin_list_user_rooms,
admin_list_room_users,
admin_get_room_config
].

init_per_suite(Config) ->
Expand Down Expand Up @@ -178,14 +184,115 @@ admin_kick_user(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_kick_user_story/3).

admin_kick_user_story(Config, Alice, Bob) ->
AliceBin = escalus_client:short_jid(Alice),
BobBin = escalus_client:short_jid(Bob),
Domain = escalus_client:server(Alice),
RoomName = <<"first room">>,
RoomID = <<"kick_user_test_room">>,
{ok, #{jid := RoomJID}} = create_room(RoomID, Domain, RoomName, <<>>, jid:from_binary(AliceBin)),
{ok, _} = invite_user(Domain, RoomName, jid:from_binary(AliceBin), jid:from_binary(BobBin)),
?assertEqual(2, length(get_room_aff(RoomJID))),
Res = execute_auth(admin_kick_user_body(Domain, RoomID, BobBin), Config),
?assertNotEqual(nomatch, binary:match(get_ok_value([data, muc_light, kickUser], Res),
<<"successfully">>)),
?assertEqual(1, length(get_room_aff(RoomJID))).

admin_send_message_to_room(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_send_message_to_room_story/3).

admin_send_message_to_room_story(Config, Alice, Bob) ->
AliceBin = escalus_client:short_jid(Alice),
BobBin = escalus_client:short_jid(Bob),
Domain = escalus_client:server(Alice),
RoomName = <<"first room">>,
RoomID = <<"send_message_test_room">>,
{ok, #{jid := _RoomJID}} = create_room(RoomID, Domain, RoomName, <<>>, jid:from_binary(AliceBin)),
{ok, _} = invite_user(Domain, RoomName, jid:from_binary(AliceBin), jid:from_binary(BobBin)),

MsgBody = <<"Hello there!">>,
_Res = execute_auth(admin_send_message_to_room_body(Domain, RoomName, AliceBin, MsgBody), Config),
mam_helper:maybe_wait_for_archive(Config),
Messages = get_room_messages(RoomID, Domain),
?assertMatch([_, _], Messages),
ok.

admin_get_room_messages(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_get_room_messages_story/2).

admin_get_room_messages_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
Domain = escalus_client:server(Alice),
RoomName = <<"first room">>,
RoomID = <<"get_messages_test_room">>,
{ok, #{jid := _RoomJID}} = create_room(RoomID, Domain, RoomName, <<>>, jid:from_binary(AliceBin)),
Message = <<"Hello friends">>,
send_message_to_room(Domain, RoomName, jid:from_binary(AliceBin), Message),

Res = execute_auth(admin_get_room_messages_body(Domain, RoomID), Config),
[#{<<"stanza">> := StanzaXML}] = get_ok_value([data, muc_light, getRoomMessages, stanzas], Res),
?assertMatch({ok, #xmlel{name = <<"message">>}}, exml:parse(StanzaXML)).

admin_list_user_rooms(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_list_user_rooms_story/2).

admin_list_user_rooms_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
Domain = escalus_client:server(Alice),
RoomName = <<"first room">>,
RoomName2 = <<"second room">>,
{ok, #{jid := RoomJID}} = create_room(<<>>, Domain, RoomName, <<>>, jid:from_binary(AliceBin)),
{ok, #{jid := RoomJID2}} = create_room(<<>>, Domain, RoomName2, <<>>, jid:from_binary(AliceBin)),
Res = execute_auth(admin_list_user_rooms_body(AliceBin), Config),
?assertEqual(lists:sort([jid:to_binary(RoomJID), jid:to_binary(RoomJID2)]),
lists:sort(get_ok_value([data, muc_light, listUserRooms], Res))).

admin_list_room_users(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_list_room_users_story/2).

admin_list_room_users_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
AliceLower = escalus_utils:jid_to_lower(AliceBin),
Domain = escalus_client:server(Alice),
RoomName = <<"first room">>,
{ok, #{jid := #jid{luser = RoomID}}} = create_room(<<>>, Domain, RoomName, <<>>, jid:from_binary(AliceBin)),

Res = execute_auth(admin_list_room_users_body(Domain, RoomID), Config),
?assertEqual([#{<<"jid">> => AliceLower, <<"affiliance">> => <<"owner">>}],
get_ok_value([data, muc_light, listRoomUsers], Res)).

admin_get_room_config(Config) ->
escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_get_room_config_story/2).

admin_get_room_config_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
AliceLower = escalus_utils:jid_to_lower(AliceBin),
Domain = escalus_client:server(Alice),
RoomName = <<"first room">>,
RoomSubject = <<"Room about nothing">>,
{ok, #{jid := #jid{luser = RoomID} = RoomJID}} = create_room(<<>>, Domain, RoomName, RoomSubject, jid:from_binary(AliceBin)),

RoomJIDBin = jid:to_binary(RoomJID),
Res = execute_auth(admin_get_room_config_body(Domain, RoomID), Config),
?assertEqual(#{<<"jid">> => RoomJIDBin, <<"subject">> => RoomSubject, <<"name">> => RoomName,
<<"participants">> => [#{<<"jid">> => AliceLower, <<"affiliance">> => <<"owner">>}]},
get_ok_value([data, muc_light, getRoomConfig], Res)).

%% Helpers

send_message_to_room(Domain, RoomName, SenderJID, Message) ->
rpc(mim(), mod_muc_light_api, send_message, [Domain, RoomName, SenderJID, Message]).

get_room_messages(ID, Domain) ->
{ok, Messages} = rpc(mim(), mod_muc_light_api, get_room_messages, [Domain, ID]),
ct:log("~p", [Messages]),
Messages.

create_room(Id, Domain, Name, Subject, CreatorJID) ->
rpc(mim(), mod_muc_light_api, create_room, [Domain, Id, Name, CreatorJID, Subject]).

invite_user(Domain, RoomName, SenderJID, RecipientJID) ->
rpc(mim(), mod_muc_light_api, invite_to_room, [Domain, RoomName, SenderJID, RecipientJID]).

get_room_info(JID) ->
HostType = domain_helper:host_type(),
RoomUS = jid:to_lus(JID),
Expand Down Expand Up @@ -226,3 +333,48 @@ admin_delete_room_body(Domain, RoomID) ->
OpName = <<"M1">>,
Vars = #{<<"domain">> => Domain, <<"id">> => RoomID},
#{query => Query, operationName => OpName, variables => Vars}.

admin_kick_user_body(Domain, RoomID, User) ->
Query = <<"mutation M1($domain: String!, $id: String!, $user: JID!)
{ muc_light { kickUser(domain: $domain, id: $id, user: $user)} }">>,
OpName = <<"M1">>,
Vars = #{<<"domain">> => Domain, <<"id">> => RoomID, <<"user">> => User},
#{query => Query, operationName => OpName, variables => Vars}.

admin_send_message_to_room_body(Domain, RoomName, From, Body) ->
Query = <<"mutation M1($domain: String!, $name: String!, $from: JID!, $body: String!)
{ muc_light { sendMessageToRoom(domain: $domain, name: $name, from: $from, body: $body)} }">>,
OpName = <<"M1">>,
Vars = #{<<"domain">> => Domain, <<"name">> => RoomName, <<"from">> => From, <<"body">> => Body},
#{query => Query, operationName => OpName, variables => Vars}.

admin_get_room_messages_body(Domain, RoomID) ->
Query = <<"query Q1($domain: String!, $id: String!)
{ muc_light { getRoomMessages(domain: $domain, id: $id)
{ stanzas { stanza } } } }">>,
OpName = <<"Q1">>,
Vars = #{<<"domain">> => Domain, <<"id">> => RoomID},
#{query => Query, operationName => OpName, variables => Vars}.

admin_list_user_rooms_body(User) ->
Query = <<"query Q1($user: JID!)
{ muc_light { listUserRooms(user: $user) } }">>,
OpName = <<"Q1">>,
Vars = #{<<"user">> => User},
#{query => Query, operationName => OpName, variables => Vars}.

admin_list_room_users_body(Domain, RoomID) ->
Query = <<"query Q1($domain: String!, $id: String!)
{ muc_light { listRoomUsers(domain: $domain, id: $id)
{ jid affiliance } } }">>,
OpName = <<"Q1">>,
Vars = #{<<"domain">> => Domain, <<"id">> => RoomID},
#{query => Query, operationName => OpName, variables => Vars}.

admin_get_room_config_body(Domain, RoomID) ->
Query = <<"query Q1($domain: String!, $id: String!)
{ muc_light { getRoomConfig(domain: $domain, id: $id)
{ jid name subject participants {jid affiliance} } } }">>,
OpName = <<"Q1">>,
Vars = #{<<"domain">> => Domain, <<"id">> => RoomID},
#{query => Query, operationName => OpName, variables => Vars}.
13 changes: 8 additions & 5 deletions priv/graphql/schemas/admin/muc_light.gql
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type MUCLightAdminMutation @protected{
"Remove a MUC light room"
deleteRoom(id: String!, domain: String!): String
"Remove a user from a room"
kickUser(domain: String!, name: String!, kicker: JID!, kicked: JID!): String
kickUser(domain: String!, id: String!, user: JID!): String
"Send a message to a MUC Light room"
sendMessageToRoom(domain: String!, name: String!, from: JID!, body: String!): String
}
Expand All @@ -20,12 +20,15 @@ type MUCLightAdminMutation @protected{
Allow admin to get information about Multi-User Chat Light rooms.
"""
type MUCLightAdminQuery @protected{
"Get users list of MUC Light room"
listRoomUsers(domain: String!, name: String!): String
"Read messages"
getRoomMessages(domain: String!, id: String!): StanzasPayload
"Get configuration of the MUC Light room"
getRoomConfig(domain: String!, name: String!): Room
getRoomConfig(domain: String!, id: String!): Room
"Get users list of MUC Light room"
listRoomUsers(domain: String!, id: String!): [RoomUser!]
"Get the list of rooms that the given user participates in"
listUserRooms(user: JID!): [JID!]

#readMessages(domain: String!, name: String!)
}

type RoomPayload{
Expand Down
20 changes: 9 additions & 11 deletions src/graphql/admin/mongoose_graphql_muc_light_admin_mutation.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

-import(mongoose_graphql_helper, [make_error/2, format_result/2]).

-import(mongoose_graphql_muc_light_helper, [make_room/1, make_ok_user/1]).

execute(_Ctx, _Obj, <<"createRoom">>, Args) ->
create_room(Args);
execute(_Ctx, _Obj, <<"changeRoomConfiguration">>, Args) ->
Expand Down Expand Up @@ -48,19 +50,15 @@ invite_user(#{<<"domain">> := Domain, <<"name">> := Name, <<"sender">> := Sender
Result = mod_muc_light_api:invite_to_room(Domain, Name, SenderJID, RecipientJID),
format_result(Result, #{}).

kick_user(#{}) ->
{ok, <<"Not implemented">>}.
kick_user(#{<<"domain">> := Domain, <<"id">> := RoomID, <<"user">> := UserJID}) ->
Result = mod_muc_light_api:remove_user_from_room(Domain, RoomID, UserJID, UserJID),
format_result(Result, #{}).

send_msg_to_room(#{}) ->
{ok, <<"Not implemented">>}.
send_msg_to_room(#{<<"domain">> := Domain, <<"name">> := RoomName, <<"from">> := FromJID,
<<"body">> := Message}) ->
Result = mod_muc_light_api:send_message(Domain, RoomName, FromJID, Message),
format_result(Result, #{}).

%% Internal

-spec make_room(mod_muc_light_api:room()) -> map().
make_room(#{jid := JID, name := Name, subject := Subject, aff_users := Users}) ->
Participants = lists:map(fun make_ok_user/1, Users),
#{<<"jid">> => JID, <<"name">> => Name, <<"subject">> => Subject,
<<"participants">> => Participants}.

make_ok_user({JID, Aff}) ->
{ok, #{<<"jid">> => JID, <<"affiliance">> => atom_to_binary(Aff)}}.
60 changes: 55 additions & 5 deletions src/graphql/admin/mongoose_graphql_muc_light_admin_query.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,63 @@

-ignore_xref([execute/4]).

-include("../mongoose_graphql_types.hrl").

-import(mongoose_graphql_helper, [make_error/2, format_result/2]).

-import(mongoose_graphql_muc_light_helper, [make_room/1, make_ok_user/1]).

execute(_Ctx, _Obj, <<"listUserRooms">>, Args) ->
list_user_rooms(Args);
execute(_Ctx, _Obj, <<"listRoomUsers">>, Args) ->
list_room_users(Args);
execute(_Ctx, _Obj, <<"getRoomConfig">>, Args) ->
get_room_config(Args).
get_room_config(Args);
execute(_Ctx, _Obj, <<"getRoomMessages">>, Args) ->
get_room_messages(Args).

-spec list_user_rooms(map()) -> {ok, [binary()]} | {error, resolver_error()}.
list_user_rooms(#{<<"user">> := UserJID}) ->
case mod_muc_light_api:get_user_rooms(UserJID) of
{ok, Rooms} ->
{ok, [{ok, R} || R <- Rooms]};
Err ->
make_error(Err, #{})
end.

-spec list_room_users(map()) -> {ok, [map()]} | {error, resolver_error()}.
list_room_users(#{<<"domain">> := Domain, <<"id">> := RoomID}) ->
case mod_muc_light_api:get_room_aff(Domain, RoomID) of
{ok, Affs} ->
{ok, [make_ok_user(A) || A <- Affs]};
Err ->
make_error(Err, #{})
end.

-spec get_room_config(map()) -> {ok, map()} | {error, resolver_error()}.
get_room_config(#{<<"domain">> := Domain, <<"id">> := RoomID}) ->
case mod_muc_light_api:get_room_info(Domain, RoomID) of
{ok, Room} ->
{ok, make_room(Room)};
Err ->
make_error(Err, #{})
end.

-spec get_room_messages(map()) -> {ok, map()} | {error, resolver_error()}.
get_room_messages(#{<<"domain">> := Domain, <<"id">> := RoomID}) ->
case mod_muc_light_api:get_room_messages(Domain, RoomID) of
{ok, Rows} ->
Maps = lists:map(fun row_to_map/1, Rows),
{ok, #{<<"stanzas">> => Maps, <<"limit">> => 0}};
Err ->
make_error(Err, #{})
end.

list_room_users(#{}) ->
{ok, <<"Not implemented">>}.
-spec row_to_map(mod_mam:message_row()) -> {ok, map()}.
row_to_map(#{id := Id, jid := From, packet := Msg}) ->
{Microseconds, _} = mod_mam_utils:decode_compact_uuid(Id),
StanzaID = mod_mam_utils:mess_id_to_external_binary(Id),
Map = #{<<"sender">> => From, <<"timestamp">> => Microseconds,
<<"stanza_id">> => StanzaID, <<"stanza">> => Msg},
{ok, Map}.

get_room_config(#{}) ->
{ok, <<"Not implemented">>}.
3 changes: 2 additions & 1 deletion src/graphql/mongoose_graphql_errors.erl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ err(_Ctx, ErrorTerm) ->

%% callback invoked when resolver crashes
-spec crash(map(), term()) -> err_msg().
crash(_Ctx, #{type := Type}) ->
crash(_Ctx, #{type := Type} = E) ->
io:format("~p", [E]),
#{message => <<"Unexpected ", Type/binary, " resolver crash">>,
extensions => #{code => resolver_crash}}.

Expand Down
12 changes: 12 additions & 0 deletions src/graphql/mongoose_graphql_muc_light_helper.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-module(mongoose_graphql_muc_light_helper).

-export([make_room/1, make_ok_user/1]).

-spec make_room(mod_muc_light_api:room()) -> map().
make_room(#{jid := JID, name := Name, subject := Subject, aff_users := Users}) ->
Participants = lists:map(fun make_ok_user/1, Users),
#{<<"jid">> => JID, <<"name">> => Name, <<"subject">> => Subject,
<<"participants">> => Participants}.

make_ok_user({JID, Aff}) ->
{ok, #{<<"jid">> => JID, <<"affiliance">> => atom_to_binary(Aff)}}.
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ handle_request_by_method(<<"PUT">>,
Req, State) ->
mongoose_client_api_rooms:assert_room_id_set(Req, State),
#{user := User, jid := #jid{lserver = Server}, room_id := RoomID} = State,
mod_muc_light_commands:change_room_config(Server, RoomID, Name, User, Subject).
mod_muc_light_api:change_room_config(Server, RoomID, Name, User, Subject).
Loading

0 comments on commit e407f89

Please sign in to comment.