Skip to content

Commit

Permalink
WiP
Browse files Browse the repository at this point in the history
  • Loading branch information
Premwoik committed Feb 9, 2022
1 parent a957367 commit 1cbc9f2
Show file tree
Hide file tree
Showing 13 changed files with 691 additions and 189 deletions.
228 changes: 228 additions & 0 deletions big_tests/tests/graphql_muc_light_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
-module(graphql_muc_light_SUITE).

-compile([export_all, nowarn_export_all]).

-import(distributed_helper, [mim/0, require_rpc_nodes/1, rpc/4]).
-import(graphql_helper, [execute/3, execute_auth/2, get_listener_port/1,
get_listener_config/1, get_ok_value/2, get_err_msg/1]).

-include_lib("common_test/include/ct.hrl").
-include_lib("jid/include/jid.hrl").
-include_lib("eunit/include/eunit.hrl").

suite() ->
require_rpc_nodes([mim]) ++ escalus:suite().

all() ->
[{group, user_muc_light},
{group, admin_muc_light}].

groups() ->
[{user_muc_light, [], user_muc_light_handler()},
{admin_muc_light, [], admin_muc_light_handler()}].

user_muc_light_handler() ->
[mock].

admin_muc_light_handler() ->
[admin_create_room,
admin_create_identified_room,
admin_change_room_configuration,
admin_invite_user,
admin_delete_room,
admin_kick_user
].

init_per_suite(Config) ->
Config1 = init_modules(Config),
[{muc_light_host, muc_light_helper:muc_host()}
| escalus:init_per_suite(Config1)].

end_per_suite(Config) ->
escalus_fresh:clean(),
dynamic_modules:restore_modules(Config),
escalus:end_per_suite(Config).

init_modules(Config) ->
HostType = domain_helper:host_type(),
Config1 = dynamic_modules:save_modules(HostType, Config),
Config2 = rest_helper:maybe_enable_mam(mam_helper:backend(), HostType, Config1),
dynamic_modules:ensure_modules(HostType, required_modules(suite)),
Config2.

required_modules(SuiteOrTC) ->
[{mod_muc_light, common_muc_light_opts() ++ muc_light_opts(SuiteOrTC)}].

muc_light_opts(config_can_be_changed_by_all) ->
[{all_can_configure, true}];
muc_light_opts(suite) ->
[].

common_muc_light_opts() ->
MucPattern = distributed_helper:subhost_pattern(muc_light_helper:muc_host_pattern()),
[{host, MucPattern},
{rooms_in_rosters, true}].

init_per_group(admin_muc_light, Config) ->
graphql_helper:init_admin_handler(Config);
init_per_group(_GN, Config) ->
Config.

end_per_group(_GN, Config) ->
Config.

init_per_testcase(TC, Config) ->
escalus:init_per_testcase(TC, Config).

end_per_testcase(TC, Config) ->

escalus:end_per_testcase(TC, Config).

mock(_Config) ->
ok.

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

admin_create_room_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
AliceBinLower = escalus_utils:jid_to_lower(AliceBin),
Domain = escalus_client:server(Alice),
MucServer = <<"muclight.", Domain/binary>>,
Name = <<"first room">>,
Subject = <<"testing">>,

Res = execute_auth(admin_create_room_body(Domain, Name, AliceBin, Subject, null), Config),
Path = [data, muc_light, createRoom],
#{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject,
<<"participants">> := Participants} = get_ok_value(Path, Res),
?assertMatch(#jid{server = MucServer}, jid:from_binary(JID)),
?assertEqual([#{<<"jid">> => AliceBinLower, <<"affiliance">> => <<"owner">>}], Participants).
% Try to create room with existing nam
%Res2 = execute_auth(admin_create_room_body(Domain, Name, AliceBin, Subject, null), Config),
%?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"already exists">>)).

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

admin_create_identified_room_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
Domain = escalus_client:server(Alice),
MucServer = <<"muclight.", Domain/binary>>,
Name = <<"first room">>,
Subject = <<"testing">>,
Id = <<"my_room">>,

Res = execute_auth(admin_create_room_body(Domain, Name, AliceBin, Subject, Id), Config),
Path = [data, muc_light, createRoom],
#{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} = get_ok_value(Path, Res),
?assertMatch(#jid{user = Id, server = MucServer}, jid:from_binary(JID)),
% Try to create room with existing ID
Res2 = execute_auth(admin_create_room_body(Domain, <<"snd room">>, AliceBin, Subject, Id), Config),
?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"already exists">>)).

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

