1: -module(graphql_muc_light_SUITE). 2: 3: -compile([export_all, nowarn_export_all]). 4: 5: -import(distributed_helper, [mim/0, require_rpc_nodes/1, rpc/4]). 6: -import(graphql_helper, [execute/3, execute_auth/2, get_listener_port/1, 7: get_listener_config/1, get_ok_value/2, get_err_msg/1, 8: make_creds/1]). 9: 10: -import(config_parser_helper, [mod_config/2]). 11: 12: -include_lib("common_test/include/ct.hrl"). 13: -include_lib("jid/include/jid.hrl"). 14: -include_lib("eunit/include/eunit.hrl"). 15: -include_lib("exml/include/exml.hrl"). 16: 17: -define(UNKNOWN_DOMAIN, <<"not-existing-domain">>). 18: -define(UNKNOWN, <<"not-existing">>). 19: 20: %% GraphQL Paths 21: -define(CREATE_ROOM_PATH, [data, muc_light, createRoom]). 22: -define(CHANGE_CONFIG_PATH, [data, muc_light, changeRoomConfiguration]). 23: -define(INVITE_USER_PATH, [data, muc_light, inviteUser]). 24: -define(KICK_USER_PATH, [data, muc_light, kickUser]). 25: -define(DELETE_ROOM_PATH, [data, muc_light, deleteRoom]). 26: -define(SEND_MESSAGE_PATH, [data, muc_light, sendMessageToRoom]). 27: -define(GET_MESSAGES_PATH, [data, muc_light, getRoomMessages]). 28: -define(LIST_USER_ROOMS_PATH, [data, muc_light, listUserRooms]). 29: -define(USER_LIST_ROOMS_PATH, [data, muc_light, listRooms]). 30: -define(LIST_ROOM_USERS_PATH, [data, muc_light, listRoomUsers]). 31: -define(GET_ROOM_CONFIG_PATH, [data, muc_light, getRoomConfig]). 32: -define(GET_BLOCKING_LIST_PATH, [data, muc_light, getBlockingList]). 33: -define(SET_BLOCKING_LIST_PATH, [data, muc_light, setBlockingList]). 34: 35: suite() -> 36: require_rpc_nodes([mim]) ++ escalus:suite(). 37: 38: all() -> 39: [{group, user_muc_light}, 40: {group, admin_muc_light}]. 41: 42: groups() -> 43: [{user_muc_light, [parallel], user_muc_light_handler()}, 44: {admin_muc_light, [parallel], admin_muc_light_handler()}]. 45: 46: user_muc_light_handler() -> 47: [user_create_room, 48: user_create_identified_room, 49: user_change_room_config, 50: user_change_room_config_errors, 51: user_invite_user, 52: user_invite_user_errors, 53: user_delete_room, 54: user_kick_user, 55: user_send_message_to_room, 56: user_send_message_to_room_errors, 57: user_get_room_messages, 58: user_list_rooms, 59: user_list_room_users, 60: user_get_room_config, 61: user_blocking_list 62: ]. 63: 64: admin_muc_light_handler() -> 65: [admin_create_room, 66: admin_create_identified_room, 67: admin_change_room_config, 68: admin_change_room_config_errors, 69: admin_invite_user, 70: admin_invite_user_errors, 71: admin_delete_room, 72: admin_kick_user, 73: admin_send_message_to_room, 74: admin_send_message_to_room_errors, 75: admin_get_room_messages, 76: admin_list_user_rooms, 77: admin_list_room_users, 78: admin_get_room_config, 79: admin_blocking_list 80: ]. 81: 82: init_per_suite(Config) -> 83: Config1 = init_modules(Config), 84: [{muc_light_host, muc_light_helper:muc_host()} 85: | escalus:init_per_suite(Config1)]. 86: 87: end_per_suite(Config) -> 88: escalus_fresh:clean(), 89: dynamic_modules:restore_modules(Config), 90: escalus:end_per_suite(Config). 91: 92: init_modules(Config) -> 93: HostType = domain_helper:host_type(), 94: Config1 = dynamic_modules:save_modules(HostType, Config), 95: Config2 = rest_helper:maybe_enable_mam(mam_helper:backend(), HostType, Config1), 96: dynamic_modules:ensure_modules(HostType, required_modules(suite)), 97: Config2. 98: 99: required_modules(_) -> 100: MucLightOpts = mod_config(mod_muc_light, #{rooms_in_rosters => true}), 101: [{mod_muc_light, MucLightOpts}]. 102: 103: init_per_group(admin_muc_light, Config) -> 104: graphql_helper:init_admin_handler(Config); 105: init_per_group(user_muc_light, Config) -> 106: [{schema_endpoint, user} | Config]. 107: 108: end_per_group(_GN, Config) -> 109: Config. 110: 111: init_per_testcase(TC, Config) -> 112: rest_helper:maybe_skip_mam_test_cases(TC, [user_get_room_messages, 113: admin_get_room_messages], Config). 114: 115: end_per_testcase(TC, Config) -> 116: escalus:end_per_testcase(TC, Config). 117: 118: %% User test cases 119: 120: user_create_room(Config) -> 121: escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_create_room_story/2). 122: 123: user_create_room_story(Config, Alice) -> 124: Ep = ?config(schema_endpoint, Config), 125: MucServer = ?config(muc_light_host, Config), 126: AliceBinLower = escalus_utils:jid_to_lower(escalus_client:short_jid(Alice)), 127: Creds = make_creds(Alice), 128: Name = <<"first room">>, 129: Subject = <<"testing">>, 130: Res = execute(Ep, user_create_room_body(MucServer, Name, Subject, null), Creds), 131: #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject, 132: <<"participants">> := Participants} = get_ok_value(?CREATE_ROOM_PATH, Res), 133: ?assertMatch(#jid{lserver = MucServer}, jid:from_binary(JID)), 134: ?assertEqual([#{<<"jid">> => AliceBinLower, <<"affiliation">> => <<"OWNER">>}], Participants), 135: % Try with a non-existent domain 136: Res2 = execute(Ep, user_create_room_body(?UNKNOWN_DOMAIN, Name, Subject, null), Creds), 137: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)). 138: 139: user_create_identified_room(Config) -> 140: escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_create_identified_room_story/2). 141: 142: user_create_identified_room_story(Config, Alice) -> 143: Ep = ?config(schema_endpoint, Config), 144: MucServer = ?config(muc_light_host, Config), 145: Creds = make_creds(Alice), 146: Name = <<"first room">>, 147: Subject = <<"testing">>, 148: Id = <<"my_user_room">>, 149: Res = execute(Ep, user_create_room_body(MucServer, Name, Subject, Id), Creds), 150: #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} = 151: get_ok_value(?CREATE_ROOM_PATH, Res), 152: ?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary(JID)), 153: % Create a room with an existing ID 154: Res2 = execute(Ep, user_create_room_body(MucServer, <<"snd room">>, Subject, Id), Creds), 155: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"already exists">>)), 156: % Try with a non-existent domain 157: Res3 = execute(Ep, user_create_room_body(?UNKNOWN_DOMAIN, <<"name">>, Subject, Id), Creds), 158: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)), 159: % Try with an empty string passed as ID 160: Res4 = execute(Ep, user_create_room_body(MucServer, <<"name">>, Subject, <<>>), Creds), 161: ?assertNotEqual(nomatch, binary:match(get_coertion_err_msg(Res4), <<"Given string is empty">>)). 162: 163: user_change_room_config(Config) -> 164: escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_change_room_config_story/2). 165: 166: user_change_room_config_story(Config, Alice) -> 167: AliceBin = escalus_client:short_jid(Alice), 168: Ep = ?config(schema_endpoint, Config), 169: MUCServer = ?config(muc_light_host, Config), 170: Creds = make_creds(Alice), 171: % Create a new room 172: {ok, #{jid := RoomJID}} = create_room(MUCServer, <<"ornithology">>, <<"birds">>, AliceBin), 173: % Try to change the room configuration 174: Name2 = <<"changed room">>, 175: Subject2 = <<"not testing">>, 176: Res = execute(Ep, user_change_room_configuration_body(jid:to_binary(RoomJID), Name2, Subject2), Creds), 177: ?assertMatch(#{<<"name">> := Name2, <<"subject">> := Subject2}, get_ok_value(?CHANGE_CONFIG_PATH, Res)). 178: 179: user_change_room_config_errors(Config) -> 180: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 181: fun user_change_room_config_errors_story/3). 182: 183: user_change_room_config_errors_story(Config, Alice, Bob) -> 184: Ep = ?config(schema_endpoint, Config), 185: MUCServer = ?config(muc_light_host, Config), 186: CredsAlice = make_creds(Alice), 187: CredsBob = make_creds(Bob), 188: AliceBin = escalus_client:short_jid(Alice), 189: BobBin = escalus_client:short_jid(Bob), 190: RoomName = <<"first room">>, 191: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 192: create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 193: % Try to change the config with a non-existent domain 194: Res = execute(Ep, user_change_room_configuration_body( 195: make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), RoomName, <<"subject2">>), CredsAlice), 196: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)), 197: % Try to change the config of the non-existent room 198: Res2 = execute(Ep, user_change_room_configuration_body( 199: make_bare_jid(?UNKNOWN, MUCServer), RoomName, <<"subject2">>), CredsAlice), 200: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 201: % Try to change the config by the user that does not occupy this room 202: Res3 = execute(Ep, user_change_room_configuration_body( 203: jid:to_binary(RoomJID), RoomName, <<"subject2">>), CredsBob), 204: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not occupy this room">>)), 205: % Try to change a config by the user without permission 206: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 207: Res4 = execute(Ep, user_change_room_configuration_body( 208: jid:to_binary(RoomJID), RoomName, <<"subject2">>), CredsBob), 209: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), 210: <<"does not have permission to change">>)). 211: 212: user_invite_user(Config) -> 213: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_invite_user_story/3). 214: 215: user_invite_user_story(Config, Alice, Bob) -> 216: Ep = ?config(schema_endpoint, Config), 217: MUCServer = ?config(muc_light_host, Config), 218: CredsAlice = make_creds(Alice), 219: AliceBin = escalus_client:short_jid(Alice), 220: BobBin = escalus_client:short_jid(Bob), 221: Domain = escalus_client:server(Alice), 222: Name = <<"first room">>, 223: {ok, #{jid := RoomJID}} = create_room(MUCServer, Name, <<"subject2">>, AliceBin), 224: % Room owner can invite a user 225: Res = execute(Ep, user_invite_user_body(jid:to_binary(RoomJID), BobBin), CredsAlice), 226: ?assertNotEqual(nomatch, binary:match(get_ok_value(?INVITE_USER_PATH, Res), 227: <<"successfully">>)), 228: escalus:wait_for_stanza(Bob), 229: BobName = escalus_utils:jid_to_lower(escalus_client:username(Bob)), 230: AliceName = escalus_utils:jid_to_lower(escalus_client:username(Alice)), 231: ExpectedAff = lists:sort([{{AliceName, Domain}, owner}, 232: {{BobName, Domain}, member}]), 233: ?assertMatch(ExpectedAff, lists:sort(get_room_aff(RoomJID))). 234: 235: user_invite_user_errors(Config) -> 236: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 237: fun user_invite_user_errors_story/3). 238: 239: user_invite_user_errors_story(Config, Alice, Bob) -> 240: Ep = ?config(schema_endpoint, Config), 241: MUCServer = ?config(muc_light_host, Config), 242: CredsAlice = make_creds(Alice), 243: CredsBob = make_creds(Bob), 244: AliceBin = escalus_client:short_jid(Alice), 245: BobBin = escalus_client:short_jid(Bob), 246: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 247: create_room(MUCServer, <<"first room">>, <<"subject">>, AliceBin), 248: % Try to invite a user to not existing room 249: Res = execute(Ep, user_invite_user_body( 250: make_bare_jid(?UNKNOWN, MUCServer), BobBin), CredsAlice), 251: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"does not occupy this room">>)), 252: % User without rooms tries to invite a user 253: Res2 = execute(Ep, user_invite_user_body( 254: jid:to_binary(RoomJID), AliceBin), CredsBob), 255: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"does not occupy this room">>)), 256: % Try with a non-existent domain 257: Res3 = execute(Ep, user_invite_user_body( 258: make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), BobBin), CredsAlice), 259: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)). 260: 261: user_delete_room(Config) -> 262: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_delete_room_story/3). 263: 264: user_delete_room_story(Config, Alice, Bob) -> 265: Ep = ?config(schema_endpoint, Config), 266: MUCServer = ?config(muc_light_host, Config), 267: CredsAlice = make_creds(Alice), 268: CredsBob = make_creds(Bob), 269: AliceBin = escalus_client:short_jid(Alice), 270: BobBin = escalus_client:short_jid(Bob), 271: Name = <<"first room">>, 272: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 273: create_room(MUCServer, Name, <<"subject">>, AliceBin), 274: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 275: % Member cannot delete room 276: Res = execute(Ep, delete_room_body(jid:to_binary(RoomJID)), CredsBob), 277: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), 278: <<"cannot delete this room">>)), 279: % Owner can delete own room 280: Res2 = execute(Ep, delete_room_body(jid:to_binary(RoomJID)), CredsAlice), 281: ?assertNotEqual(nomatch, binary:match(get_ok_value(?DELETE_ROOM_PATH, Res2), 282: <<"successfully">>)), 283: ?assertEqual({error, not_exists}, get_room_info(jid:from_binary(RoomJID))), 284: % Try with a non-existent domain 285: Res3 = execute(Ep, delete_room_body(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN)), CredsAlice), 286: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)), 287: % Try with a non-existent room 288: Res4 = execute(Ep, delete_room_body(make_bare_jid(?UNKNOWN, MUCServer)), CredsAlice), 289: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not existing room">>)). 290: 291: user_kick_user(Config) -> 292: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_kick_user_story/3). 293: 294: user_kick_user_story(Config, Alice, Bob) -> 295: Ep = ?config(schema_endpoint, Config), 296: MUCServer = ?config(muc_light_host, Config), 297: CredsAlice = make_creds(Alice), 298: CredsBob = make_creds(Bob), 299: AliceBin = escalus_client:short_jid(Alice), 300: BobBin = escalus_client:short_jid(Bob), 301: RoomName = <<"first room">>, 302: {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 303: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 304: % Member kicks himself from a room 305: ?assertEqual(2, length(get_room_aff(RoomJID))), 306: Res = execute(Ep, user_kick_user_body(jid:to_binary(RoomJID), null), CredsBob), 307: ?assertNotEqual(nomatch, binary:match(get_ok_value(?KICK_USER_PATH, Res), 308: <<"successfully">>)), 309: ?assertEqual(1, length(get_room_aff(RoomJID))), 310: % Member cannot kick the room owner. The kick stanza is sent successfully, 311: % but is ignored by server 312: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 313: Res2 = execute(Ep, user_kick_user_body(jid:to_binary(RoomJID), AliceBin), CredsBob), 314: ?assertNotEqual(nomatch, binary:match(get_ok_value(?KICK_USER_PATH, Res2), <<"successfully">>)), 315: ?assertEqual(2, length(get_room_aff(RoomJID))), 316: % Owner kicks the member from a room 317: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 318: Res3 = execute(Ep, user_kick_user_body(jid:to_binary(RoomJID), BobBin), CredsAlice), 319: ?assertNotEqual(nomatch, binary:match(get_ok_value(?KICK_USER_PATH, Res3), <<"successfully">>)), 320: ?assertEqual(1, length(get_room_aff(RoomJID))). 321: 322: user_send_message_to_room(Config) -> 323: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 324: fun user_send_message_to_room_story/3). 325: 326: user_send_message_to_room_story(Config, Alice, Bob) -> 327: Ep = ?config(schema_endpoint, Config), 328: MUCServer = ?config(muc_light_host, Config), 329: CredsAlice = make_creds(Alice), 330: AliceBin = escalus_client:short_jid(Alice), 331: BobBin = escalus_client:short_jid(Bob), 332: RoomName = <<"first room">>, 333: MsgBody = <<"Hello there!">>, 334: {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 335: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 336: Res = execute(Ep, user_send_message_to_room_body(jid:to_binary(RoomJID), MsgBody), CredsAlice), 337: ?assertNotEqual(nomatch, binary:match(get_ok_value(?SEND_MESSAGE_PATH, Res), <<"successfully">>)), 338: [_, Msg] = escalus:wait_for_stanzas(Bob, 2), 339: escalus:assert(is_message, Msg). 340: 341: user_send_message_to_room_errors(Config) -> 342: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 343: fun user_send_message_to_room_errors_story/3). 344: 345: user_send_message_to_room_errors_story(Config, Alice, Bob) -> 346: Ep = ?config(schema_endpoint, Config), 347: MUCServer = ?config(muc_light_host, Config), 348: CredsAlice = make_creds(Alice), 349: CredsBob = make_creds(Bob), 350: AliceBin = escalus_client:short_jid(Alice), 351: BobBin = escalus_client:short_jid(Bob), 352: MsgBody = <<"Hello there!">>, 353: {ok, #{jid := #jid{luser = ARoomID} = ARoomJID}} = 354: create_room(MUCServer, <<"alice room">>, <<"subject">>, AliceBin), 355: % Try with a non-existent domain 356: Res = execute(Ep, user_send_message_to_room_body( 357: make_bare_jid(ARoomID, ?UNKNOWN_DOMAIN), MsgBody), CredsAlice), 358: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)), 359: % Try with a user without rooms 360: Res2 = execute(Ep, user_send_message_to_room_body( 361: jid:to_binary(ARoomJID), MsgBody), CredsBob), 362: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not occupy this room">>)), 363: % Try with a room not occupied by this user 364: {ok, #{jid := _RoomJID2}} = create_room(MUCServer, <<"bob room">>, <<"subject">>, BobBin), 365: Res3 = execute(Ep, user_send_message_to_room_body( 366: jid:to_binary(ARoomJID), MsgBody), CredsBob), 367: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not occupy this room">>)). 368: 369: user_get_room_messages(Config) -> 370: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_get_room_messages_story/3). 371: 372: user_get_room_messages_story(Config, Alice, Bob) -> 373: Ep = ?config(schema_endpoint, Config), 374: MUCServer = ?config(muc_light_host, Config), 375: CredsAlice = make_creds(Alice), 376: CredsBob = make_creds(Bob), 377: AliceBin = escalus_client:short_jid(Alice), 378: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 379: create_room(MUCServer, <<"first room">>, <<"subject">>, AliceBin), 380: Message = <<"Hello friends">>, 381: send_message_to_room(RoomJID, jid:from_binary(AliceBin), Message), 382: mam_helper:maybe_wait_for_archive(Config), 383: % Get messages so far 384: Limit = 40, 385: Res = execute(Ep, get_room_messages_body(jid:to_binary(RoomJID), Limit, null), CredsAlice), 386: #{<<"stanzas">> :=[#{<<"stanza">> := StanzaXML}], <<"limit">> := Limit} = 387: get_ok_value(?GET_MESSAGES_PATH, Res), 388: ?assertMatch({ok, #xmlel{name = <<"message">>}}, exml:parse(StanzaXML)), 389: % Get messages before the given date and time 390: Before = <<"2022-02-17T04:54:13+00:00">>, 391: Res2 = execute(Ep, get_room_messages_body(jid:to_binary(RoomJID), null, Before), CredsAlice), 392: ?assertMatch(#{<<"stanzas">> := [], <<"limit">> := 50}, get_ok_value(?GET_MESSAGES_PATH, Res2)), 393: % Try to pass too big page size value 394: Res3 = execute(Ep, get_room_messages_body(jid:to_binary(RoomJID), 51, Before), CredsAlice), 395: ?assertMatch(#{<<"limit">> := 50}, get_ok_value(?GET_MESSAGES_PATH, Res3)), 396: % Try with a non-existent domain 397: Res4 = execute(Ep, get_room_messages_body( 398: make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Limit, null), CredsAlice), 399: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not found">>)), 400: % Try with a user that is not a room member 401: Res5 = execute(Ep, get_room_messages_body( 402: jid:to_binary(RoomJID), Limit, null), CredsBob), 403: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res5), <<"not occupy this room">>)). 404: 405: user_list_rooms(Config) -> 406: escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_list_rooms_story/2). 407: 408: user_list_rooms_story(Config, Alice) -> 409: Ep = ?config(schema_endpoint, Config), 410: MUCServer = ?config(muc_light_host, Config), 411: CredsAlice = make_creds(Alice), 412: AliceBin = escalus_client:short_jid(Alice), 413: {ok, #{jid := RoomJID}} = create_room(MUCServer, <<"room a">>, <<"subject">>, AliceBin), 414: {ok, #{jid := RoomJID2}} = create_room(MUCServer, <<"room b">>, <<"subject">>, AliceBin), 415: Res = execute(Ep, user_list_rooms_body(), CredsAlice), 416: ?assertEqual(lists:sort([jid:to_binary(RoomJID), jid:to_binary(RoomJID2)]), 417: lists:sort(get_ok_value(?USER_LIST_ROOMS_PATH, Res))). 418: 419: user_list_room_users(Config) -> 420: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_list_room_users_story/3). 421: 422: user_list_room_users_story(Config, Alice, Bob) -> 423: Ep = ?config(schema_endpoint, Config), 424: MUCServer = ?config(muc_light_host, Config), 425: CredsAlice = make_creds(Alice), 426: CredsBob = make_creds(Bob), 427: AliceBin = escalus_client:short_jid(Alice), 428: BobBin = escalus_client:short_jid(Bob), 429: AliceLower = escalus_utils:jid_to_lower(AliceBin), 430: {ok, #{jid := RoomJID}} = create_room(MUCServer, <<"room a">>, <<"subject">>, AliceBin), 431: % Owner can list room users 432: Res = execute(Ep, list_room_users_body(jid:to_binary(RoomJID)), CredsAlice), 433: ?assertEqual([#{<<"jid">> => AliceLower, <<"affiliation">> => <<"OWNER">>}], 434: get_ok_value(?LIST_ROOM_USERS_PATH, Res)), 435: % Try with a non-existent domain 436: Res2 = execute(Ep, list_room_users_body( 437: make_bare_jid(RoomJID#jid.luser, ?UNKNOWN_DOMAIN)), CredsAlice), 438: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 439: % Try with a non-existent room 440: Res3 = execute(Ep, list_room_users_body( 441: make_bare_jid(?UNKNOWN, MUCServer)), CredsAlice), 442: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)), 443: % User that is not a member cannot get aff 444: Res4 = execute(Ep, list_room_users_body(jid:to_binary(RoomJID)), CredsBob), 445: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not occupy this room">>)), 446: % Member can get aff 447: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 448: escalus:wait_for_stanza(Bob), 449: Res5 = execute(Ep, list_room_users_body(jid:to_binary(RoomJID)), CredsBob), 450: ?assertMatch([_, _], get_ok_value(?LIST_ROOM_USERS_PATH, Res5)). 451: 452: user_get_room_config(Config) -> 453: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_get_room_config_story/3). 454: 455: user_get_room_config_story(Config, Alice, Bob) -> 456: Ep = ?config(schema_endpoint, Config), 457: MUCServer = ?config(muc_light_host, Config), 458: CredsAlice = make_creds(Alice), 459: CredsBob = make_creds(Bob), 460: AliceBin = escalus_client:short_jid(Alice), 461: BobBin = escalus_client:short_jid(Bob), 462: AliceLower = escalus_utils:jid_to_lower(AliceBin), 463: BobLower = escalus_utils:jid_to_lower(BobBin), 464: RoomName = <<"first room">>, 465: RoomSubject = <<"Room about nothing">>, 466: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 467: create_room(MUCServer, RoomName, RoomSubject, AliceBin), 468: RoomJIDBin = jid:to_binary(RoomJID), 469: Res = execute(Ep, get_room_config_body(jid:to_binary(RoomJID)), CredsAlice), 470: % Owner can get a config 471: ?assertEqual(#{<<"jid">> => RoomJIDBin, <<"subject">> => RoomSubject, <<"name">> => RoomName, 472: <<"participants">> => [#{<<"jid">> => AliceLower, 473: <<"affiliation">> => <<"OWNER">>}]}, 474: get_ok_value(?GET_ROOM_CONFIG_PATH, Res)), 475: % Try with a non-existent domain 476: Res2 = execute(Ep, get_room_config_body(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN)), CredsAlice), 477: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 478: % Try with a non-existent room 479: Res3 = execute(Ep, get_room_config_body(make_bare_jid(?UNKNOWN, MUCServer)), CredsAlice), 480: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)), 481: % User that is not a member cannot get a room config 482: Res4 = execute(Ep, get_room_config_body(jid:to_binary(RoomJID)), CredsBob), 483: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not occupy this room">>)), 484: % Member can get a config 485: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 486: Res5 = execute(Ep, get_room_config_body(jid:to_binary(RoomJID)), CredsBob), 487: ?assertEqual(#{<<"jid">> => RoomJIDBin, <<"subject">> => RoomSubject, <<"name">> => RoomName, 488: <<"participants">> => [#{<<"jid">> => AliceLower, 489: <<"affiliation">> => <<"OWNER">>}, 490: #{<<"jid">> => BobLower, 491: <<"affiliation">> => <<"MEMBER">>}]}, 492: get_ok_value(?GET_ROOM_CONFIG_PATH, Res5)). 493: 494: user_blocking_list(Config) -> 495: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_blocking_list_story/3). 496: 497: user_blocking_list_story(Config, Alice, Bob) -> 498: Ep = ?config(schema_endpoint, Config), 499: CredsAlice = make_creds(Alice), 500: BobBin = escalus_client:full_jid(Bob), 501: BobShortBin = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)), 502: {ok, #{jid := RoomJID}} = create_room(?config(muc_light_host, Config), 503: <<"room">>, <<"subject">>, BobBin), 504: RoomBin = jid:to_binary(RoomJID), 505: Res = execute(Ep, user_get_blocking_body(), CredsAlice), 506: ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res)), 507: Res2 = execute(Ep, user_set_blocking_body([{<<"USER">>, <<"DENY">>, BobBin}]), CredsAlice), 508: ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res2), 509: <<"successfully">>)), 510: Res3 = execute(Ep, user_get_blocking_body(), CredsAlice), 511: ?assertEqual([#{<<"entityType">> => <<"USER">>, 512: <<"action">> => <<"DENY">>, 513: <<"entity">> => BobShortBin}], 514: get_ok_value(?GET_BLOCKING_LIST_PATH, Res3)), 515: Res4 = execute(Ep, user_set_blocking_body([{<<"USER">>, <<"ALLOW">>, BobBin}, 516: {<<"ROOM">>, <<"DENY">>, jid:to_binary(RoomJID)}]), 517: CredsAlice), 518: ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res4), 519: <<"successfully">>)), 520: Res5 = execute(Ep, user_get_blocking_body(), CredsAlice), 521: ?assertEqual([#{<<"entityType">> => <<"ROOM">>, 522: <<"action">> => <<"DENY">>, 523: <<"entity">> => RoomBin}], 524: get_ok_value(?GET_BLOCKING_LIST_PATH, Res5)). 525: 526: %% Admin test cases 527: 528: admin_blocking_list(Config) -> 529: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_blocking_list_story/3). 530: 531: admin_blocking_list_story(Config, Alice, Bob) -> 532: AliceBin = escalus_client:full_jid(Alice), 533: BobBin = escalus_client:full_jid(Bob), 534: BobShortBin = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)), 535: Res = execute_auth(admin_get_user_blocking_body(AliceBin), Config), 536: ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res)), 537: Res2 = execute_auth(admin_set_blocking_body( 538: AliceBin, [{<<"USER">>, <<"DENY">>, BobBin}]), Config), 539: ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res2), 540: <<"successfully">>)), 541: Res3 = execute_auth(admin_get_user_blocking_body(AliceBin), Config), 542: ?assertEqual([#{<<"entityType">> => <<"USER">>, 543: <<"action">> => <<"DENY">>, 544: <<"entity">> => BobShortBin}], 545: get_ok_value(?GET_BLOCKING_LIST_PATH, Res3)), 546: Res4 = execute_auth(admin_set_blocking_body( 547: AliceBin, [{<<"USER">>, <<"ALLOW">>, BobBin}]), Config), 548: ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res4), 549: <<"successfully">>)), 550: Res5 = execute_auth(admin_get_user_blocking_body(AliceBin), Config), 551: ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res5)), 552: % Check whether errors are handled correctly 553: InvalidUser = make_bare_jid(?UNKNOWN, ?UNKNOWN_DOMAIN), 554: Res6 = execute_auth(admin_get_user_blocking_body(InvalidUser), Config), 555: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res6), <<"not found">>)), 556: Res7 = execute_auth(admin_set_blocking_body(InvalidUser, []), Config), 557: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res7), <<"not found">>)). 558: 559: admin_create_room(Config) -> 560: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_create_room_story/2). 561: 562: admin_create_room_story(Config, Alice) -> 563: AliceBin = escalus_client:short_jid(Alice), 564: AliceBinLower = escalus_utils:jid_to_lower(AliceBin), 565: MucServer = ?config(muc_light_host, Config), 566: Name = <<"first room">>, 567: Subject = <<"testing">>, 568: Res = execute_auth(admin_create_room_body(MucServer, Name, AliceBin, Subject, null), Config), 569: #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject, 570: <<"participants">> := Participants} = get_ok_value(?CREATE_ROOM_PATH, Res), 571: ?assertMatch(#jid{lserver = MucServer}, jid:from_binary(JID)), 572: ?assertEqual([#{<<"jid">> => AliceBinLower, <<"affiliation">> => <<"OWNER">>}], Participants), 573: % Try with a non-existent domain 574: Res2 = execute_auth(admin_create_room_body(?UNKNOWN_DOMAIN, Name, AliceBin, Subject, null), 575: Config), 576: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)). 577: 578: admin_create_identified_room(Config) -> 579: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_create_identified_room_story/2). 580: 581: admin_create_identified_room_story(Config, Alice) -> 582: AliceBin = escalus_client:short_jid(Alice), 583: MucServer = ?config(muc_light_host, Config), 584: Name = <<"first room">>, 585: Subject = <<"testing">>, 586: Id = <<"my_room">>, 587: Res = execute_auth(admin_create_room_body(MucServer, Name, AliceBin, Subject, Id), Config), 588: #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} = 589: get_ok_value(?CREATE_ROOM_PATH, Res), 590: ?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary(JID)), 591: % Create a room with an existing ID 592: Res2 = execute_auth(admin_create_room_body(MucServer, <<"snd room">>, AliceBin, Subject, Id), 593: Config), 594: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"already exists">>)), 595: % Try with a non-existent domain 596: Res3 = execute_auth(admin_create_room_body(?UNKNOWN_DOMAIN, <<"name">>, AliceBin, Subject, Id), 597: Config), 598: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)), 599: % Try with an empty string passed as ID 600: Res4 = execute_auth(admin_create_room_body(MucServer, <<"name">>, AliceBin, Subject, <<>>), Config), 601: ?assertNotEqual(nomatch, binary:match(get_coertion_err_msg(Res4), <<"Given string is empty">>)). 602: 603: admin_change_room_config(Config) -> 604: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_change_room_config_story/2). 605: 606: admin_change_room_config_story(Config, Alice) -> 607: AliceBin = escalus_client:short_jid(Alice), 608: MUCServer = ?config(muc_light_host, Config), 609: Name = <<"first room">>, 610: Subject = <<"testing">>, 611: % Create a new room 612: {ok, #{jid := RoomJID}} = create_room(MUCServer, Name, Subject, AliceBin), 613: % Try to change the room configuration 614: Name2 = <<"changed room">>, 615: Subject2 = <<"not testing">>, 616: Res = execute_auth(admin_change_room_configuration_body(jid:to_binary(RoomJID), 617: AliceBin, Name2, Subject2), Config), 618: ?assertMatch(#{<<"name">> := Name2, <<"subject">> := Subject2}, 619: get_ok_value(?CHANGE_CONFIG_PATH, Res)). 620: 621: admin_change_room_config_errors(Config) -> 622: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 623: fun admin_change_room_config_errors_story/3). 624: 625: admin_change_room_config_errors_story(Config, Alice, Bob) -> 626: AliceBin = escalus_client:short_jid(Alice), 627: BobBin = escalus_client:short_jid(Bob), 628: MUCServer = ?config(muc_light_host, Config), 629: RoomName = <<"first room">>, 630: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 631: create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 632: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 633: % Try to change the config with a non-existent domain 634: Res = execute_auth(admin_change_room_configuration_body( 635: make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), AliceBin, RoomName, <<"subject2">>), Config), 636: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)), 637: % Try to change the config of the non-existent room 638: Res2 = execute_auth(admin_change_room_configuration_body( 639: make_bare_jid(<<"unknown">>, MUCServer), AliceBin, 640: RoomName, <<"subject2">>), Config), 641: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 642: % Try to change the config by the non-existent user 643: Res3 = execute_auth(admin_change_room_configuration_body( 644: jid:to_binary(RoomJID), <<"wrong-user@wrong-domain">>, 645: RoomName, <<"subject2">>), Config), 646: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not occupy this room">>)), 647: % Try to change a config by the user without permission 648: Res4 = execute_auth(admin_change_room_configuration_body( 649: jid:to_binary(RoomJID), BobBin, RoomName, <<"subject2">>), Config), 650: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), 651: <<"does not have permission to change">>)). 652: 653: admin_invite_user(Config) -> 654: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_invite_user_story/3). 655: 656: admin_invite_user_story(Config, Alice, Bob) -> 657: AliceBin = escalus_client:short_jid(Alice), 658: BobBin = escalus_client:short_jid(Bob), 659: Domain = escalus_client:server(Alice), 660: MUCServer = ?config(muc_light_host, Config), 661: Name = <<"first room">>, 662: {ok, #{jid := RoomJID}} = create_room(MUCServer, Name, <<"subject2">>, AliceBin), 663: 664: Res = execute_auth(admin_invite_user_body(jid:to_binary(RoomJID), AliceBin, BobBin), Config), 665: ?assertNotEqual(nomatch, binary:match(get_ok_value(?INVITE_USER_PATH, Res), 666: <<"successfully">>)), 667: BobName = escalus_utils:jid_to_lower(escalus_client:username(Bob)), 668: AliceName = escalus_utils:jid_to_lower(escalus_client:username(Alice)), 669: ExpectedAff = lists:sort([{{AliceName, Domain}, owner}, 670: {{BobName, Domain}, member}]), 671: ?assertMatch(ExpectedAff, lists:sort(get_room_aff(RoomJID))). 672: 673: admin_invite_user_errors(Config) -> 674: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 675: fun admin_invite_user_errors_story/3). 676: 677: admin_invite_user_errors_story(Config, Alice, Bob) -> 678: AliceBin = escalus_client:short_jid(Alice), 679: BobBin = escalus_client:short_jid(Bob), 680: MUCServer = ?config(muc_light_host, Config), 681: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 682: create_room(MUCServer, <<"first room">>, <<"subject">>, AliceBin), 683: % Try to invite a user to not existing room 684: Res = execute_auth(admin_invite_user_body( 685: make_bare_jid(?UNKNOWN, MUCServer), AliceBin, BobBin), Config), 686: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"does not occupy this room">>)), 687: % User without rooms tries to invite a user 688: Res2 = execute_auth(admin_invite_user_body( 689: jid:to_binary(RoomJID), BobBin, AliceBin), Config), 690: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"does not occupy this room">>)), 691: % Try with a non-existent domain 692: Res3 = execute_auth(admin_invite_user_body( 693: make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), AliceBin, BobBin), Config), 694: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)). 695: 696: admin_delete_room(Config) -> 697: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_delete_room_story/2). 698: 699: admin_delete_room_story(Config, Alice) -> 700: AliceBin = escalus_client:short_jid(Alice), 701: MUCServer = ?config(muc_light_host, Config), 702: Name = <<"first room">>, 703: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 704: create_room(MUCServer, Name, <<"subject">>, AliceBin), 705: Res = execute_auth(delete_room_body(jid:to_binary(RoomJID)), Config), 706: ?assertNotEqual(nomatch, binary:match(get_ok_value(?DELETE_ROOM_PATH, Res), 707: <<"successfully">>)), 708: ?assertEqual({error, not_exists}, get_room_info(jid:from_binary(RoomJID))), 709: % Try with a non-existent domain 710: Res2 = execute_auth(delete_room_body(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN)), Config), 711: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 712: % Try with a non-existent room 713: Res3 = execute_auth(delete_room_body(make_bare_jid(?UNKNOWN, MUCServer)), Config), 714: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"Cannot remove">>)). 715: 716: admin_kick_user(Config) -> 717: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_kick_user_story/3). 718: 719: admin_kick_user_story(Config, Alice, Bob) -> 720: AliceBin = escalus_client:short_jid(Alice), 721: BobBin = escalus_client:short_jid(Bob), 722: MUCServer = ?config(muc_light_host, Config), 723: RoomName = <<"first room">>, 724: {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 725: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 726: ?assertEqual(2, length(get_room_aff(RoomJID))), 727: Res = execute_auth(admin_kick_user_body(jid:to_binary(RoomJID), BobBin), Config), 728: ?assertNotEqual(nomatch, binary:match(get_ok_value(?KICK_USER_PATH, Res), 729: <<"successfully">>)), 730: ?assertEqual(1, length(get_room_aff(RoomJID))). 731: 732: admin_send_message_to_room(Config) -> 733: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 734: fun admin_send_message_to_room_story/3). 735: 736: admin_send_message_to_room_story(Config, Alice, Bob) -> 737: AliceBin = escalus_client:short_jid(Alice), 738: BobBin = escalus_client:short_jid(Bob), 739: MUCServer = ?config(muc_light_host, Config), 740: RoomName = <<"first room">>, 741: MsgBody = <<"Hello there!">>, 742: {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 743: {ok, _} = invite_user(RoomJID, AliceBin, BobBin), 744: Res = execute_auth(admin_send_message_to_room_body( 745: jid:to_binary(RoomJID), AliceBin, MsgBody), Config), 746: ?assertNotEqual(nomatch, binary:match(get_ok_value(?SEND_MESSAGE_PATH, Res), 747: <<"successfully">>)), 748: [_, Msg] = escalus:wait_for_stanzas(Bob, 2), 749: escalus:assert(is_message, Msg). 750: 751: admin_send_message_to_room_errors(Config) -> 752: escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], 753: fun admin_send_message_to_room_errors_story/3). 754: 755: admin_send_message_to_room_errors_story(Config, Alice, Bob) -> 756: AliceBin = escalus_client:short_jid(Alice), 757: BobBin = escalus_client:short_jid(Bob), 758: MUCServer = ?config(muc_light_host, Config), 759: MsgBody = <<"Hello there!">>, 760: {ok, #{jid := #jid{luser = ARoomID} = ARoomJID}} = 761: create_room(MUCServer, <<"alice room">>, <<"subject">>, AliceBin), 762: % Try with a non-existent domain 763: Res2 = execute_auth(admin_send_message_to_room_body( 764: make_bare_jid(ARoomID, ?UNKNOWN_DOMAIN), AliceBin, MsgBody), Config), 765: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 766: % Try with a user without rooms 767: Res3 = execute_auth(admin_send_message_to_room_body( 768: jid:to_binary(ARoomJID), BobBin, MsgBody), Config), 769: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"does not occupy this room">>)), 770: % Try with a room not occupied by this user 771: {ok, #{jid := _RoomJID2}} = create_room(MUCServer, <<"bob room">>, <<"subject">>, BobBin), 772: Res4 = execute_auth(admin_send_message_to_room_body( 773: jid:to_binary(ARoomJID), BobBin, MsgBody), Config), 774: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"does not occupy this room">>)). 775: 776: admin_get_room_messages(Config) -> 777: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_get_room_messages_story/2). 778: 779: admin_get_room_messages_story(Config, Alice) -> 780: AliceBin = escalus_client:short_jid(Alice), 781: %Domain = escalus_client:server(Alice), 782: MUCServer = ?config(muc_light_host, Config), 783: RoomName = <<"first room">>, 784: RoomName2 = <<"second room">>, 785: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 786: create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 787: {ok, _} = create_room(MUCServer, RoomName2, <<"subject">>, AliceBin), 788: Message = <<"Hello friends">>, 789: send_message_to_room(RoomJID, jid:from_binary(AliceBin), Message), 790: mam_helper:maybe_wait_for_archive(Config), 791: % Get messages so far 792: Limit = 40, 793: Res = execute_auth(get_room_messages_body(jid:to_binary(RoomJID), Limit, null), Config), 794: #{<<"stanzas">> := [#{<<"stanza">> := StanzaXML}], <<"limit">> := Limit} = 795: get_ok_value(?GET_MESSAGES_PATH, Res), 796: ?assertMatch({ok, #xmlel{name = <<"message">>}}, exml:parse(StanzaXML)), 797: % Get messages before the given date and time 798: Before = <<"2022-02-17T04:54:13+00:00">>, 799: Res2 = execute_auth(get_room_messages_body(jid:to_binary(RoomJID), null, Before), Config), 800: ?assertMatch(#{<<"stanzas">> := [], <<"limit">> := 50}, get_ok_value(?GET_MESSAGES_PATH, Res2)), 801: % Try to pass too big page size value 802: Res3 = execute_auth(get_room_messages_body(jid:to_binary(RoomJID), 51, Before), Config), 803: ?assertMatch(#{<<"limit">> := 50},get_ok_value(?GET_MESSAGES_PATH, Res3)), 804: % Try with a non-existent domain 805: Res4 = execute_auth(get_room_messages_body( 806: make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Limit, null), Config), 807: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not found">>)). 808: 809: admin_list_user_rooms(Config) -> 810: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_list_user_rooms_story/2). 811: 812: admin_list_user_rooms_story(Config, Alice) -> 813: AliceBin = escalus_client:short_jid(Alice), 814: Domain = escalus_client:server(Alice), 815: MUCServer = ?config(muc_light_host, Config), 816: RoomName = <<"first room">>, 817: RoomName2 = <<"second room">>, 818: {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 819: {ok, #{jid := RoomJID2}} = create_room(MUCServer, RoomName2, <<"subject">>, AliceBin), 820: Res = execute_auth(admin_list_user_rooms_body(AliceBin), Config), 821: ?assertEqual(lists:sort([jid:to_binary(RoomJID), jid:to_binary(RoomJID2)]), 822: lists:sort(get_ok_value(?LIST_USER_ROOMS_PATH, Res))), 823: % Try with a non-existent user 824: Res2 = execute_auth(admin_list_user_rooms_body(<<"not-exist@", Domain/binary>>), Config), 825: ?assertEqual([], lists:sort(get_ok_value(?LIST_USER_ROOMS_PATH, Res2))), 826: % Try with a non-existent domain 827: Res3 = execute_auth(admin_list_user_rooms_body(<<"not-exist@not-exist">>), Config), 828: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)). 829: 830: admin_list_room_users(Config) -> 831: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_list_room_users_story/2). 832: 833: admin_list_room_users_story(Config, Alice) -> 834: AliceBin = escalus_client:short_jid(Alice), 835: AliceLower = escalus_utils:jid_to_lower(AliceBin), 836: MUCServer = ?config(muc_light_host, Config), 837: RoomName = <<"first room">>, 838: {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin), 839: Res = execute_auth(list_room_users_body(jid:to_binary(RoomJID)), Config), 840: ?assertEqual([#{<<"jid">> => AliceLower, <<"affiliation">> => <<"OWNER">>}], 841: get_ok_value(?LIST_ROOM_USERS_PATH, Res)), 842: % Try with a non-existent domain 843: Res2 = execute_auth(list_room_users_body( 844: make_bare_jid(RoomJID#jid.luser, ?UNKNOWN_DOMAIN)), Config), 845: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 846: % Try with a non-existent room 847: Res3 = execute_auth(list_room_users_body( 848: make_bare_jid(?UNKNOWN, MUCServer)), Config), 849: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)). 850: 851: admin_get_room_config(Config) -> 852: escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_get_room_config_story/2). 853: 854: admin_get_room_config_story(Config, Alice) -> 855: AliceBin = escalus_client:short_jid(Alice), 856: AliceLower = escalus_utils:jid_to_lower(AliceBin), 857: MUCServer = ?config(muc_light_host, Config), 858: RoomName = <<"first room">>, 859: RoomSubject = <<"Room about nothing">>, 860: {ok, #{jid := #jid{luser = RoomID} = RoomJID}} = 861: create_room(MUCServer, RoomName, RoomSubject, AliceBin), 862: RoomJIDBin = jid:to_binary(RoomJID), 863: Res = execute_auth(get_room_config_body(jid:to_binary(RoomJID)), Config), 864: ?assertEqual(#{<<"jid">> => RoomJIDBin, <<"subject">> => RoomSubject, <<"name">> => RoomName, 865: <<"participants">> => [#{<<"jid">> => AliceLower, 866: <<"affiliation">> => <<"OWNER">>}]}, 867: get_ok_value([data, muc_light, getRoomConfig], Res)), 868: % Try with a non-existent domain 869: Res2 = execute_auth(get_room_config_body(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN)), Config), 870: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)), 871: % Try with a non-existent room 872: Res3 = execute_auth(get_room_config_body(make_bare_jid(?UNKNOWN, MUCServer)), Config), 873: ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)). 874: 875: %% Helpers 876: 877: make_bare_jid(User, Server) -> 878: JID = jid:make_bare(User, Server), 879: jid:to_binary(JID). 880: 881: send_message_to_room(RoomJID, SenderJID, Message) -> 882: rpc(mim(), mod_muc_light_api, send_message, [RoomJID, SenderJID, Message]). 883: 884: get_room_messages(ID, Domain) -> 885: {ok, Messages} = rpc(mim(), mod_muc_light_api, get_room_messages, [Domain, ID]), 886: Messages. 887: 888: create_room(Domain, Name, Subject, CreatorBin) -> 889: CreatorJID = jid:from_binary(CreatorBin), 890: rpc(mim(), mod_muc_light_api, create_room, [Domain, CreatorJID, Name, Subject]). 891: 892: invite_user(RoomJID, SenderBin, RecipientBin) -> 893: SenderJID = jid:from_binary(SenderBin), 894: RecipientJID = jid:from_binary(RecipientBin), 895: rpc(mim(), mod_muc_light_api, invite_to_room, [RoomJID, SenderJID, RecipientJID]). 896: 897: get_room_info(JID) -> 898: HostType = domain_helper:host_type(), 899: RoomUS = jid:to_lus(JID), 900: rpc(mim(), mod_muc_light_db_backend, get_info, [HostType, RoomUS]). 901: 902: get_room_aff(JID) -> 903: {ok, _, Aff, _} = get_room_info(JID), 904: Aff. 905: 906: prepare_blocking_items_for_query(Items) -> 907: [#{<<"entity">> => Who, <<"entityType">> => What, 908: <<"action">> => Action} || {What, Action, Who} <- Items]. 909: 910: get_coertion_err_msg(Response) -> 911: {{<<"400">>, <<"Bad Request">>}, 912: #{<<"errors">> := [#{<<"message">> := Msg, 913: <<"extensions">> := #{<<"code">> := <<"input_coercion">>}}]}} = Response, 914: Msg. 915: 916: %% Request bodies 917: 918: admin_create_room_body(MUCDomain, Name, Owner, Subject, Id) -> 919: Query = <<"mutation M1($mucDomain: String!, $name: String!, $owner: JID!, $subject: String!, $id: NonEmptyString) 920: { muc_light { createRoom(mucDomain: $mucDomain, name: $name, owner: $owner, subject: $subject, id: $id) 921: { jid name subject participants {jid affiliation} } } }">>, 922: OpName = <<"M1">>, 923: Vars = #{<<"mucDomain">> => MUCDomain, <<"name">> => Name, <<"owner">> => Owner, 924: <<"subject">> => Subject, <<"id">> => Id}, 925: #{query => Query, operationName => OpName, variables => Vars}. 926: 927: admin_change_room_configuration_body(RoomJID, OwnerJID, Name, Subject) -> 928: Query = <<"mutation M1($room: JID!, $name: String!, $owner: JID!, $subject: String!) 929: { muc_light { changeRoomConfiguration(room: $room, name: $name, owner: $owner, subject: $subject) 930: { jid name subject participants {jid affiliation} } } }">>, 931: OpName = <<"M1">>, 932: Vars = #{<<"room">> => RoomJID, <<"name">> => Name, <<"owner">> => OwnerJID, 933: <<"subject">> => Subject}, 934: #{query => Query, operationName => OpName, variables => Vars}. 935: 936: admin_invite_user_body(RoomJID, Sender, Recipient) -> 937: Query = <<"mutation M1($room: JID!, $sender: JID!, $recipient: JID!) 938: { muc_light { inviteUser(room: $room, sender: $sender, recipient: $recipient) } }">>, 939: OpName = <<"M1">>, 940: Vars = #{<<"room">> => RoomJID, <<"sender">> => Sender, <<"recipient">> => Recipient}, 941: #{query => Query, operationName => OpName, variables => Vars}. 942: 943: admin_kick_user_body(RoomJID, User) -> 944: Query = <<"mutation M1($room: JID!, $user: JID!) 945: { muc_light { kickUser(room: $room, user: $user)} }">>, 946: OpName = <<"M1">>, 947: Vars = #{<<"room">> => RoomJID, <<"user">> => User}, 948: #{query => Query, operationName => OpName, variables => Vars}. 949: 950: admin_send_message_to_room_body(RoomJID, From, Body) -> 951: Query = <<"mutation M1($room: JID!, $from: JID!, $body: String!) 952: { muc_light { sendMessageToRoom(room: $room, from: $from, body: $body)} }">>, 953: OpName = <<"M1">>, 954: Vars = #{<<"room">> => RoomJID, <<"from">> => From, <<"body">> => Body}, 955: #{query => Query, operationName => OpName, variables => Vars}. 956: 957: admin_list_user_rooms_body(User) -> 958: Query = <<"query Q1($user: JID!) 959: { muc_light { listUserRooms(user: $user) } }">>, 960: OpName = <<"Q1">>, 961: Vars = #{<<"user">> => User}, 962: #{query => Query, operationName => OpName, variables => Vars}. 963: 964: user_create_room_body(MUCDomain, Name, Subject, Id) -> 965: Query = <<"mutation M1($mucDomain: String!, $name: String!, $subject: String!, $id: NonEmptyString) 966: { muc_light { createRoom(mucDomain: $mucDomain, name: $name, subject: $subject, id: $id) 967: { jid name subject participants {jid affiliation} } } }">>, 968: OpName = <<"M1">>, 969: Vars = #{<<"mucDomain">> => MUCDomain, <<"name">> => Name, <<"subject">> => Subject, 970: <<"id">> => Id}, 971: #{query => Query, operationName => OpName, variables => Vars}. 972: 973: user_change_room_configuration_body(RoomJID, Name, Subject) -> 974: Query = <<"mutation M1($room: JID!, $name: String!, $subject: String!) 975: { muc_light { changeRoomConfiguration(room: $room, name: $name, subject: $subject) 976: { jid name subject participants {jid affiliation} } } }">>, 977: OpName = <<"M1">>, 978: Vars = #{<<"room">> => RoomJID, <<"name">> => Name, <<"subject">> => Subject}, 979: #{query => Query, operationName => OpName, variables => Vars}. 980: 981: user_invite_user_body(RoomJID, Recipient) -> 982: Query = <<"mutation M1($room: JID!, $recipient: JID!) 983: { muc_light { inviteUser(room: $room, recipient: $recipient) } }">>, 984: OpName = <<"M1">>, 985: Vars = #{<<"room">> => RoomJID, <<"recipient">> => Recipient}, 986: #{query => Query, operationName => OpName, variables => Vars}. 987: 988: delete_room_body(RoomJID) -> 989: Query = <<"mutation M1($room: JID!) 990: { muc_light { deleteRoom(room: $room) } }">>, 991: OpName = <<"M1">>, 992: Vars = #{<<"room">> => RoomJID}, 993: #{query => Query, operationName => OpName, variables => Vars}. 994: 995: user_kick_user_body(RoomJID, User) -> 996: Query = <<"mutation M1($room: JID!, $user: JID) 997: { muc_light { kickUser(room: $room, user: $user)} }">>, 998: OpName = <<"M1">>, 999: Vars = #{<<"room">> => RoomJID, <<"user">> => User}, 1000: #{query => Query, operationName => OpName, variables => Vars}. 1001: 1002: user_send_message_to_room_body(RoomJID, Body) -> 1003: Query = <<"mutation M1($room: JID!, $body: String!) 1004: { muc_light { sendMessageToRoom(room: $room, body: $body)} }">>, 1005: OpName = <<"M1">>, 1006: Vars = #{<<"room">> => RoomJID, <<"body">> => Body}, 1007: #{query => Query, operationName => OpName, variables => Vars}. 1008: 1009: get_room_messages_body(RoomJID, PageSize, Before) -> 1010: Query = <<"query Q1($room: JID!, $pageSize: Int, $before: DateTime) 1011: { muc_light { getRoomMessages(room: $room, pageSize: $pageSize, before: $before) 1012: { stanzas { stanza } limit } } }">>, 1013: OpName = <<"Q1">>, 1014: Vars = #{<<"room">> => RoomJID, <<"pageSize">> => PageSize, <<"before">> => Before}, 1015: #{query => Query, operationName => OpName, variables => Vars}. 1016: 1017: user_list_rooms_body() -> 1018: Query = <<"query Q1 { muc_light { listRooms } }">>, 1019: #{query => Query, operationName => <<"Q1">>, variables => #{}}. 1020: 1021: list_room_users_body(RoomJID) -> 1022: Query = <<"query Q1($room: JID!) 1023: { muc_light { listRoomUsers(room: $room) 1024: { jid affiliation} } }">>, 1025: OpName = <<"Q1">>, 1026: Vars = #{<<"room">> => RoomJID}, 1027: #{query => Query, operationName => OpName, variables => Vars}. 1028: 1029: get_room_config_body(RoomJID) -> 1030: Query = <<"query Q1($room: JID!) 1031: { muc_light { getRoomConfig(room: $room) 1032: { jid name subject participants {jid affiliation} } } }">>, 1033: OpName = <<"Q1">>, 1034: Vars = #{<<"room">> => RoomJID}, 1035: #{query => Query, operationName => OpName, variables => Vars}. 1036: 1037: admin_get_user_blocking_body(UserJID) -> 1038: Query = <<"query Q1($user: JID!) 1039: { muc_light { getBlockingList(user: $user) 1040: { entity entityType action } } }">>, 1041: OpName = <<"Q1">>, 1042: Vars = #{<<"user">> => UserJID}, 1043: #{query => Query, operationName => OpName, variables => Vars}. 1044: 1045: admin_set_blocking_body(UserJID, Items) -> 1046: Query = <<"mutation M1($user: JID!, $items: [BlockingInput!]!) 1047: { muc_light { setBlockingList(user: $user, items: $items) } }">>, 1048: OpName = <<"M1">>, 1049: Vars = #{<<"user">> => UserJID, <<"items">> => prepare_blocking_items_for_query(Items)}, 1050: #{query => Query, operationName => OpName, variables => Vars}. 1051: 1052: user_get_blocking_body() -> 1053: Query = <<"query Q1 { muc_light { getBlockingList { entity entityType action } } }">>, 1054: OpName = <<"Q1">>, 1055: #{query => Query, operationName => OpName}. 1056: 1057: user_set_blocking_body(Items) -> 1058: Query = <<"mutation M1($items: [BlockingInput!]!) 1059: { muc_light { setBlockingList(items: $items) } }">>, 1060: OpName = <<"M1">>, 1061: Vars = #{<<"items">> => prepare_blocking_items_for_query(Items)}, 1062: #{query => Query, operationName => OpName, variables => Vars}.