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