admin_change_room_configuration_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
Domain = escalus_client:server(Alice),
Name = <<"first room">>,
Subject = <<"testing">>,
Id = atom_to_binary(?FUNCTION_NAME),
%% Create a new room
execute_auth(admin_create_room_body(Domain, Name, AliceBin, Subject, Id), Config),
%% Try to change the room configuration
Name2 = <<"changed room">>,
Subject2 = <<"not testing">>,
Res = execute_auth(admin_change_room_configuration_body(Id, Domain, AliceBin, Name2, Subject2), Config),
Path = [data, muc_light, changeRoomConfiguration],
?assertMatch(#{<<"name">> := Name2, <<"subject">> := Subject2}, get_ok_value(Path, Res)).


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

admin_invite_user_story(Config, Alice, Bob) ->
AliceBin = escalus_client:short_jid(Alice),
BobBin = escalus_client:short_jid(Bob),
Domain = escalus_client:server(Alice),
Name = <<"first room">>,
{ok, #{jid := RoomJID}} = create_room(<<>>, Domain, Name, <<>>, jid:from_binary(AliceBin)),
Res = execute_auth(admin_invite_user_body(Domain, Name, AliceBin, BobBin), Config),
?assertNotEqual(nomatch, binary:match(get_ok_value([data, muc_light, inviteUser], Res),
<<"successfully">>)),
BobName = escalus_utils:jid_to_lower(escalus_client:username(Bob)),
AliceName = escalus_utils:jid_to_lower(escalus_client:username(Alice)),
ExpectedAff = lists:sort([{{AliceName, Domain}, owner},
{{BobName, Domain}, member}]),
?assertMatch(ExpectedAff, lists:sort(get_room_aff(RoomJID))).

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

admin_delete_room_story(Config, Alice) ->
AliceBin = escalus_client:short_jid(Alice),
Domain = escalus_client:server(Alice),
Name = <<"first room">>,
RoomID = <<"delete_room_id">>,
{ok, #{jid := RoomJID}} = create_room(RoomID, Domain, Name, <<>>, jid:from_binary(AliceBin)),

Res = execute_auth(admin_delete_room_body(Domain, RoomID), Config),
?assertNotEqual(nomatch, binary:match(get_ok_value([data, muc_light, deleteRoom], Res),
<<"successfully">>)),
?assertEqual({error, not_exists}, get_room_info(jid:from_binary(RoomJID))).


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) ->
ok.


%% Helpers

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

get_room_info(JID) ->
HostType = domain_helper:host_type(),
RoomUS = jid:to_lus(JID),
rpc(mim(), mod_muc_light_db_backend, get_info, [HostType, RoomUS]).

get_room_aff(JID) ->
{ok, _, Aff, _} = get_room_info(JID),
Aff.

%% Request bodies

admin_create_room_body(Domain, Name, Owner, Subject, Id) ->
Query = <<"mutation M1($domain: String!, $name: String!, $owner: JID!, $subject: String!, $id: String)
{ muc_light { createRoom(domain: $domain, name: $name, owner: $owner, subject: $subject, id: $id)
{ jid name subject participants {jid affiliance} } } }">>,
OpName = <<"M1">>,
Vars = #{<<"domain">> => Domain, <<"name">> => Name, <<"owner">> => Owner, <<"subject">> => Subject, <<"id">> => Id},
#{query => Query, operationName => OpName, variables => Vars}.

admin_change_room_configuration_body(Id, Domain, Owner, Name, Subject) ->
Query = <<"mutation M1($id: String!, $domain: String!, $name: String!, $owner: JID!, $subject: String!)
{ muc_light { changeRoomConfiguration(id: $id, domain: $domain, name: $name, owner: $owner, subject: $subject)
{ jid name subject participants {jid affiliance} } } }">>,
OpName = <<"M1">>,
Vars = #{<<"id">> => Id, <<"domain">> => Domain, <<"name">> => Name, <<"owner">> => Owner, <<"subject">> => Subject},
#{query => Query, operationName => OpName, variables => Vars}.

admin_invite_user_body(Domain, Name, Sender, Recipient) ->
Query = <<"mutation M1($domain: String!, $name: String!, $sender: JID!, $recipient: JID!)
{ muc_light { inviteUser(domain: $domain, name: $name, sender: $sender, recipient: $recipient) } }">>,
OpName = <<"M1">>,
Vars = #{<<"domain">> => Domain, <<"name">> => Name, <<"sender">> => Sender, <<"recipient">> => Recipient},
#{query => Query, operationName => OpName, variables => Vars}.

admin_delete_room_body(Domain, RoomID) ->
Query = <<"mutation M1($domain: String!, $id: String!)
{ muc_light { deleteRoom(domain: $domain, id: $id)} }">>,
OpName = <<"M1">>,
Vars = #{<<"domain">> => Domain, <<"id">> => RoomID},
#{query => Query, operationName => OpName, variables => Vars}.
6 changes: 3 additions & 3 deletions big_tests/tests/rest_client_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ all() ->
{group, security}].

groups() ->
G = [{messages_with_props, [parallel], message_with_props_test_cases()},
_G = [{messages_with_props, [parallel], message_with_props_test_cases()},
{messages_with_thread, [parallel], message_with_thread_test_cases()},
{messages, [parallel], message_test_cases()},
{muc, [pararell], muc_test_cases()},
{muc_config, [], muc_config_cases()},
{roster, [parallel], roster_test_cases()},
{security, [], security_test_cases()}],
ct_helper:repeat_all_until_all_ok(G).
{security, [], security_test_cases()}].
%ct_helper:repeat_all_until_all_ok(G).

message_test_cases() ->
[msg_is_sent_and_delivered_over_xmpp,
Expand Down
4 changes: 4 additions & 0 deletions priv/graphql/schemas/admin/admin_schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ type AdminQuery{
session: SessionAdminQuery
"Stanza management"
stanza: StanzaAdminQuery
"MUC Light room management"
muc_light: MUCLightAdminQuery
}

"""
Expand All @@ -33,4 +35,6 @@ type AdminMutation @protected{
session: SessionAdminMutation
"Stanza management"
stanza: StanzaAdminMutation
"MUC Light room management"
muc_light: MUCLightAdminMutation
}
52 changes: 52 additions & 0 deletions priv/graphql/schemas/admin/muc_light.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
Allow admin to manage Multi-User Chat Light rooms.
"""
type MUCLightAdminMutation @protected{
"Create a MUC light room under the given XMPP hostname"
createRoom(domain: String!, name: String!, owner: JID!, subject: String!, id: String): Room
"Change configuration of MUC Light room"
changeRoomConfiguration(id: String!, domain: String!, name: String!, owner: JID!, subject: String!): Room
"Invite a user to a MUC Light room"
inviteUser(domain: String!, name: String!, sender: JID!, recipient: JID!): String
"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
"Send a message to a MUC Light room"
sendMessageToRoom(domain: String!, name: String!, from: JID!, body: String!): String
}

"""
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
"Get configuration of the MUC Light room"
getRoomConfig(domain: String!, name: String!): Room

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

type RoomPayload{
message: String!
room: Room
}

type Room{
jid: JID
name: String
subject: String
participants: [RoomUser!]
}

type RoomUser{
jid: JID
affiliance: String
}

enum Affiliance{
OWNER
MEMBER
NONE
}
2 changes: 2 additions & 0 deletions src/graphql/admin/mongoose_graphql_admin_mutation.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ execute(_Ctx, _Obj, <<"domains">>, _Args) ->
{ok, admin};
execute(_Ctx, _Obj, <<"account">>, _Args) ->
{ok, account};
execute(_Ctx, _Obj, <<"muc_light">>, _Args) ->
{ok, muc_light};
execute(_Ctx, _Obj, <<"session">>, _Opts) ->
{ok, session};
execute(_Ctx, _Obj, <<"stanza">>, _) ->
Expand Down
2 changes: 2 additions & 0 deletions src/graphql/admin/mongoose_graphql_admin_query.erl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ execute(_Ctx, _Obj, <<"domains">>, _Args) ->
{ok, admin};
execute(_Ctx, _Obj, <<"account">>, _Args) ->
{ok, account};
execute(_Ctx, _Obj, <<"muc_light">>, _Args) ->
{ok, muc_light};
execute(_Ctx, _Obj, <<"session">>, _Opts) ->
{ok, session};
execute(_Ctx, _Obj, <<"stanza">>, _Opts) ->
Expand Down
Loading

0 comments on commit 1cbc9f2

Please sign in to comment.