1: -module(graphql_muc_light_SUITE).
    2: 
    3: -compile([export_all, nowarn_export_all]).
    4: 
    5: -import(common_helper, [unprep/1]).
    6: -import(distributed_helper, [mim/0, require_rpc_nodes/1, rpc/4, subhost_pattern/1]).
    7: -import(graphql_helper, [execute_user_command/5, execute_command/4, get_listener_port/1,
    8:                          get_listener_config/1, get_ok_value/2, get_err_msg/1,
    9:                          get_coercion_err_msg/1, make_creds/1, get_unauthorized/1,
   10:                          get_err_code/1, get_not_loaded/1]).
   11: 
   12: -import(config_parser_helper, [mod_config/2]).
   13: 
   14: -include_lib("common_test/include/ct.hrl").
   15: -include_lib("jid/include/jid.hrl").
   16: -include_lib("eunit/include/eunit.hrl").
   17: -include_lib("exml/include/exml.hrl").
   18: 
   19: -define(UNKNOWN_DOMAIN, <<"not-existing-domain">>).
   20: -define(UNKNOWN, <<"not-existing">>).
   21: 
   22: %% GraphQL Paths
   23: -define(CREATE_ROOM_PATH, [data, muc_light, createRoom]).
   24: -define(CHANGE_CONFIG_PATH, [data, muc_light, changeRoomConfiguration]).
   25: -define(INVITE_USER_PATH, [data, muc_light, inviteUser]).
   26: -define(KICK_USER_PATH, [data, muc_light, kickUser]).
   27: -define(DELETE_ROOM_PATH, [data, muc_light, deleteRoom]).
   28: -define(SEND_MESSAGE_PATH, [data, muc_light, sendMessageToRoom]).
   29: -define(GET_MESSAGES_PATH, [data, muc_light, getRoomMessages]).
   30: -define(LIST_USER_ROOMS_PATH, [data, muc_light, listUserRooms]).
   31: -define(USER_LIST_ROOMS_PATH, [data, muc_light, listRooms]).
   32: -define(LIST_ROOM_USERS_PATH, [data, muc_light, listRoomUsers]).
   33: -define(GET_ROOM_CONFIG_PATH, [data, muc_light, getRoomConfig]).
   34: -define(GET_BLOCKING_LIST_PATH, [data, muc_light, getBlockingList]).
   35: -define(SET_BLOCKING_LIST_PATH, [data, muc_light, setBlockingList]).
   36: 
   37: suite() ->
   38:     require_rpc_nodes([mim]) ++ escalus:suite().
   39: 
   40: all() ->
   41:     [{group, user},
   42:      {group, admin_http},
   43:      {group, admin_cli},
   44:      {group, domain_admin}].
   45: 
   46: groups() ->
   47:     [{user, [], user_groups()},
   48:      {admin_http, [], admin_groups()},
   49:      {admin_cli, [], admin_groups()},
   50:      {domain_admin, domain_admin_groups()},
   51:      {user_muc_light, [parallel], user_muc_light_tests()},
   52:      {user_muc_light_with_mam, [parallel], user_muc_light_with_mam_tests()},
   53:      {user_muc_light_not_configured, [], user_muc_light_not_configured_tests()},
   54:      {admin_muc_light, [], admin_muc_light_tests()},
   55:      {admin_muc_light_with_mam, [], admin_muc_light_with_mam_tests()},
   56:      {domain_admin_muc_light, [], domain_admin_muc_light_tests()},
   57:      {domain_admin_muc_light_with_mam, [], domain_admin_muc_light_with_mam_tests()},
   58:      {admin_muc_light_not_configured, [], admin_muc_light_not_configured_tests()}].
   59: 
   60: user_groups() ->
   61:     [{group, user_muc_light},
   62:      {group, user_muc_light_with_mam},
   63:      {group, user_muc_light_not_configured}].
   64: 
   65: admin_groups() ->
   66:     [{group, admin_muc_light},
   67:      {group, admin_muc_light_with_mam},
   68:      {group, admin_muc_light_not_configured}].
   69: 
   70: domain_admin_groups() ->
   71:     [{group, domain_admin_muc_light},
   72:      {group, domain_admin_muc_light_with_mam}].
   73: 
   74: user_muc_light_tests() ->
   75:     [user_create_room,
   76:      user_create_room_with_unprepped_domain,
   77:      user_create_room_with_bad_config,
   78:      user_create_room_with_custom_fields,
   79:      user_create_identified_room,
   80:      user_create_room_with_unprepped_id,
   81:      user_change_room_config,
   82:      user_change_room_config_errors,
   83:      user_invite_user,
   84:      user_invite_user_errors,
   85:      user_delete_room,
   86:      user_kick_user,
   87:      user_send_message_to_room,
   88:      user_send_message_to_room_errors,
   89:      user_get_room_messages_muc_light_or_mam_not_configured,
   90:      user_list_rooms,
   91:      user_list_room_users,
   92:      user_get_room_config,
   93:      user_blocking_list
   94:     ].
   95: 
   96: user_muc_light_with_mam_tests() ->
   97:     [user_get_room_messages,
   98:      user_shouldnt_store_messages_in_muc].
   99: 
  100: user_muc_light_not_configured_tests() ->
  101:     [user_create_room_muc_light_not_configured,
  102:      user_change_room_config_muc_light_not_configured,
  103:      user_invite_user_muc_light_not_configured,
  104:      user_delete_room_muc_light_not_configured,
  105:      user_kick_user_muc_light_not_configured,
  106:      user_send_message_to_room_muc_light_not_configured,
  107:      user_get_room_messages_muc_light_or_mam_not_configured,
  108:      user_list_rooms_muc_light_not_configured,
  109:      user_list_room_users_muc_light_not_configured,
  110:      user_get_room_config_muc_light_not_configured,
  111:      user_blocking_list_muc_light_not_configured].
  112: 
  113: admin_muc_light_tests() ->
  114:     [admin_create_room,
  115:      admin_create_room_non_existent_domain,
  116:      admin_create_room_with_unprepped_domain,
  117:      admin_create_room_with_custom_fields,
  118:      admin_create_identified_room,
  119:      admin_create_identified_room_non_existent_domain,
  120:      admin_create_room_with_unprepped_id,
  121:      admin_change_room_config,
  122:      admin_change_room_config_with_custom_fields,
  123:      admin_change_room_config_errors,
  124:      admin_change_room_config_non_existent_domain,
  125:      admin_invite_user,
  126:      admin_invite_user_errors,
  127:      admin_delete_room,
  128:      admin_delete_room_non_existent_domain,
  129:      admin_kick_user,
  130:      admin_send_message_to_room,
  131:      admin_send_message_to_room_errors,
  132:      admin_get_room_messages_muc_light_or_mam_not_configured,
  133:      admin_list_user_rooms,
  134:      admin_list_user_rooms_non_existent_domain,
  135:      admin_list_room_users,
  136:      admin_list_room_users_non_existent_domain,
  137:      admin_get_room_config,
  138:      admin_get_room_config_non_existent_domain,
  139:      admin_blocking_list,
  140:      admin_blocking_list_null,
  141:      admin_blocking_list_errors
  142:     ].
  143: 
  144: admin_muc_light_with_mam_tests() ->
  145:     [admin_get_room_messages,
  146:      admin_get_room_messages_non_existent_domain].
  147: 
  148: domain_admin_muc_light_tests() ->
  149:     [admin_create_room,
  150:      admin_create_room_with_unprepped_domain,
  151:      admin_create_room_with_custom_fields,
  152:      domain_admin_create_room_no_permission,
  153:      admin_create_identified_room,
  154:      admin_create_room_with_unprepped_id,
  155:      domain_admin_create_identified_room_no_permission,
  156:      admin_change_room_config,
  157:      admin_change_room_config_with_custom_fields,
  158:      admin_change_room_config_errors,
  159:      domain_admin_change_room_config_no_permission,
  160:      admin_invite_user,
  161:      admin_invite_user_errors,
  162:      domain_admin_invite_user_no_permission,
  163:      admin_delete_room,
  164:      domain_admin_delete_room_no_permission,
  165:      admin_kick_user,
  166:      domain_admin_kick_user_no_permission,
  167:      admin_send_message_to_room,
  168:      admin_send_message_to_room_errors,
  169:      domain_admin_send_message_to_room_no_permission,
  170:      admin_get_room_messages_muc_light_or_mam_not_configured,
  171:      admin_list_user_rooms,
  172:      domain_admin_list_user_rooms_no_permission,
  173:      admin_list_room_users,
  174:      domain_admin_list_room_users_no_permission,
  175:      admin_get_room_config,
  176:      domain_admin_get_room_config_no_permission,
  177:      admin_blocking_list,
  178:      domain_admin_blocking_list_no_permission
  179:     ].
  180: 
  181: domain_admin_muc_light_with_mam_tests() ->
  182:     [admin_get_room_messages,
  183:      domain_admin_get_room_messages_no_permission].
  184: 
  185: admin_muc_light_not_configured_tests() ->
  186:     [admin_create_room_muc_light_not_configured,
  187:      admin_change_room_config_muc_light_not_configured,
  188:      admin_invite_user_muc_light_not_configured,
  189:      admin_delete_room_muc_light_not_configured,
  190:      admin_kick_user_muc_light_not_configured,
  191:      admin_send_message_to_room_muc_light_not_configured,
  192:      admin_get_room_messages_muc_light_or_mam_not_configured,
  193:      admin_list_user_rooms_muc_light_not_configured,
  194:      admin_list_room_users_muc_light_not_configured,
  195:      admin_get_room_config_muc_light_not_configured,
  196:      admin_blocking_list_muc_light_not_configured].
  197: 
  198: init_per_suite(Config) ->
  199:     HostType = domain_helper:host_type(),
  200:     SecondaryHostType = domain_helper:secondary_host_type(),
  201:     Config1 = dynamic_modules:save_modules(HostType, Config),
  202:     Config2 = dynamic_modules:save_modules(SecondaryHostType, Config1),
  203:     Config3 = ejabberd_node_utils:init(mim(), Config2),
  204:     escalus:init_per_suite(Config3).
  205: 
  206: end_per_suite(Config) ->
  207:     escalus_fresh:clean(),
  208:     dynamic_modules:restore_modules(Config),
  209:     escalus:end_per_suite(Config).
  210: 
  211: required_modules(_) ->
  212:     Backend = mongoose_helper:mnesia_or_rdbms_backend(),
  213:     MucLightOpts = mod_config(mod_muc_light, #{backend => Backend,
  214:                                                rooms_in_rosters => true,
  215:                                                config_schema => custom_schema()}),
  216:     [{mod_muc_light, MucLightOpts}].
  217: 
  218: custom_schema() ->
  219:     %% Should be sorted
  220:     [{<<"background">>, <<>>, background, binary},
  221:      {<<"music">>, <<>>, music, binary},
  222:      %% Default fields
  223:      {<<"roomname">>, <<>>, roomname, binary},
  224:      {<<"subject">>, <<"Test">>, subject, binary}].
  225: 
  226: init_per_group(admin_http, Config) ->
  227:     graphql_helper:init_admin_handler(Config);
  228: init_per_group(admin_cli, Config) ->
  229:     graphql_helper:init_admin_cli(Config);
  230: init_per_group(domain_admin, Config) ->
  231:     graphql_helper:init_domain_admin_handler(Config);
  232: init_per_group(Group, Config) when Group =:= user_muc_light;
  233:                                    Group =:= admin_muc_light;
  234:                                    Group =:= domain_admin_muc_light ->
  235:     disable_mam(),
  236:     ensure_muc_light_started(Config);
  237: init_per_group(Group, Config) when Group =:= user_muc_light_with_mam;
  238:                                    Group =:= admin_muc_light_with_mam;
  239:                                    Group =:= domain_admin_muc_light_with_mam ->
  240:     case maybe_enable_mam() of
  241:         true ->
  242:             ensure_muc_started(),
  243:             ensure_muc_light_started(Config);
  244:         false ->
  245:             {skip, "No MAM backend available"}
  246:     end;
  247: init_per_group(Group, Config) when Group =:= user_muc_light_not_configured;
  248:                                    Group =:= admin_muc_light_not_configured ->
  249:     maybe_enable_mam(),
  250:     ensure_muc_light_stopped(Config);
  251: init_per_group(user, Config) ->
  252:     graphql_helper:init_user(Config).
  253: 
  254: disable_mam() ->
  255:     dynamic_modules:ensure_modules(domain_helper:host_type(), [{mod_mam, stopped}]).
  256: 
  257: maybe_enable_mam() ->
  258:     case mam_helper:backend() of
  259:         disabled ->
  260:             false;
  261:         Backend ->
  262:             MAMOpts = mam_helper:config_opts(
  263:                         #{backend => Backend,
  264:                           muc => #{host => subhost_pattern(muc_light_helper:muc_host_pattern())},
  265:                           async_writer => #{enabled => false}}),
  266:             dynamic_modules:ensure_modules(domain_helper:host_type(), [{mod_mam, MAMOpts}]),
  267:             true
  268:     end.
  269: 
  270: ensure_muc_light_started(Config) ->
  271:     HostType = domain_helper:host_type(),
  272:     SecondaryHostType = domain_helper:secondary_host_type(),
  273:     dynamic_modules:ensure_modules(HostType, required_modules(suite)),
  274:     dynamic_modules:ensure_modules(SecondaryHostType, required_modules(suite)),
  275:     [{muc_light_host, muc_light_helper:muc_host()},
  276:      {secondary_muc_light_host, <<"muclight.", (domain_helper:secondary_domain())/binary>>}
  277:      | Config].
  278: 
  279: ensure_muc_light_stopped(Config) ->
  280:     HostType = domain_helper:host_type(),
  281:     SecondaryHostType = domain_helper:secondary_host_type(),
  282:     dynamic_modules:ensure_modules(HostType, [{mod_muc_light, stopped}]),
  283:     dynamic_modules:ensure_modules(SecondaryHostType, [{mod_muc_light, stopped}]),
  284:     [{muc_light_host, <<"NON_EXISTING">>} | Config].
  285: 
  286: ensure_muc_started() ->
  287:     muc_helper:load_muc(),
  288:     mongoose_helper:ensure_muc_clean().
  289: 
  290: ensure_muc_stopped() ->
  291:     muc_helper:unload_muc().
  292: 
  293: end_per_group(Group, _Config) when Group =:= user;
  294:                                    Group =:= admin_http;
  295:                                    Group =:= admin_cli;
  296:                                    Group =:= domain_admin ->
  297:     maybe_clear_db(),
  298:     graphql_helper:clean();
  299: end_per_group(Group, _Config) when Group =:= user_muc_light_with_mam;
  300:                                    Group =:= admin_muc_light_with_mam;
  301:                                    Group =:= domain_admin_muc_light_with_mam ->
  302:     maybe_clear_db(),
  303:     ensure_muc_stopped(),
  304:     escalus_fresh:clean();
  305: end_per_group(_Group, _Config) ->
  306:     maybe_clear_db(),
  307:     escalus_fresh:clean().
  308: 
  309: maybe_clear_db() ->
  310:     case mongoose_helper:is_rdbms_enabled(domain_helper:host_type()) of
  311:         true ->
  312:             F = fun() -> rpc(mim(), mod_muc_light_db_rdbms, force_clear, []) end,
  313:             mongoose_helper:wait_until(F, ok);
  314:         false ->
  315:             ok
  316:     end.
  317: 
  318: init_per_testcase(TC, Config) ->
  319:     rest_helper:maybe_skip_mam_test_cases(TC, [user_get_room_messages,
  320:                                                admin_get_room_messages], Config).
  321: 
  322: end_per_testcase(TC, Config) ->
  323:     escalus:end_per_testcase(TC, Config).
  324: 
  325: %% User test cases
  326: 
  327: user_create_room(Config) ->
  328:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_create_room_story/2).
  329: 
  330: user_create_room_story(Config, Alice) ->
  331:     MucServer = ?config(muc_light_host, Config),
  332:     AliceBinLower = escalus_utils:jid_to_lower(escalus_client:short_jid(Alice)),
  333:     Name = <<"first room">>,
  334:     Subject = <<"testing">>,
  335:     Res = user_create_room(Alice, MucServer, Name, Subject, null, Config),
  336:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject,
  337:       <<"participants">> := Participants} = get_ok_value(?CREATE_ROOM_PATH, Res),
  338:     ?assertMatch(#jid{lserver = MucServer}, jid:from_binary(JID)),
  339:     ?assertEqual([#{<<"jid">> => AliceBinLower, <<"affiliation">> => <<"OWNER">>}], Participants),
  340:     % Try with a non-existent domain
  341:     Res2 = user_create_room(Alice, ?UNKNOWN_DOMAIN, Name, Subject, null, Config),
  342:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)).
  343: 
  344: user_create_room_with_unprepped_domain(Config) ->
  345:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  346:                                     fun user_create_room_with_unprepped_domain_story/2).
  347: 
  348: user_create_room_with_unprepped_domain_story(Config, Alice) ->
  349:     MucServer = ?config(muc_light_host, Config),
  350:     Name = <<"room with unprepped domain">>,
  351:     Subject = <<"testing">>,
  352:     Res = user_create_room(Alice, unprep(MucServer), Name, Subject, null, Config),
  353:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
  354:         get_ok_value(?CREATE_ROOM_PATH, Res),
  355:     ?assertMatch(#jid{lserver = MucServer}, jid:from_binary_noprep(JID)).
  356: 
  357: user_create_room_with_bad_config(Config) ->
  358:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  359:                                     fun user_create_room_with_bad_config_story/2).
  360: 
  361: user_create_room_with_bad_config_story(Config, Alice) ->
  362:     MucServer = ?config(muc_light_host, Config),
  363:     Name = <<"room with custom fields">>,
  364:     Subject = <<"testing_custom">>,
  365:     Opts = #{<<"badkey">> => <<"badvalue">>},
  366:     Res =  user_create_room_with_options(Alice, MucServer, Name, Subject, null, Opts, Config),
  367:     ?assertMatch({_, _}, binary:match(get_err_msg(Res), <<"Validation failed for key: badkey">>)).
  368: 
  369: user_create_room_with_custom_fields(Config) ->
  370:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_create_room_with_custom_fields_story/2).
  371: 
  372: user_create_room_with_custom_fields_story(Config, Alice) ->
  373:     MucServer = ?config(muc_light_host, Config),
  374:     AliceBinLower = escalus_utils:jid_to_lower(escalus_client:short_jid(Alice)),
  375:     Name = <<"room with custom fields">>,
  376:     Subject = <<"testing_custom">>,
  377:     Opts = [#{<<"key">> => <<"background">>, <<"value">> => <<"red">>},
  378:             #{<<"key">> => <<"roomname">>, <<"value">> => Name},
  379:             #{<<"key">> => <<"subject">>, <<"value">> => Subject}],
  380:     Res = user_create_room_with_options(Alice, MucServer, Name, Subject, null,
  381:                                         #{<<"background">> => <<"red">>}, Config),
  382:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject,
  383:       <<"participants">> := Participants, <<"options">> := Opts}
  384:         = get_ok_value(?CREATE_ROOM_PATH, Res),
  385:     ?assertMatch(#jid{lserver = MucServer}, jid:from_binary(JID)),
  386:     ?assertEqual([#{<<"jid">> => AliceBinLower, <<"affiliation">> => <<"OWNER">>}], Participants).
  387: 
  388: user_create_identified_room(Config) ->
  389:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_create_identified_room_story/2).
  390: 
  391: user_create_identified_room_story(Config, Alice) ->
  392:     MucServer = ?config(muc_light_host, Config),
  393:     Name = <<"first room">>,
  394:     Subject = <<"testing">>,
  395:     Id = <<"my_user_room">>,
  396:     Res = user_create_room(Alice, MucServer, Name, Subject, Id, Config),
  397:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
  398:         get_ok_value(?CREATE_ROOM_PATH, Res),
  399:     ?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary(JID)),
  400:     % Create a room with an existing ID
  401:     Res2 = user_create_room(Alice, MucServer, <<"snd room">>, Subject, Id, Config),
  402:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"already exists">>)),
  403:     % Try with a non-existent domain
  404:     Res3 = user_create_room(Alice, ?UNKNOWN_DOMAIN, <<"name">>, Subject, Id, Config),
  405:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)),
  406:     % Try with an empty string passed as ID
  407:     Res4 = user_create_room(Alice, MucServer, <<"name">>, Subject, <<>>, Config),
  408:     ?assertMatch({_, _}, binary:match(get_coercion_err_msg(Res4), <<"empty_room_name">>)).
  409: 
  410: user_create_room_with_unprepped_id(Config) ->
  411:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  412:                                     fun user_create_room_with_unprepped_id_story/2).
  413: 
  414: user_create_room_with_unprepped_id_story(Config, Alice) ->
  415:     MucServer = ?config(muc_light_host, Config),
  416:     Name = <<"first room">>,
  417:     Subject = <<"testing">>,
  418:     Id = <<"user_room_with_unprepped_id">>,
  419:     Res = user_create_room(Alice, unprep(MucServer), Name, Subject, unprep(Id), Config),
  420:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
  421:         get_ok_value(?CREATE_ROOM_PATH, Res),
  422:     ?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary_noprep(JID)).
  423: 
  424: user_change_room_config(Config) ->
  425:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_change_room_config_story/2).
  426: 
  427: user_change_room_config_story(Config, Alice) ->
  428:     AliceBin = escalus_client:short_jid(Alice),
  429:     MUCServer = ?config(muc_light_host, Config),
  430:     % Create a new room
  431:     {ok, #{jid := RoomJID}} = create_room(MUCServer, <<"ornithology">>, <<"birds">>, AliceBin),
  432:     % Try to change the room configuration
  433:     Name2 = <<"changed room">>,
  434:     Subject2 = <<"not testing">>,
  435:     Res = user_change_room_configuration(Alice, jid:to_binary(RoomJID), Name2, Subject2, Config),
  436:     ?assertMatch(#{<<"name">> := Name2, <<"subject">> := Subject2}, get_ok_value(?CHANGE_CONFIG_PATH, Res)).
  437: 
  438: user_change_room_config_with_custom_fields(Config) ->
  439:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_change_room_config_with_custom_fields_story/2).
  440: 
  441: user_change_room_config_with_custom_fields_story(Config, Alice) ->
  442:     AliceBin = escalus_client:short_jid(Alice),
  443:     MUCServer = ?config(muc_light_host, Config),
  444:     % Create a new room
  445:     {ok, #{jid := RoomJID}} = create_room(MUCServer, <<"ornithology">>, <<"birds">>, AliceBin),
  446:     % Try to change the room configuration
  447:     Name2 = <<"changed room">>,
  448:     Subject2 = <<"not testing">>,
  449:     Opts2 = #{<<"music">> => <<"sad">>},
  450:     Res = user_change_room_configuration_with_custom_fields(Alice, jid:to_binary(RoomJID), Name2, Subject2, Config, Opts2),
  451:     Opts3 = [#{<<"key">> => <<"music">>, <<"value">> => <<"sad">>},
  452:              #{<<"key">> => <<"roomname">>, <<"value">> => Name2},
  453:              #{<<"key">> => <<"subject">>, <<"value">> => Subject2}],
  454:     ?assertMatch(#{<<"name">> := Name2, <<"subject">> := Subject2, <<"options">> := Opts3}, get_ok_value(?CHANGE_CONFIG_PATH, Res)).
  455: 
  456: user_change_room_config_errors(Config) ->
  457:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
  458:                                     fun user_change_room_config_errors_story/3).
  459: 
  460: user_change_room_config_errors_story(Config, Alice, Bob) ->
  461:     MUCServer = ?config(muc_light_host, Config),
  462:     AliceBin = escalus_client:short_jid(Alice),
  463:     BobBin = escalus_client:short_jid(Bob),
  464:     RoomName = <<"first room">>,
  465:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  466:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  467:     % Try to change the config with a non-existent domain
  468:     Res = user_change_room_configuration(
  469:             Alice, make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), RoomName, <<"subject2">>, Config),
  470:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)),
  471:     % Try to change the config of the non-existent room
  472:     Res2 = user_change_room_configuration(
  473:              Alice, make_bare_jid(?UNKNOWN, MUCServer), RoomName, <<"subject2">>, Config),
  474:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)),
  475:     % Try to change the config by the user that does not occupy this room
  476:     Res3 = user_change_room_configuration(
  477:              Bob, jid:to_binary(RoomJID), RoomName, <<"subject2">>, Config),
  478:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not occupy this room">>)),
  479:     % Try to change a config by the user without permission
  480:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  481:     Res4 = user_change_room_configuration(
  482:              Bob, jid:to_binary(RoomJID), RoomName, <<"subject2">>, Config),
  483:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4),
  484:                                           <<"does not have permission to change">>)).
  485: 
  486: user_invite_user(Config) ->
  487:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_invite_user_story/3).
  488: 
  489: user_invite_user_story(Config, Alice, Bob) ->
  490:     MUCServer = ?config(muc_light_host, Config),
  491:     AliceBin = escalus_client:short_jid(Alice),
  492:     BobBin = escalus_client:short_jid(Bob),
  493:     Domain = escalus_client:server(Alice),
  494:     Name = <<"first room">>,
  495:     {ok, #{jid := RoomJID}} = create_room(MUCServer, Name, <<"subject2">>, AliceBin),
  496:     % Room owner can invite a user
  497:     Res = user_invite_user(Alice, jid:to_binary(RoomJID), BobBin, Config),
  498:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?INVITE_USER_PATH, Res),
  499:                                           <<"successfully">>)),
  500:     escalus:wait_for_stanza(Bob),
  501:     BobName = escalus_utils:jid_to_lower(escalus_client:username(Bob)),
  502:     AliceName = escalus_utils:jid_to_lower(escalus_client:username(Alice)),
  503:     ExpectedAff = lists:sort([{{AliceName, Domain}, owner},
  504:                               {{BobName, Domain}, member}]),
  505:     ?assertMatch(ExpectedAff, lists:sort(get_room_aff(RoomJID))).
  506: 
  507: user_invite_user_errors(Config) ->
  508:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
  509:                                     fun user_invite_user_errors_story/3).
  510: 
  511: user_invite_user_errors_story(Config, Alice, Bob) ->
  512:     MUCServer = ?config(muc_light_host, Config),
  513:     AliceBin = escalus_client:short_jid(Alice),
  514:     BobBin = escalus_client:short_jid(Bob),
  515:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  516:         create_room(MUCServer, <<"first room">>, <<"subject">>, AliceBin),
  517:     % Try to invite a user to not existing room
  518:     Res = user_invite_user(Alice, make_bare_jid(?UNKNOWN, MUCServer), BobBin, Config),
  519:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)),
  520:     % User without rooms tries to invite a user
  521:     Res2 = user_invite_user(Bob, jid:to_binary(RoomJID), AliceBin, Config),
  522:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"does not occupy this room">>)),
  523:     % Try with a non-existent domain
  524:     Res3 = user_invite_user(Alice, make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), BobBin, Config),
  525:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)).
  526: 
  527: user_delete_room(Config) ->
  528:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_delete_room_story/3).
  529: 
  530: user_delete_room_story(Config, Alice, Bob) ->
  531:     MUCServer = ?config(muc_light_host, Config),
  532:     AliceBin = escalus_client:short_jid(Alice),
  533:     BobBin = escalus_client:short_jid(Bob),
  534:     Name = <<"first room">>,
  535:     {ok, #{jid := #jid{luser = RoomID} = RoomJID} = RoomInfo} =
  536:         create_room(MUCServer, Name, <<"subject">>, AliceBin),
  537:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  538:     % Member cannot delete room
  539:     Res = user_delete_room(Bob, jid:to_binary(RoomJID), Config),
  540:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res),
  541:                                           <<"cannot delete this room">>)),
  542:     % Owner can delete own room
  543:     Res2 = user_delete_room(Alice, jid:to_binary(RoomJID), Config),
  544:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?DELETE_ROOM_PATH, Res2),
  545:                                           <<"successfully">>)),
  546:     ?assertEqual({error, not_exists}, get_room_info(RoomJID), RoomInfo),
  547:     % Try with a non-existent domain
  548:     Res3 = user_delete_room(Alice, make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Config),
  549:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)),
  550:     % Try with a non-existent room
  551:     Res4 = user_delete_room(Alice, make_bare_jid(?UNKNOWN, MUCServer), Config),
  552:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not found">>)).
  553: 
  554: user_kick_user(Config) ->
  555:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_kick_user_story/3).
  556: 
  557: user_kick_user_story(Config, Alice, Bob) ->
  558:     MUCServer = ?config(muc_light_host, Config),
  559:     AliceBin = escalus_client:short_jid(Alice),
  560:     BobBin = escalus_client:short_jid(Bob),
  561:     RoomName = <<"first room">>,
  562:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  563:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  564:     % Member kicks himself from a room
  565:     ?assertEqual(2, length(get_room_aff(RoomJID))),
  566:     Res = user_kick_user(Bob, jid:to_binary(RoomJID), null, Config),
  567:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?KICK_USER_PATH, Res),
  568:                                           <<"successfully">>)),
  569:     ?assertEqual(1, length(get_room_aff(RoomJID))),
  570:     % Member cannot kick the room owner.
  571:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  572:     Res2 = user_kick_user(Bob, jid:to_binary(RoomJID), AliceBin, Config),
  573:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"does not have permission">>)),
  574:     ?assertEqual(2, length(get_room_aff(RoomJID))),
  575:     % Owner kicks the member from a room
  576:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  577:     Res3 = user_kick_user(Alice, jid:to_binary(RoomJID), BobBin, Config),
  578:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?KICK_USER_PATH, Res3), <<"successfully">>)),
  579:     ?assertEqual(1, length(get_room_aff(RoomJID))).
  580: 
  581: user_send_message_to_room(Config) ->
  582:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
  583:                                     fun user_send_message_to_room_story/3).
  584: 
  585: user_send_message_to_room_story(Config, Alice, Bob) ->
  586:     MUCServer = ?config(muc_light_host, Config),
  587:     AliceBin = escalus_client:short_jid(Alice),
  588:     BobBin = escalus_client:short_jid(Bob),
  589:     RoomName = <<"first room">>,
  590:     MsgBody = <<"Hello there!">>,
  591:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  592:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  593:     Res = user_send_message_to_room(Alice, jid:to_binary(RoomJID), MsgBody, Config),
  594:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SEND_MESSAGE_PATH, Res), <<"successfully">>)),
  595:     [_, Msg] = escalus:wait_for_stanzas(Bob, 2),
  596:     escalus:assert(is_message, Msg).
  597: 
  598: user_send_message_to_room_errors(Config) ->
  599:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
  600:                                     fun user_send_message_to_room_errors_story/3).
  601: 
  602: user_send_message_to_room_errors_story(Config, Alice, Bob) ->
  603:     MUCServer = ?config(muc_light_host, Config),
  604:     AliceBin = escalus_client:short_jid(Alice),
  605:     BobBin = escalus_client:short_jid(Bob),
  606:     MsgBody = <<"Hello there!">>,
  607:     {ok, #{jid := #jid{luser = ARoomID} = ARoomJID}} =
  608:         create_room(MUCServer, <<"alice room">>, <<"subject">>, AliceBin),
  609:     % Try with a non-existent domain
  610:     Res = user_send_message_to_room(
  611:             Alice, make_bare_jid(ARoomID, ?UNKNOWN_DOMAIN), MsgBody, Config),
  612:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)),
  613:     % Try with a user without rooms
  614:     Res2 = user_send_message_to_room(Bob, jid:to_binary(ARoomJID), MsgBody, Config),
  615:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not occupy this room">>)),
  616:     % Try with a room not occupied by this user
  617:     {ok, #{jid := _RoomJID2}} = create_room(MUCServer, <<"bob room">>, <<"subject">>, BobBin),
  618:     Res3 = user_send_message_to_room(Bob, jid:to_binary(ARoomJID), MsgBody, Config),
  619:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not occupy this room">>)).
  620: 
  621: user_get_room_messages(Config) ->
  622:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_get_room_messages_story/3).
  623: 
  624: user_get_room_messages_story(Config, Alice, Bob) ->
  625:     MUCServer = ?config(muc_light_host, Config),
  626:     AliceBin = escalus_client:short_jid(Alice),
  627:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  628:         create_room(MUCServer, <<"first room">>, <<"subject">>, AliceBin),
  629:     Message = <<"Hello friends">>,
  630:     send_message_to_room(RoomJID, jid:from_binary(AliceBin), Message),
  631:     mam_helper:wait_for_room_archive_size(MUCServer, RoomID, 1),
  632:     % Get messages so far
  633:     Limit = 40,
  634:     Res = user_get_room_messages(Alice, jid:to_binary(RoomJID), Limit, null, Config),
  635:     #{<<"stanzas">> :=[#{<<"stanza">> := StanzaXML}], <<"limit">> := Limit} =
  636:         get_ok_value(?GET_MESSAGES_PATH, Res),
  637:     ?assertMatch({ok, #xmlel{name = <<"message">>}}, exml:parse(StanzaXML)),
  638:     % Get messages before the given date and time
  639:     Before = <<"2022-02-17T04:54:13+00:00">>,
  640:     Res2 = user_get_room_messages(Alice, jid:to_binary(RoomJID), null, Before, Config),
  641:     ?assertMatch(#{<<"stanzas">> := [], <<"limit">> := 50}, get_ok_value(?GET_MESSAGES_PATH, Res2)),
  642:     % Try to pass too big page size value
  643:     Res3 = user_get_room_messages(Alice, jid:to_binary(RoomJID), 51, Before, Config),
  644:     ?assertMatch(#{<<"limit">> := 50}, get_ok_value(?GET_MESSAGES_PATH, Res3)),
  645:     % Try with a non-existent domain
  646:     Res4 = user_get_room_messages(
  647:              Alice, make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Limit, null, Config),
  648:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"server not found">>)),
  649:     % Try with a user that is not a room member
  650:     Res5 = user_get_room_messages(Bob, jid:to_binary(RoomJID), Limit, null, Config),
  651:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res5), <<"not occupy this room">>)).
  652: 
  653: user_shouldnt_store_messages_in_muc(Config) ->
  654:     muc_helper:story_with_room(Config, [], [{alice, 1}],
  655:                                fun user_shouldnt_store_messages_in_muc_story/2).
  656: 
  657: user_shouldnt_store_messages_in_muc_story(Config, Alice) ->
  658:     %% Enter a MUC room
  659:     MUCRoomJID = jid:from_binary(?config(room_jid, Config)),
  660:     enter_muc_room(MUCRoomJID, Alice, <<"Ali">>),
  661:     escalus:wait_for_stanza(Alice),
  662:     %% Send a message
  663:     Message = <<"Hello friends">>,
  664:     send_message_to_muc_room(Alice, MUCRoomJID, Message, null, Config),
  665:     escalus:wait_for_stanza(Alice),
  666:     %% Try to get a MUC message
  667:     Limit = 1,
  668:     Res3 = user_get_muc_room_messages(Alice, jid:to_binary(MUCRoomJID), Limit, null, Config),
  669:     #{<<"stanzas">> := [], <<"limit">> := Limit} = get_ok_value([data, muc, getRoomMessages], Res3).
  670: 
  671: user_list_rooms(Config) ->
  672:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_list_rooms_story/2).
  673: 
  674: user_list_rooms_story(Config, Alice) ->
  675:     MUCServer = ?config(muc_light_host, Config),
  676:     AliceBin = escalus_client:short_jid(Alice),
  677:     {ok, #{jid := RoomJID}} = create_room(MUCServer, <<"room a">>, <<"subject">>, AliceBin),
  678:     {ok, #{jid := RoomJID2}} = create_room(MUCServer, <<"room b">>, <<"subject">>, AliceBin),
  679:     Res = user_list_rooms(Alice, Config),
  680:     ?assertEqual(lists:sort([jid:to_binary(RoomJID), jid:to_binary(RoomJID2)]),
  681:                  lists:sort(get_ok_value(?USER_LIST_ROOMS_PATH, Res))).
  682: 
  683: user_list_room_users(Config) ->
  684:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_list_room_users_story/3).
  685: 
  686: user_list_room_users_story(Config, Alice, Bob) ->
  687:     MUCServer = ?config(muc_light_host, Config),
  688:     AliceBin = escalus_client:short_jid(Alice),
  689:     BobBin = escalus_client:short_jid(Bob),
  690:     AliceLower = escalus_utils:jid_to_lower(AliceBin),
  691:     {ok, #{jid := RoomJID}} = create_room(MUCServer, <<"room a">>, <<"subject">>, AliceBin),
  692:     % Owner can list room users
  693:     Res = user_list_room_users(Alice, jid:to_binary(RoomJID), Config),
  694:     ?assertEqual([#{<<"jid">> => AliceLower, <<"affiliation">> => <<"OWNER">>}],
  695:                  get_ok_value(?LIST_ROOM_USERS_PATH, Res)),
  696:     % Try with a non-existent domain
  697:     Res2 = user_list_room_users(Alice, make_bare_jid(RoomJID#jid.luser, ?UNKNOWN_DOMAIN), Config),
  698:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)),
  699:     % Try with a non-existent room
  700:     Res3 = user_list_room_users(Alice, make_bare_jid(?UNKNOWN, MUCServer), Config),
  701:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)),
  702:     % User that is not a member cannot get aff
  703:     Res4 = user_list_room_users(Bob, jid:to_binary(RoomJID), Config),
  704:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not occupy this room">>)),
  705:     % Member can get aff
  706:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  707:     escalus:wait_for_stanza(Bob),
  708:     Res5 = user_list_room_users(Bob, jid:to_binary(RoomJID), Config),
  709:     ?assertMatch([_, _], get_ok_value(?LIST_ROOM_USERS_PATH, Res5)).
  710: 
  711: user_get_room_config(Config) ->
  712:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_get_room_config_story/3).
  713: 
  714: user_get_room_config_story(Config, Alice, Bob) ->
  715:     MUCServer = ?config(muc_light_host, Config),
  716:     AliceBin = escalus_client:short_jid(Alice),
  717:     BobBin = escalus_client:short_jid(Bob),
  718:     AliceLower = escalus_utils:jid_to_lower(AliceBin),
  719:     BobLower = escalus_utils:jid_to_lower(BobBin),
  720:     RoomName = <<"first room">>,
  721:     RoomSubject = <<"Room about nothing">>,
  722:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  723:         create_room(MUCServer, RoomName, RoomSubject, AliceBin),
  724:     RoomJIDBin = jid:to_binary(RoomJID),
  725:     Res = user_get_room_config(Alice, jid:to_binary(RoomJID), Config),
  726:     % Owner can get a config
  727:     ?assertEqual(#{<<"jid">> => RoomJIDBin, <<"subject">> => RoomSubject, <<"name">> => RoomName,
  728:                     <<"options">> => [#{<<"key">> => <<"background">>, <<"value">> => <<>>},
  729:                                       #{<<"key">> => <<"music">>, <<"value">> => <<>>},
  730:                                       #{<<"key">> => <<"roomname">>, <<"value">> => RoomName},
  731:                                       #{<<"key">> => <<"subject">>, <<"value">> => RoomSubject}],
  732:                     <<"participants">> => [#{<<"jid">> => AliceLower,
  733:                                              <<"affiliation">> => <<"OWNER">>}]},
  734:                  get_ok_value(?GET_ROOM_CONFIG_PATH, Res)),
  735:     % Try with a non-existent domain
  736:     Res2 = user_get_room_config(Alice, make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Config),
  737:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)),
  738:     % Try with a non-existent room
  739:     Res3 = user_get_room_config(Alice, make_bare_jid(?UNKNOWN, MUCServer), Config),
  740:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)),
  741:     % User that is not a member cannot get a room config
  742:     Res4 = user_get_room_config(Bob, jid:to_binary(RoomJID), Config),
  743:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"not occupy this room">>)),
  744:     % Member can get a config
  745:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  746:     Res5 = user_get_room_config(Bob, jid:to_binary(RoomJID), Config),
  747:     ?assertEqual(#{<<"jid">> => RoomJIDBin, <<"subject">> => RoomSubject, <<"name">> => RoomName,
  748:                     <<"options">> => [#{<<"key">> => <<"background">>, <<"value">> => <<>>},
  749:                                       #{<<"key">> => <<"music">>, <<"value">> => <<>>},
  750:                                       #{<<"key">> => <<"roomname">>, <<"value">> => RoomName},
  751:                                       #{<<"key">> => <<"subject">>, <<"value">> => RoomSubject}],
  752:                     <<"participants">> => [#{<<"jid">> => AliceLower,
  753:                                              <<"affiliation">> => <<"OWNER">>},
  754:                                            #{<<"jid">> => BobLower,
  755:                                              <<"affiliation">> => <<"MEMBER">>}]},
  756:                  get_ok_value(?GET_ROOM_CONFIG_PATH, Res5)).
  757: 
  758: user_blocking_list(Config) ->
  759:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun user_blocking_list_story/3).
  760: 
  761: user_blocking_list_story(Config, Alice, Bob) ->
  762:     BobBin = escalus_client:full_jid(Bob),
  763:     BobShortBin = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)),
  764:     {ok, #{jid := RoomJID}} = create_room(?config(muc_light_host, Config),
  765:                                           <<"room">>, <<"subject">>, BobBin),
  766:     RoomBin = jid:to_binary(RoomJID),
  767:     Res = user_get_blocking(Alice, Config),
  768:     ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res)),
  769:     Res2 = user_set_blocking(Alice, [{<<"USER">>, <<"DENY">>, BobBin}], Config),
  770:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res2),
  771:                                           <<"successfully">>)),
  772:     Res3 = user_get_blocking(Alice, Config),
  773:     ?assertEqual([#{<<"entityType">> => <<"USER">>,
  774:                     <<"action">> => <<"DENY">>,
  775:                     <<"entity">> => BobShortBin}],
  776:                  get_ok_value(?GET_BLOCKING_LIST_PATH, Res3)),
  777:     Res4 = user_set_blocking(Alice, [{<<"USER">>, <<"ALLOW">>, BobBin},
  778:                                      {<<"ROOM">>, <<"DENY">>, jid:to_binary(RoomJID)}], Config),
  779:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res4),
  780:                                           <<"successfully">>)),
  781:     Res5 = user_get_blocking(Alice, Config),
  782:     ?assertEqual([#{<<"entityType">> => <<"ROOM">>,
  783:                     <<"action">> => <<"DENY">>,
  784:                     <<"entity">> => RoomBin}],
  785:                  get_ok_value(?GET_BLOCKING_LIST_PATH, Res5)).
  786: 
  787: %% Domain admin test cases
  788: 
  789: domain_admin_create_room_no_permission(Config) ->
  790:     escalus:fresh_story_with_config(Config, [{alice, 1}, {alice_bis, 1}],
  791:                                     fun domain_admin_create_room_no_permission_story/3).
  792: 
  793: domain_admin_create_room_no_permission_story(Config, Alice, AliceBis) ->
  794:     AliceBin = escalus_client:short_jid(Alice),
  795:     AliceBisBin = escalus_client:short_jid(AliceBis),
  796:     InvalidUser = make_bare_jid(?UNKNOWN, ?UNKNOWN_DOMAIN),
  797:     MucServer = ?config(muc_light_host, Config),
  798:     ExternalMucServer = ?config(secondary_muc_light_host, Config),
  799:     Name = <<"first room">>,
  800:     Subject = <<"testing">>,
  801:     % Try with a non-existent domain
  802:     Res = create_room(MucServer, Name, InvalidUser, Subject, null, Config),
  803:     get_unauthorized(Res),
  804:     % Try with an external domain
  805:     Res2 = create_room(MucServer, Name, AliceBisBin, Subject, null, Config),
  806:     get_unauthorized(Res2),
  807:     % Try to create a room at an external domain
  808:     Res3 = create_room(ExternalMucServer, Name, AliceBin, Subject, null, Config),
  809:     get_unauthorized(Res3).
  810: 
  811: domain_admin_create_identified_room_no_permission(Config) ->
  812:     escalus:fresh_story_with_config(Config, [{alice_bis, 1}],
  813:                                     fun domain_admin_create_identified_room_no_permission_story/2).
  814: 
  815: domain_admin_create_identified_room_no_permission_story(Config, AliceBis) ->
  816:     AliceBisBin = escalus_client:short_jid(AliceBis),
  817:     InvalidUser = make_bare_jid(?UNKNOWN, ?UNKNOWN_DOMAIN),
  818:     MucServer = ?config(muc_light_host, Config),
  819:     Name = <<"first room">>,
  820:     Subject = <<"testing">>,
  821:     SchemaEndpoint = atom_to_binary(?config(schema_endpoint, Config)),
  822:     Protocol = atom_to_binary(?config(protocol, Config)),
  823:     Id = <<"my_room_", SchemaEndpoint/binary, "_", Protocol/binary>>,
  824:     % Try with a non-existent domain
  825:     Res = create_room(MucServer, Name, InvalidUser, Subject, Id, Config),
  826:     get_unauthorized(Res),
  827:     % Try with an external domain
  828:     Res2 = create_room(MucServer, Name, AliceBisBin, Subject, Id, Config),
  829:     get_unauthorized(Res2).
  830: 
  831: domain_admin_change_room_config_no_permission(Config) ->
  832:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
  833:                                     fun domain_admin_change_room_config_no_permission_story/3).
  834: 
  835: domain_admin_change_room_config_no_permission_story(Config, Alice, Bob) ->
  836:     AliceBin = escalus_client:short_jid(Alice),
  837:     BobBin = escalus_client:short_jid(Bob),
  838:     MUCServer = ?config(secondary_muc_light_host, Config),
  839:     RoomName = <<"first room">>,
  840:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  841:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  842:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  843:     RoomJIDBin = jid:to_binary(RoomJID),
  844:     Res = change_room_configuration(RoomJIDBin, AliceBin, RoomName, <<"subject">>, Config),
  845:     get_unauthorized(Res),
  846:     % Try to change the config with an external domain
  847:     Res2 = change_room_configuration(
  848:             make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), AliceBin, RoomName, <<"subject2">>, Config),
  849:     get_unauthorized(Res2).
  850: 
  851: domain_admin_invite_user_no_permission(Config) ->
  852:     escalus:fresh_story_with_config(Config, [{alice_bis, 1}, {bob, 1}],
  853:                                     fun domain_admin_invite_user_no_permission_story/3).
  854: 
  855: domain_admin_invite_user_no_permission_story(Config, AliceBis, Bob) ->
  856:     AliceBisBin = escalus_client:short_jid(AliceBis),
  857:     BobBin = escalus_client:short_jid(Bob),
  858:     MUCServer = ?config(muc_light_host, Config),
  859:     Name = <<"first room">>,
  860:     {ok, #{jid := RoomJID}} = create_room(MUCServer, Name, <<"subject2">>, AliceBisBin),
  861:     Res = invite_user(jid:to_binary(RoomJID), AliceBisBin, BobBin, Config),
  862:     get_unauthorized(Res).
  863: 
  864: domain_admin_delete_room_no_permission(Config) ->
  865:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  866:                                     fun domain_admin_delete_room_no_permission_story/2).
  867: 
  868: domain_admin_delete_room_no_permission_story(Config, Alice) ->
  869:     AliceBin = escalus_client:short_jid(Alice),
  870:     RoomName = <<"first room">>,
  871:     MUCServer = ?config(secondary_muc_light_host, Config),
  872:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  873:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  874:     RoomJIDBin = jid:to_binary(RoomJID),
  875:     Res = delete_room(RoomJIDBin, Config),
  876:     get_unauthorized(Res),
  877:     % Try with a non-existent domain
  878:     Res2 = delete_room(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Config),
  879:     get_unauthorized(Res2).
  880: 
  881: domain_admin_kick_user_no_permission(Config) ->
  882:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
  883:                                     fun domain_admin_kick_user_no_permission_story/3).
  884: 
  885: domain_admin_kick_user_no_permission_story(Config, Alice, Bob) ->
  886:     AliceBin = escalus_client:short_jid(Alice),
  887:     BobBin = escalus_client:short_jid(Bob),
  888:     RoomName = <<"first room">>,
  889:     MUCServer = ?config(secondary_muc_light_host, Config),
  890:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  891:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  892:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
  893:     RoomJIDBin = jid:to_binary(RoomJID),
  894:     ?assertEqual(2, length(get_room_aff(RoomJID))),
  895:     Res = kick_user(RoomJIDBin, BobBin, Config),
  896:     get_unauthorized(Res),
  897:     % Try with a non-existent domain
  898:     Res2 = kick_user(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), BobBin, Config),
  899:     get_unauthorized(Res2).
  900: 
  901: domain_admin_send_message_to_room_no_permission(Config) ->
  902:     escalus:fresh_story_with_config(Config, [{alice_bis, 1}, {bob, 1}],
  903:                                     fun domain_admin_send_message_to_room_no_permission_story/3).
  904: 
  905: domain_admin_send_message_to_room_no_permission_story(Config, AliceBis, Bob) ->
  906:     AliceBisBin = escalus_client:short_jid(AliceBis),
  907:     InvalidUser = make_bare_jid(?UNKNOWN, ?UNKNOWN_DOMAIN),
  908:     BobBin = escalus_client:short_jid(Bob),
  909:     MUCServer = ?config(muc_light_host, Config),
  910:     RoomName = <<"first room">>,
  911:     MsgBody = <<"Hello there!">>,
  912:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBisBin),
  913:     {ok, _} = invite_user(RoomJID, AliceBisBin, BobBin),
  914:     % Try with a non-existent domain
  915:     Res = send_message_to_room(jid:to_binary(RoomJID), InvalidUser, MsgBody, Config),
  916:     get_unauthorized(Res),
  917:     % Try with an external domain room
  918:     Res2 = send_message_to_room(jid:to_binary(RoomJID), AliceBisBin, MsgBody, Config),
  919:     get_unauthorized(Res2).
  920: 
  921: domain_admin_get_room_messages_no_permission(Config) ->
  922:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  923:                                     fun domain_admin_get_room_messages_no_permission_story/2).
  924: 
  925: domain_admin_get_room_messages_no_permission_story(Config, Alice) ->
  926:     AliceBin = escalus_client:short_jid(Alice),
  927:     MUCServer = ?config(secondary_muc_light_host, Config),
  928:     RoomName = <<"first room">>,
  929:     Limit = 40,
  930:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  931:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  932:     RoomJIDBin = jid:to_binary(RoomJID),
  933:     Res = get_room_messages(RoomJIDBin, Limit, null, Config),
  934:     get_unauthorized(Res),
  935:     % Try with a non-existent domain
  936:     Res2 = get_room_messages(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Limit, null, Config),
  937:     get_unauthorized(Res2).
  938: 
  939: domain_admin_list_user_rooms_no_permission(Config) ->
  940:     escalus:fresh_story_with_config(Config, [{alice_bis, 1}],
  941:                                     fun domain_admin_list_user_rooms_no_permission_story/2).
  942: 
  943: domain_admin_list_user_rooms_no_permission_story(Config, AliceBis) ->
  944:     AliceBisBin = escalus_client:short_jid(AliceBis),
  945:     InvalidUser = make_bare_jid(?UNKNOWN, ?UNKNOWN_DOMAIN),
  946:     % Try with a non-existent domain
  947:     Res = list_user_rooms(InvalidUser, Config),
  948:     get_unauthorized(Res),
  949:     % Try with an external domain
  950:     Res2 = list_user_rooms(AliceBisBin, Config),
  951:     get_unauthorized(Res2).
  952: 
  953: domain_admin_list_room_users_no_permission(Config) ->
  954:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  955:                                     fun domain_admin_list_room_users_story_no_permission/2).
  956: 
  957: domain_admin_list_room_users_story_no_permission(Config, Alice) ->
  958:     AliceBin = escalus_client:short_jid(Alice),
  959:     MUCServer = ?config(secondary_muc_light_host, Config),
  960:     RoomName = <<"first room">>,
  961:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  962:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  963:     RoomJIDBin = jid:to_binary(RoomJID),
  964:     Res = list_room_users(RoomJIDBin, Config),
  965:     get_unauthorized(Res),
  966:     % Try with an external domain
  967:     Res2 = list_room_users(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Config),
  968:     get_unauthorized(Res2).
  969: 
  970: domain_admin_get_room_config_no_permission(Config) ->
  971:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  972:                                     fun domain_admin_get_room_config_no_permission_story/2).
  973: 
  974: domain_admin_get_room_config_no_permission_story(Config, Alice) ->
  975:     AliceBin = escalus_client:short_jid(Alice),
  976:     MUCServer = ?config(secondary_muc_light_host, Config),
  977:     RoomName = <<"first room">>,
  978:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
  979:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
  980:     RoomJIDBin = jid:to_binary(RoomJID),
  981:     Res = get_room_config(RoomJIDBin, Config),
  982:     get_unauthorized(Res),
  983:     % Try with a non-existent domain
  984:     Res2 = get_room_config(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Config),
  985:     get_unauthorized(Res2).
  986: 
  987: domain_admin_blocking_list_no_permission(Config) ->
  988:     escalus:fresh_story_with_config(Config, [{alice_bis, 1}],
  989:                                     fun domain_admin_blocking_list_no_permission_story/2).
  990: 
  991: domain_admin_blocking_list_no_permission_story(Config, AliceBis) ->
  992:     AliceBisBin = escalus_client:full_jid(AliceBis),
  993:     InvalidUser = make_bare_jid(?UNKNOWN, ?UNKNOWN_DOMAIN),
  994:     % Try with a non-existent user
  995:     Res = get_user_blocking(InvalidUser, Config),
  996:     get_unauthorized(Res),
  997:     Res2 = set_blocking(InvalidUser, [], Config),
  998:     get_unauthorized(Res2),
  999:     % Try with an external domain user
 1000:     Res3 = get_user_blocking(AliceBisBin, Config),
 1001:     get_unauthorized(Res3),
 1002:     Res4 = set_blocking(AliceBisBin, [], Config),
 1003:     get_unauthorized(Res4).
 1004: 
 1005: %% Admin test cases
 1006: 
 1007: admin_blocking_list(Config) ->
 1008:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_blocking_list_story/3).
 1009: 
 1010: admin_blocking_list_story(Config, Alice, Bob) ->
 1011:     AliceBin = escalus_client:full_jid(Alice),
 1012:     BobBin = escalus_client:full_jid(Bob),
 1013:     BobShortBin = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)),
 1014:     Res = get_user_blocking(AliceBin, Config),
 1015:     ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res)),
 1016:     Res2 = set_blocking(AliceBin, [{<<"USER">>, <<"DENY">>, BobBin}], Config),
 1017:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res2),
 1018:                                           <<"successfully">>)),
 1019:     Res3 = get_user_blocking(AliceBin, Config),
 1020:     ?assertEqual([#{<<"entityType">> => <<"USER">>,
 1021:                     <<"action">> => <<"DENY">>,
 1022:                     <<"entity">> => BobShortBin}],
 1023:                  get_ok_value(?GET_BLOCKING_LIST_PATH, Res3)),
 1024:     Res4 = set_blocking(AliceBin, [{<<"USER">>, <<"ALLOW">>, BobBin}], Config),
 1025:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res4),
 1026:                                           <<"successfully">>)),
 1027:     Res5 = get_user_blocking(AliceBin, Config),
 1028:     ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res5)).
 1029: 
 1030: admin_blocking_list_null(Config) ->
 1031:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1032:                                     fun admin_blocking_list_null_story/3).
 1033: 
 1034: admin_blocking_list_null_story(Config, Alice, Bob) ->
 1035:     AliceBin = escalus_client:full_jid(Alice),
 1036:     BobBin = escalus_client:full_jid(Bob),
 1037:     BobShortBin = escalus_utils:jid_to_lower(escalus_client:short_jid(Bob)),
 1038:     Res = get_user_blocking(AliceBin, Config),
 1039:     ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res)),
 1040:     Res2 = set_blocking(AliceBin, [{<<"USER">>, null, BobBin}], Config),
 1041:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res2),
 1042:                                             <<"successfully">>)),
 1043:     Res3 = get_user_blocking(AliceBin, Config),
 1044:     ?assertEqual([#{<<"entityType">> => <<"USER">>,
 1045:                     <<"action">> => <<"DENY">>,
 1046:                     <<"entity">> => BobShortBin}],
 1047:                     get_ok_value(?GET_BLOCKING_LIST_PATH, Res3)),
 1048:     Res4 = set_blocking(AliceBin, [{<<"USER">>, <<"ALLOW">>, BobBin}], Config),
 1049:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SET_BLOCKING_LIST_PATH, Res4),
 1050:                                             <<"successfully">>)),
 1051:     Res5 = get_user_blocking(AliceBin, Config),
 1052:     ?assertMatch([], get_ok_value(?GET_BLOCKING_LIST_PATH, Res5)).
 1053: 
 1054: admin_blocking_list_errors(Config) ->
 1055:     InvalidUser = make_bare_jid(?UNKNOWN, ?UNKNOWN_DOMAIN),
 1056:     Res = get_user_blocking(InvalidUser, Config),
 1057:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"domain does not exist">>)),
 1058:     Res2 = set_blocking(InvalidUser, [], Config),
 1059:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"domain does not exist">>)),
 1060:     BadUser = make_bare_jid(<<"baduser">>, domain_helper:domain()),
 1061:     Res3 = get_user_blocking(BadUser, Config),
 1062:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"user does not exist">>)),
 1063:     Res4 = set_blocking(BadUser, [], Config),
 1064:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"user does not exist">>)).
 1065: 
 1066: admin_create_room(Config) ->
 1067:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_create_room_story/2).
 1068: 
 1069: admin_create_room_story(Config, Alice) ->
 1070:     AliceBin = escalus_client:short_jid(Alice),
 1071:     AliceBinLower = escalus_utils:jid_to_lower(AliceBin),
 1072:     MucServer = ?config(muc_light_host, Config),
 1073:     Name = <<"first room">>,
 1074:     Subject = <<"testing">>,
 1075:     Res = create_room(MucServer, Name, AliceBin, Subject, null, Config),
 1076:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject,
 1077:       <<"participants">> := Participants} = get_ok_value(?CREATE_ROOM_PATH, Res),
 1078:     ?assertMatch(#jid{lserver = MucServer}, jid:from_binary(JID)),
 1079:     ?assertEqual([#{<<"jid">> => AliceBinLower, <<"affiliation">> => <<"OWNER">>}], Participants),
 1080:     % Try with a non-existent user
 1081:     BadUser = make_bare_jid(<<"baduser">>, domain_helper:domain()),
 1082:     Res1 = create_room(?config(muc_light_host, Config), null, BadUser, null, null, Config),
 1083:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res1), <<"user does not exist">>)).
 1084: 
 1085: admin_create_room_non_existent_domain(Config) ->
 1086:     Config1 = escalus_fresh:create_users(Config, [{alice, 1}]),
 1087:     AliceBin = escalus_users:get_jid(Config1, alice),
 1088:     MucServer = ?config(muc_light_host, Config),
 1089:     Res1 = create_room(?UNKNOWN_DOMAIN, null, AliceBin, null, null, Config1),
 1090:     ?assertMatch({_, _}, binary:match(get_err_msg(Res1), <<"MUC Light server not found">>)),
 1091:     BadUser = make_bare_jid(<<"baduser">>, ?UNKNOWN_DOMAIN),
 1092:     Res2 = create_room(MucServer, null, BadUser, null, null, Config1),
 1093:     ?assertMatch({_, _}, binary:match(get_err_msg(Res2), <<"User's domain does not exist">>)).
 1094: 
 1095: admin_create_room_with_unprepped_domain(Config) ->
 1096:     FreshConfig = escalus_fresh:create_users(Config, [{alice, 1}]),
 1097:     AliceBin = escalus_users:get_jid(FreshConfig, alice),
 1098:     MucServer = ?config(muc_light_host, Config),
 1099:     Name = <<"room with unprepped domain">>,
 1100:     Subject = <<"testing">>,
 1101:     Res = create_room(unprep(MucServer), Name, AliceBin, Subject, null, Config),
 1102:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
 1103:         get_ok_value(?CREATE_ROOM_PATH, Res),
 1104:     ?assertMatch(#jid{lserver = MucServer}, jid:from_binary_noprep(JID)).
 1105: 
 1106: admin_create_room_with_custom_fields(Config) ->
 1107:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_create_room_with_custom_fields_story/2).
 1108: 
 1109: admin_create_room_with_custom_fields_story(Config, Alice) ->
 1110:     AliceBin = escalus_client:short_jid(Alice),
 1111:     AliceBinLower = escalus_utils:jid_to_lower(AliceBin),
 1112:     MucServer = ?config(muc_light_host, Config),
 1113:     Name = <<"first room">>,
 1114:     Subject = <<"testing">>,
 1115:     Options = #{<<"background">> => <<"red">>},
 1116:     Opts = [#{<<"key">> => <<"background">>, <<"value">> => <<"red">>},
 1117:             #{<<"key">> => <<"roomname">>, <<"value">> => Name},
 1118:             #{<<"key">> => <<"subject">>, <<"value">> => Subject}],
 1119:     Res = create_room_with_custom_fields(MucServer, Name, AliceBin, Subject, null, Config, Options),
 1120:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject,
 1121:       <<"participants">> := Participants, <<"options">> := Opts} = get_ok_value(?CREATE_ROOM_PATH, Res),
 1122:     ?assertMatch(#jid{lserver = MucServer}, jid:from_binary(JID)),
 1123:     ?assertEqual([#{<<"jid">> => AliceBinLower, <<"affiliation">> => <<"OWNER">>}], Participants).
 1124: 
 1125: admin_create_identified_room(Config) ->
 1126:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_create_identified_room_story/2).
 1127: 
 1128: admin_create_identified_room_story(Config, Alice) ->
 1129:     AliceBin = escalus_client:short_jid(Alice),
 1130:     MucServer = ?config(muc_light_host, Config),
 1131:     Name = <<"first room">>,
 1132:     Subject = <<"testing">>,
 1133:     SchemaEndpoint = atom_to_binary(?config(schema_endpoint, Config)),
 1134:     Protocol = atom_to_binary(?config(protocol, Config)),
 1135:     Id = <<"my_room_", SchemaEndpoint/binary, "_", Protocol/binary>>,
 1136:     Res = create_room(MucServer, Name, AliceBin, Subject, Id, Config),
 1137:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
 1138:         get_ok_value(?CREATE_ROOM_PATH, Res),
 1139:     ?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary(JID)),
 1140:     % Create a room with an existing ID
 1141:     Res1 = create_room(MucServer, <<"snd room">>, AliceBin, Subject, Id, Config),
 1142:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res1), <<"already exists">>)),
 1143:     % Try with a non-existent user
 1144:     BadUser = make_bare_jid(<<"baduser">>, domain_helper:domain()),
 1145:     Res2 = create_room(?config(muc_light_host, Config), null, BadUser, null, Id, Config),
 1146:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"user does not exist">>)).
 1147: 
 1148: admin_create_identified_room_non_existent_domain(Config) ->
 1149:     Config1 = escalus_fresh:create_users(Config, [{alice, 1}]),
 1150:     AliceBin = escalus_users:get_jid(Config1, alice),
 1151:     Id = <<"bad_room">>,
 1152:     MucServer = ?config(muc_light_host, Config),
 1153:     Res1 = create_room(?UNKNOWN_DOMAIN, null, AliceBin, null, Id, Config1),
 1154:     ?assertMatch({_, _}, binary:match(get_err_msg(Res1), <<"MUC Light server not found">>)),
 1155:     BadUser = make_bare_jid(<<"baduser">>, ?UNKNOWN_DOMAIN),
 1156:     Res2 = create_room(MucServer, null, BadUser, null, Id, Config1),
 1157:     ?assertMatch({_, _}, binary:match(get_err_msg(Res2), <<"User's domain does not exist">>)).
 1158: 
 1159: admin_create_room_with_unprepped_id(Config) ->
 1160:     FreshConfig = escalus_fresh:create_users(Config, [{alice, 1}]),
 1161:     AliceBin = escalus_users:get_jid(FreshConfig, alice),
 1162:     MucServer = ?config(muc_light_host, FreshConfig),
 1163:     Name = <<"first room">>,
 1164:     Subject = <<"testing">>,
 1165:     Id = <<"room_with_unprepped_id">>,
 1166:     Res = create_room(unprep(MucServer), Name, AliceBin, Subject, unprep(Id), FreshConfig),
 1167:     #{<<"jid">> := JID, <<"name">> := Name, <<"subject">> := Subject} =
 1168:         get_ok_value(?CREATE_ROOM_PATH, Res),
 1169:     ?assertMatch(#jid{luser = Id, lserver = MucServer}, jid:from_binary_noprep(JID)).
 1170: 
 1171: admin_change_room_config(Config) ->
 1172:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_change_room_config_story/2).
 1173: 
 1174: admin_change_room_config_story(Config, Alice) ->
 1175:     AliceBin = escalus_client:short_jid(Alice),
 1176:     MUCServer = ?config(muc_light_host, Config),
 1177:     Name = <<"first room">>,
 1178:     Subject = <<"testing">>,
 1179:     % Create a new room
 1180:     {ok, #{jid := RoomJID}} = create_room(MUCServer, Name, Subject, AliceBin),
 1181:     % Try to change the room configuration
 1182:     Name2 = <<"changed room">>,
 1183:     Subject2 = <<"not testing">>,
 1184:     Res = change_room_configuration(jid:to_binary(RoomJID), AliceBin, Name2, Subject2, Config),
 1185:     ?assertMatch(#{<<"name">> := Name2, <<"subject">> := Subject2},
 1186:                  get_ok_value(?CHANGE_CONFIG_PATH, Res)).
 1187: 
 1188: admin_change_room_config_with_custom_fields(Config) ->
 1189:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_change_room_config_with_custom_fields_story/2).
 1190: 
 1191: admin_change_room_config_with_custom_fields_story(Config, Alice) ->
 1192:     AliceBin = escalus_client:short_jid(Alice),
 1193:     MUCServer = ?config(muc_light_host, Config),
 1194:     Name = <<"first room">>,
 1195:     Subject = <<"testing">>,
 1196:     Opts = #{<<"background">> => <<"red">>},
 1197:     % Create a new room
 1198:     Res = create_room_with_custom_fields(MUCServer, Name, AliceBin, Subject, null, Config, Opts),
 1199:     #{<<"jid">> := RoomJID} = get_ok_value(?CREATE_ROOM_PATH, Res),
 1200:     % Try to change the room configuration
 1201:     Name2 = <<"changed room">>,
 1202:     Subject2 = <<"not testing">>,
 1203:     Opts2 = #{<<"music">> => <<"sad">>},
 1204:     Res2 = change_room_configuration_with_custom_fields(jid:to_binary(RoomJID), AliceBin, Name2, Subject2, Config, Opts2),
 1205:     %% It overwrites old config for all fields
 1206:     Opts3 = [% #{<<"key">> => <<"background">>, <<"value">> => <<"red">>},
 1207:              #{<<"key">> => <<"music">>, <<"value">> => <<"sad">>},
 1208:              #{<<"key">> => <<"roomname">>, <<"value">> => Name2},
 1209:              #{<<"key">> => <<"subject">>, <<"value">> => Subject2}],
 1210:     ?assertMatch(#{<<"name">> := Name2, <<"subject">> := Subject2, <<"options">> := Opts3},
 1211:                  get_ok_value(?CHANGE_CONFIG_PATH, Res2)).
 1212: 
 1213: admin_change_room_config_errors(Config) ->
 1214:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}, {kate, 1}],
 1215:                                     fun admin_change_room_config_errors_story/4).
 1216: 
 1217: admin_change_room_config_errors_story(Config, Alice, Bob, Kate) ->
 1218:     AliceBin = escalus_client:short_jid(Alice),
 1219:     BobBin = escalus_client:short_jid(Bob),
 1220:     MUCServer = ?config(muc_light_host, Config),
 1221:     RoomName = <<"first room">>,
 1222:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1223:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
 1224:     % Try to change the config of the non-existent room
 1225:     Res = change_room_configuration(
 1226:              make_bare_jid(<<"unknown">>, MUCServer), AliceBin, RoomName, <<"subject2">>, Config),
 1227:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)),
 1228:     % Try to change the config by the non-existent user
 1229:     Res2 = change_room_configuration(
 1230:              jid:to_binary(RoomJID), <<"wrong-user@wrong-domain">>, RoomName, <<"subject2">>,
 1231:              Config),
 1232:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"User's domain does not exist">>)),
 1233:     % Try to change a config by the user without permission
 1234:     Res3 = change_room_configuration(
 1235:              jid:to_binary(RoomJID), BobBin, RoomName, <<"subject2">>, Config),
 1236:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3),
 1237:                                           <<"does not have permission to change">>)),
 1238:     % Try to change a config by a user not occupying the room
 1239:     KateBin = escalus_client:short_jid(Kate),
 1240:     Res4 = change_room_configuration(
 1241:              jid:to_binary(RoomJID), KateBin, RoomName, <<"subject2">>, Config),
 1242:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"does not occupy">>)).
 1243: 
 1244: admin_change_room_config_non_existent_domain(Config) ->
 1245:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1246:                                     fun admin_change_room_config_non_existent_domain_story/3).
 1247: 
 1248: admin_change_room_config_non_existent_domain_story(Config, Alice, Bob) ->
 1249:     AliceBin = escalus_client:short_jid(Alice),
 1250:     BobBin = escalus_client:short_jid(Bob),
 1251:     MUCServer = ?config(muc_light_host, Config),
 1252:     RoomName = <<"first room">>,
 1253:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
 1254:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1255:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
 1256:     Res = change_room_configuration(
 1257:             make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), AliceBin, RoomName, <<"subject2">>, Config),
 1258:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)).
 1259: 
 1260: admin_invite_user(Config) ->
 1261:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_invite_user_story/3).
 1262: 
 1263: admin_invite_user_story(Config, Alice, Bob) ->
 1264:     AliceBin = escalus_client:short_jid(Alice),
 1265:     BobBin = escalus_client:short_jid(Bob),
 1266:     Domain = escalus_client:server(Alice),
 1267:     MUCServer = ?config(muc_light_host, Config),
 1268:     Name = <<"first room">>,
 1269:     {ok, #{jid := RoomJID}} = create_room(MUCServer, Name, <<"subject2">>, AliceBin),
 1270: 
 1271:     Res = invite_user(jid:to_binary(RoomJID), AliceBin, BobBin, Config),
 1272:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?INVITE_USER_PATH, Res),
 1273:                                           <<"successfully">>)),
 1274:     BobName = escalus_utils:jid_to_lower(escalus_client:username(Bob)),
 1275:     AliceName = escalus_utils:jid_to_lower(escalus_client:username(Alice)),
 1276:     ExpectedAff = lists:sort([{{AliceName, Domain}, owner},
 1277:                               {{BobName, Domain}, member}]),
 1278:     ?assertMatch(ExpectedAff, lists:sort(get_room_aff(RoomJID))).
 1279: 
 1280: admin_invite_user_errors(Config) ->
 1281:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1282:                                     fun admin_invite_user_errors_story/3).
 1283: 
 1284: admin_invite_user_errors_story(Config, Alice, Bob) ->
 1285:     AliceBin = escalus_client:short_jid(Alice),
 1286:     BobBin = escalus_client:short_jid(Bob),
 1287:     MUCServer = ?config(muc_light_host, Config),
 1288:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
 1289:         create_room(MUCServer, <<"first room">>, <<"subject">>, AliceBin),
 1290:     % Try to invite a user to not existing room
 1291:     Res = invite_user(make_bare_jid(?UNKNOWN, MUCServer), AliceBin, BobBin, Config),
 1292:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)),
 1293:     % User without rooms tries to invite a user
 1294:     Res2 = invite_user(jid:to_binary(RoomJID), BobBin, AliceBin, Config),
 1295:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"does not occupy this room">>)),
 1296:     % Try with a non-existent domain
 1297:     Res3 = invite_user(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), AliceBin, BobBin, Config),
 1298:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"not found">>)).
 1299: 
 1300: admin_delete_room(Config) ->
 1301:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_delete_room_story/2).
 1302: 
 1303: admin_delete_room_story(Config, Alice) ->
 1304:     AliceBin = escalus_client:short_jid(Alice),
 1305:     MUCServer = ?config(muc_light_host, Config),
 1306:     Name = <<"first room">>,
 1307:     {ok, #{jid := RoomJID} = RoomInfo} = create_room(MUCServer, Name, <<"subject">>, AliceBin),
 1308:     Res = delete_room(jid:to_binary(RoomJID), Config),
 1309:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?DELETE_ROOM_PATH, Res),
 1310:                                           <<"successfully">>)),
 1311:     ?assertEqual({error, not_exists}, get_room_info(RoomJID), RoomInfo),
 1312:     % Try with a non-existent room
 1313:     Res2 = delete_room(make_bare_jid(?UNKNOWN, MUCServer), Config),
 1314:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)).
 1315: 
 1316: admin_delete_room_non_existent_domain(Config) ->
 1317:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1318:                                     fun admin_delete_room_non_existent_domain_story/2).
 1319: 
 1320: admin_delete_room_non_existent_domain_story(Config, Alice) ->
 1321:     AliceBin = escalus_client:short_jid(Alice),
 1322:     MUCServer = ?config(muc_light_host, Config),
 1323:     Name = <<"first room">>,
 1324:     {ok, #{jid := #jid{luser = RoomID}}} =
 1325:         create_room(MUCServer, Name, <<"subject">>, AliceBin),
 1326:     Res = delete_room(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Config),
 1327:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)).
 1328: 
 1329: admin_kick_user(Config) ->
 1330:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}], fun admin_kick_user_story/3).
 1331: 
 1332: admin_kick_user_story(Config, Alice, Bob) ->
 1333:     AliceBin = escalus_client:short_jid(Alice),
 1334:     BobBin = escalus_client:short_jid(Bob),
 1335:     MUCServer = ?config(muc_light_host, Config),
 1336:     RoomName = <<"first room">>,
 1337:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1338:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
 1339:     ?assertEqual(2, length(get_room_aff(RoomJID))),
 1340:     Res = kick_user(jid:to_binary(RoomJID), BobBin, Config),
 1341:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?KICK_USER_PATH, Res),
 1342:                                           <<"successfully">>)),
 1343:     ?assertEqual(1, length(get_room_aff(RoomJID))).
 1344: 
 1345: admin_send_message_to_room(Config) ->
 1346:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1347:                                     fun admin_send_message_to_room_story/3).
 1348: 
 1349: admin_send_message_to_room_story(Config, Alice, Bob) ->
 1350:     AliceBin = escalus_client:short_jid(Alice),
 1351:     BobBin = escalus_client:short_jid(Bob),
 1352:     MUCServer = ?config(muc_light_host, Config),
 1353:     RoomName = <<"first room">>,
 1354:     MsgBody = <<"Hello there!">>,
 1355:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1356:     {ok, _} = invite_user(RoomJID, AliceBin, BobBin),
 1357:     Res = send_message_to_room(jid:to_binary(RoomJID), AliceBin, MsgBody, Config),
 1358:     ?assertNotEqual(nomatch, binary:match(get_ok_value(?SEND_MESSAGE_PATH, Res),
 1359:                                           <<"successfully">>)),
 1360:     [_, Msg] = escalus:wait_for_stanzas(Bob, 2),
 1361:     escalus:assert(is_message, Msg).
 1362: 
 1363: admin_send_message_to_room_errors(Config) ->
 1364:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1365:                                     fun admin_send_message_to_room_errors_story/3).
 1366: 
 1367: admin_send_message_to_room_errors_story(Config, Alice, Bob) ->
 1368:     AliceBin = escalus_client:short_jid(Alice),
 1369:     BobBin = escalus_client:short_jid(Bob),
 1370:     MUCServer = ?config(muc_light_host, Config),
 1371:     MsgBody = <<"Hello there!">>,
 1372:     {ok, #{jid := #jid{luser = ARoomID} = ARoomJID}} =
 1373:         create_room(MUCServer, <<"alice room">>, <<"subject">>, AliceBin),
 1374:     % Try with a non-existent domain
 1375:     Res2 = send_message_to_room(make_bare_jid(ARoomID, ?UNKNOWN_DOMAIN), AliceBin, MsgBody, Config),
 1376:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)),
 1377:     % Try with a user without rooms
 1378:     Res3 = send_message_to_room(jid:to_binary(ARoomJID), BobBin, MsgBody, Config),
 1379:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res3), <<"does not occupy this room">>)),
 1380:     % Try with a room not occupied by this user
 1381:     {ok, #{jid := _RoomJID2}} = create_room(MUCServer, <<"bob room">>, <<"subject">>, BobBin),
 1382:     Res4 = send_message_to_room(jid:to_binary(ARoomJID), BobBin, MsgBody, Config),
 1383:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"does not occupy this room">>)).
 1384: 
 1385: admin_get_room_messages(Config) ->
 1386:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_get_room_messages_story/2).
 1387: 
 1388: admin_get_room_messages_story(Config, Alice) ->
 1389:     AliceBin = escalus_client:short_jid(Alice),
 1390:     %Domain = escalus_client:server(Alice),
 1391:     MUCServer = ?config(muc_light_host, Config),
 1392:     RoomName = <<"first room">>,
 1393:     RoomName2 = <<"second room">>,
 1394:     {ok, #{jid := #jid{luser = RoomID} = RoomJID}} =
 1395:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1396:     {ok, _} = create_room(MUCServer, RoomName2, <<"subject">>, AliceBin),
 1397:     Message = <<"Hello friends">>,
 1398:     send_message_to_room(RoomJID, jid:from_binary(AliceBin), Message),
 1399:     mam_helper:wait_for_room_archive_size(MUCServer, RoomID, 1),
 1400:     % Get messages so far
 1401:     Limit = 40,
 1402:     Res = get_room_messages(jid:to_binary(RoomJID), Limit, null, Config),
 1403:     #{<<"stanzas">> := [#{<<"stanza">> := StanzaXML}], <<"limit">> := Limit} =
 1404:         get_ok_value(?GET_MESSAGES_PATH, Res),
 1405:     ?assertMatch({ok, #xmlel{name = <<"message">>}}, exml:parse(StanzaXML)),
 1406:     % Get messages before the given date and time
 1407:     Before = <<"2022-02-17T04:54:13+00:00">>,
 1408:     Res2 = get_room_messages(jid:to_binary(RoomJID), null, Before, Config),
 1409:     ?assertMatch(#{<<"stanzas">> := [], <<"limit">> := 50}, get_ok_value(?GET_MESSAGES_PATH, Res2)),
 1410:     % Try to pass too big page size value
 1411:     Res3 = get_room_messages(jid:to_binary(RoomJID), 51, Before, Config),
 1412:     ?assertMatch(#{<<"limit">> := 50}, get_ok_value(?GET_MESSAGES_PATH, Res3)),
 1413:     % Try with a non-existent room
 1414:     Res4 = get_room_messages(make_bare_jid(<<"badroom">>, MUCServer), null, null, Config),
 1415:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res4), <<"Room not found">>)).
 1416: 
 1417: admin_get_room_messages_non_existent_domain(Config) ->
 1418:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1419:                                     fun admin_get_room_messages_non_existent_domain_story/2).
 1420: 
 1421: admin_get_room_messages_non_existent_domain_story(Config, Alice) ->
 1422:     AliceBin = escalus_client:short_jid(Alice),
 1423:     MUCServer = ?config(muc_light_host, Config),
 1424:     RoomName = <<"first room">>,
 1425:     {ok, #{jid := #jid{luser = RoomID}}} =
 1426:     create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1427:     Limit = 40,
 1428:     Res = get_room_messages(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Limit, null, Config),
 1429:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)).
 1430: 
 1431: admin_list_user_rooms(Config) ->
 1432:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_list_user_rooms_story/2).
 1433: 
 1434: admin_list_user_rooms_story(Config, Alice) ->
 1435:     AliceBin = escalus_client:short_jid(Alice),
 1436:     Domain = escalus_client:server(Alice),
 1437:     MUCServer = ?config(muc_light_host, Config),
 1438:     RoomName = <<"first room">>,
 1439:     RoomName2 = <<"second room">>,
 1440:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1441:     {ok, #{jid := RoomJID2}} = create_room(MUCServer, RoomName2, <<"subject">>, AliceBin),
 1442:     Res = list_user_rooms(AliceBin, Config),
 1443:     ?assertEqual(lists:sort([jid:to_binary(RoomJID), jid:to_binary(RoomJID2)]),
 1444:                  lists:sort(get_ok_value(?LIST_USER_ROOMS_PATH, Res))),
 1445:     % Try with a non-existent user
 1446:     Res2 = list_user_rooms(<<"not-exist@", Domain/binary>>, Config),
 1447:     ?assertMatch({_, _}, binary:match(get_err_msg(Res2), <<"does not exist">>)).
 1448: 
 1449: admin_list_user_rooms_non_existent_domain(Config) ->
 1450:     Res = list_user_rooms(<<"not-exist@not-exist">>, Config),
 1451:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"does not exist">>)).
 1452: 
 1453: admin_list_room_users(Config) ->
 1454:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_list_room_users_story/2).
 1455: 
 1456: admin_list_room_users_story(Config, Alice) ->
 1457:     AliceBin = escalus_client:short_jid(Alice),
 1458:     AliceLower = escalus_utils:jid_to_lower(AliceBin),
 1459:     MUCServer = ?config(muc_light_host, Config),
 1460:     RoomName = <<"first room">>,
 1461:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1462:     Res = list_room_users(jid:to_binary(RoomJID), Config),
 1463:     ?assertEqual([#{<<"jid">> => AliceLower, <<"affiliation">> => <<"OWNER">>}],
 1464:                  get_ok_value(?LIST_ROOM_USERS_PATH, Res)),
 1465:     % Try with a non-existent room
 1466:     Res2 = list_room_users(make_bare_jid(?UNKNOWN, MUCServer), Config),
 1467:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)).
 1468: 
 1469: admin_list_room_users_non_existent_domain(Config) ->
 1470:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1471:                                     fun admin_list_room_users_non_existent_domain_story/2).
 1472: 
 1473: admin_list_room_users_non_existent_domain_story(Config, Alice) ->
 1474:     AliceBin = escalus_client:short_jid(Alice),
 1475:     MUCServer = ?config(muc_light_host, Config),
 1476:     RoomName = <<"first room">>,
 1477:     {ok, #{jid := RoomJID}} = create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1478:     Res = list_room_users(make_bare_jid(RoomJID#jid.luser, ?UNKNOWN_DOMAIN), Config),
 1479:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)).
 1480: 
 1481: admin_get_room_config(Config) ->
 1482:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_get_room_config_story/2).
 1483: 
 1484: admin_get_room_config_story(Config, Alice) ->
 1485:     AliceBin = escalus_client:short_jid(Alice),
 1486:     AliceLower = escalus_utils:jid_to_lower(AliceBin),
 1487:     MUCServer = ?config(muc_light_host, Config),
 1488:     RoomName = <<"first room">>,
 1489:     RoomSubject = <<"Room about nothing">>,
 1490:     {ok, #{jid := #jid{luser = _RoomID} = RoomJID}} =
 1491:         create_room(MUCServer, RoomName, RoomSubject, AliceBin),
 1492:     RoomJIDBin = jid:to_binary(RoomJID),
 1493:     Res = get_room_config(RoomJIDBin, Config),
 1494:     ?assertEqual(#{<<"jid">> => RoomJIDBin, <<"subject">> => RoomSubject, <<"name">> => RoomName,
 1495:                     <<"options">> => [#{<<"key">> => <<"background">>, <<"value">> => <<>>},
 1496:                                       #{<<"key">> => <<"music">>, <<"value">> => <<>>},
 1497:                                       #{<<"key">> => <<"roomname">>, <<"value">> => RoomName},
 1498:                                       #{<<"key">> => <<"subject">>, <<"value">> => RoomSubject}],
 1499:                     <<"participants">> => [#{<<"jid">> => AliceLower,
 1500:                                              <<"affiliation">> => <<"OWNER">>}]},
 1501:                  get_ok_value([data, muc_light, getRoomConfig], Res)),
 1502:     % Try with a non-existent room
 1503:     Res2 = get_room_config(make_bare_jid(?UNKNOWN, MUCServer), Config),
 1504:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res2), <<"not found">>)).
 1505: 
 1506: admin_get_room_config_non_existent_domain(Config) ->
 1507:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1508:                                     fun admin_get_room_config_non_existent_domain_story/2).
 1509: 
 1510: admin_get_room_config_non_existent_domain_story(Config, Alice) ->
 1511:     AliceBin = escalus_client:short_jid(Alice),
 1512:     MUCServer = ?config(muc_light_host, Config),
 1513:     RoomName = <<"first room">>,
 1514:     {ok, #{jid := #jid{luser = RoomID}}} =
 1515:         create_room(MUCServer, RoomName, <<"subject">>, AliceBin),
 1516:     Res = get_room_config(make_bare_jid(RoomID, ?UNKNOWN_DOMAIN), Config),
 1517:     ?assertNotEqual(nomatch, binary:match(get_err_msg(Res), <<"not found">>)).
 1518: 
 1519: %% User mod_muc_light not configured test cases
 1520: user_create_room_muc_light_not_configured(Config) ->
 1521:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1522:         fun user_create_room_muc_light_not_configured_story/2).
 1523: 
 1524: user_create_room_muc_light_not_configured_story(Config, Alice) ->
 1525:     MucServer = ?config(muc_light_host, Config),
 1526:     Name = <<"first room">>,
 1527:     Subject = <<"testing">>,
 1528:     Res = user_create_room(Alice, MucServer, Name, Subject, null, Config),
 1529:     ?assertEqual(<<"muc_server_not_found">>, get_err_code(Res)).
 1530: 
 1531: user_change_room_config_muc_light_not_configured(Config) ->
 1532:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1533:         fun user_change_room_config_muc_light_not_configured_story/2).
 1534: 
 1535: user_change_room_config_muc_light_not_configured_story(Config, Alice) ->
 1536:     Name = <<"changed room">>,
 1537:     Subject = <<"not testing">>,
 1538:     Res = user_change_room_configuration(Alice, get_room_name(), Name, Subject, Config),
 1539:     get_not_loaded(Res).
 1540: 
 1541: user_invite_user_muc_light_not_configured(Config) ->
 1542:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1543:         fun user_invite_user_muc_light_not_configured_story/3).
 1544: 
 1545: user_invite_user_muc_light_not_configured_story(Config, Alice, Bob) ->
 1546:     BobBin = escalus_client:short_jid(Bob),
 1547:     Res = user_invite_user(Alice, get_room_name(), BobBin, Config),
 1548:     get_not_loaded(Res).
 1549: 
 1550: user_delete_room_muc_light_not_configured(Config) ->
 1551:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1552:         fun user_delete_room_muc_light_not_configured_story/2).
 1553: 
 1554: user_delete_room_muc_light_not_configured_story(Config, Alice) ->
 1555:     Res = user_delete_room(Alice, get_room_name(), Config),
 1556:     get_not_loaded(Res).
 1557: 
 1558: user_kick_user_muc_light_not_configured(Config) ->
 1559:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1560:         fun user_kick_user_muc_light_not_configured_story/2).
 1561: 
 1562: user_kick_user_muc_light_not_configured_story(Config, Alice) ->
 1563:     Res = user_kick_user(Alice, get_room_name(), null, Config),
 1564:     get_not_loaded(Res).
 1565: 
 1566: user_send_message_to_room_muc_light_not_configured(Config) ->
 1567:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1568:         fun user_send_message_to_room_muc_light_not_configured_story/2).
 1569: 
 1570: user_send_message_to_room_muc_light_not_configured_story(Config, Alice) ->
 1571:     MsgBody = <<"Hello there!">>,
 1572:     Res = user_send_message_to_room(Alice, get_room_name(), MsgBody, Config),
 1573:     get_not_loaded(Res).
 1574: 
 1575: user_get_room_messages_muc_light_or_mam_not_configured(Config) ->
 1576:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1577:         fun user_get_room_messages_muc_light_or_mam_not_configured_story/2).
 1578: 
 1579: user_get_room_messages_muc_light_or_mam_not_configured_story(Config, Alice) ->
 1580:     Before = <<"2022-02-17T04:54:13+00:00">>,
 1581:     Res = user_get_room_messages(Alice, get_room_name(), 51, Before, Config),
 1582:     get_not_loaded(Res).
 1583: 
 1584: user_list_rooms_muc_light_not_configured(Config) ->
 1585:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1586:         fun user_list_rooms_muc_light_not_configured_story/2).
 1587: 
 1588: user_list_rooms_muc_light_not_configured_story(Config, Alice) ->
 1589:     Res = user_list_rooms(Alice, Config),
 1590:     get_not_loaded(Res).
 1591: 
 1592: user_list_room_users_muc_light_not_configured(Config) ->
 1593:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1594:         fun user_list_room_users_muc_light_not_configured_story/2).
 1595: 
 1596: user_list_room_users_muc_light_not_configured_story(Config, Alice) ->
 1597:     Res = user_list_room_users(Alice, get_room_name(), Config),
 1598:     get_not_loaded(Res).
 1599: 
 1600: user_get_room_config_muc_light_not_configured(Config) ->
 1601:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1602:         fun user_get_room_config_muc_light_not_configured_story/2).
 1603: 
 1604: user_get_room_config_muc_light_not_configured_story(Config, Alice) ->
 1605:     Res = user_get_room_config(Alice, get_room_name(), Config),
 1606:     get_not_loaded(Res).
 1607: 
 1608: user_blocking_list_muc_light_not_configured(Config) ->
 1609:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1610:          fun user_blocking_list_muc_light_not_configured_story/3).
 1611: 
 1612: user_blocking_list_muc_light_not_configured_story(Config, Alice, Bob) ->
 1613:     BobBin = escalus_client:full_jid(Bob),
 1614:     Res = user_get_blocking(Alice, Config),
 1615:     get_not_loaded(Res),
 1616:     Res2 = user_set_blocking(Alice, [{<<"USER">>, <<"DENY">>, BobBin}], Config),
 1617:     get_not_loaded(Res2).
 1618: 
 1619: %% Admin mod_muc_light not configured test cases
 1620: 
 1621: admin_create_room_muc_light_not_configured(Config) ->
 1622:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1623:         fun admin_create_room_muc_light_not_configured_story/2).
 1624: 
 1625: admin_create_room_muc_light_not_configured_story(Config, Alice) ->
 1626:     AliceBin = escalus_client:short_jid(Alice),
 1627:     MucServer = ?config(muc_light_host, Config),
 1628:     Name = <<"first room">>,
 1629:     Subject = <<"testing">>,
 1630:     Res = create_room(MucServer, Name, AliceBin, Subject, null, Config),
 1631:     ?assertEqual(<<"muc_server_not_found">>, get_err_code(Res)).
 1632: 
 1633: admin_invite_user_muc_light_not_configured(Config) ->
 1634:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1635:         fun admin_invite_user_muc_light_not_configured_story/3).
 1636: 
 1637: admin_invite_user_muc_light_not_configured_story(Config, Alice, Bob) ->
 1638:     AliceBin = escalus_client:short_jid(Alice),
 1639:     BobBin = escalus_client:short_jid(Bob),
 1640:     Res = invite_user(get_room_name(), AliceBin, BobBin, Config),
 1641:     get_not_loaded(Res).
 1642: 
 1643: admin_change_room_config_muc_light_not_configured(Config) ->
 1644:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1645:         fun admin_change_room_config_muc_light_not_configured_story/2).
 1646: 
 1647: admin_change_room_config_muc_light_not_configured_story(Config, Alice) ->
 1648:     AliceBin = escalus_client:short_jid(Alice),
 1649:     Name = <<"changed room">>,
 1650:     Subject = <<"not testing">>,
 1651:     Res = change_room_configuration(get_room_name(), AliceBin, Name, Subject, Config),
 1652:     get_not_loaded(Res).
 1653: 
 1654: admin_delete_room_muc_light_not_configured(Config) ->
 1655:     Res = delete_room(get_room_name(), Config),
 1656:     get_not_loaded(Res).
 1657: 
 1658: admin_kick_user_muc_light_not_configured(Config) ->
 1659:     escalus:fresh_story_with_config(Config, [{bob, 1}],
 1660:         fun admin_kick_user_muc_light_not_configured_story/2).
 1661: 
 1662: admin_kick_user_muc_light_not_configured_story(Config, Bob) ->
 1663:     BobBin = escalus_client:short_jid(Bob),
 1664:     Res = kick_user(get_room_name(), BobBin, Config),
 1665:     get_not_loaded(Res).
 1666: 
 1667: admin_send_message_to_room_muc_light_not_configured(Config) ->
 1668:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1669:         fun admin_send_message_to_room_muc_light_not_configured_story/2).
 1670: 
 1671: admin_send_message_to_room_muc_light_not_configured_story(Config, Alice) ->
 1672:     AliceBin = escalus_client:short_jid(Alice),
 1673:     MsgBody = <<"Hello there!">>,
 1674:     Res = send_message_to_room(get_room_name(), AliceBin, MsgBody, Config),
 1675:     get_not_loaded(Res).
 1676: 
 1677: admin_get_room_messages_muc_light_or_mam_not_configured(Config) ->
 1678:     Limit = 40,
 1679:     Res = get_room_messages(get_room_name(), Limit, null, Config),
 1680:     get_not_loaded(Res).
 1681: 
 1682: admin_list_user_rooms_muc_light_not_configured(Config) ->
 1683:     escalus:fresh_story_with_config(Config, [{alice, 1}],
 1684:         fun admin_list_user_rooms_muc_light_not_configured_story/2).
 1685: 
 1686: admin_list_user_rooms_muc_light_not_configured_story(Config, Alice) ->
 1687:     AliceBin = escalus_client:short_jid(Alice),
 1688:     Res = list_user_rooms(AliceBin, Config),
 1689:     get_not_loaded(Res).
 1690: 
 1691: admin_list_room_users_muc_light_not_configured(Config) ->
 1692:     Res = list_room_users(get_room_name(), Config),
 1693:     get_not_loaded(Res).
 1694: 
 1695: admin_get_room_config_muc_light_not_configured(Config) ->
 1696:     Res = get_room_config(get_room_name(), Config),
 1697:     get_not_loaded(Res).
 1698: 
 1699: %% Helpers
 1700: 
 1701: get_room_name() ->
 1702:     Domain = domain_helper:domain(),
 1703:     <<"NON_EXISTING@", Domain/binary>>.
 1704: 
 1705: admin_blocking_list_muc_light_not_configured(Config) ->
 1706:     escalus:fresh_story_with_config(Config, [{alice, 1}, {bob, 1}],
 1707:         fun admin_blocking_list_muc_light_not_configured_story/3).
 1708: 
 1709: admin_blocking_list_muc_light_not_configured_story(Config, Alice, Bob) ->
 1710:     AliceBin = escalus_client:full_jid(Alice),
 1711:     BobBin = escalus_client:full_jid(Bob),
 1712:     Res = get_user_blocking(AliceBin, Config),
 1713:     get_not_loaded(Res),
 1714:     Res2 = set_blocking(AliceBin, [{<<"USER">>, <<"DENY">>, BobBin}], Config),
 1715:     get_not_loaded(Res2).
 1716: 
 1717: make_bare_jid(User, Server) ->
 1718:     JID = jid:make_bare(User, Server),
 1719:     jid:to_binary(JID).
 1720: 
 1721: send_message_to_room(RoomJID, SenderJID, Message) ->
 1722:     rpc(mim(), mod_muc_light_api, send_message, [RoomJID, SenderJID, Message]).
 1723: 
 1724: get_room_messages(ID, Domain) ->
 1725:     {ok, Messages} = rpc(mim(), mod_muc_light_api, get_room_messages, [Domain, ID]),
 1726:     Messages.
 1727: 
 1728: create_room(Domain, Name, Subject, CreatorBin) ->
 1729:     CreatorJID = jid:from_binary(CreatorBin),
 1730:     Config = #{<<"roomname">> => Name, <<"subject">> => Subject},
 1731:     rpc(mim(), mod_muc_light_api, create_room, [Domain, CreatorJID, Config]).
 1732: 
 1733: invite_user(RoomJID, SenderBin, RecipientBin) ->
 1734:     SenderJID = jid:from_binary(SenderBin),
 1735:     RecipientJID = jid:from_binary(RecipientBin),
 1736:     rpc(mim(), mod_muc_light_api, invite_to_room, [RoomJID, SenderJID, RecipientJID]).
 1737: 
 1738: get_room_info(error) ->
 1739:     arg_is_not_jid;
 1740: get_room_info(#jid{} = JID) ->
 1741:     HostType = domain_helper:host_type(),
 1742:     RoomUS = jid:to_lus(JID),
 1743:     rpc(mim(), mod_muc_light_db_backend, get_info, [HostType, RoomUS]).
 1744: 
 1745: get_room_aff(JID) ->
 1746:     {ok, _, Aff, _} = get_room_info(JID),
 1747:     Aff.
 1748: 
 1749: prepare_blocking_items_for_query(Items) ->
 1750:     [#{<<"entity">> => Who, <<"entityType">> => What,
 1751:        <<"action">> => Action} || {What, Action, Who} <- Items].
 1752: 
 1753: %% Commands
 1754: 
 1755: create_room(MUCDomain, Name, Owner, Subject, Id, Config) ->
 1756:     Vars = #{<<"mucDomain">> => MUCDomain, <<"name">> => Name, <<"owner">> => Owner,
 1757:              <<"subject">> => Subject, <<"id">> => Id},
 1758:     execute_command(<<"muc_light">>, <<"createRoom">>, Vars, Config).
 1759: 
 1760: create_room_with_custom_fields(MUCDomain, Name, Owner, Subject,
 1761:                                Id, Config, CustomFields) ->
 1762:     Vars = #{<<"mucDomain">> => MUCDomain, <<"name">> => Name, <<"owner">> => Owner,
 1763:              <<"subject">> => Subject, <<"id">> => Id,
 1764:              <<"options">> => format_options(CustomFields)},
 1765:     execute_command(<<"muc_light">>, <<"createRoom">>, Vars, Config).
 1766: 
 1767: change_room_configuration(RoomJID, OwnerJID, Name, Subject, Config) ->
 1768:     Vars = #{<<"room">> => RoomJID, <<"name">> => Name, <<"owner">> => OwnerJID,
 1769:              <<"subject">> => Subject},
 1770:     execute_command(<<"muc_light">>, <<"changeRoomConfiguration">>, Vars, Config).
 1771: 
 1772: change_room_configuration_with_custom_fields(RoomJID, OwnerJID, Name, Subject, Config, Opts) ->
 1773:     Vars = #{<<"room">> => RoomJID, <<"name">> => Name, <<"owner">> => OwnerJID,
 1774:              <<"subject">> => Subject, <<"options">> => format_options(Opts)},
 1775:     execute_command(<<"muc_light">>, <<"changeRoomConfiguration">>, Vars, Config).
 1776: 
 1777: invite_user(RoomJID, Sender, Recipient, Config) ->
 1778:     Vars = #{<<"room">> => RoomJID, <<"sender">> => Sender, <<"recipient">> => Recipient},
 1779:     execute_command(<<"muc_light">>, <<"inviteUser">>, Vars, Config).
 1780: 
 1781: kick_user(RoomJID, User, Config) ->
 1782:     Vars = #{<<"room">> => RoomJID, <<"user">> => User},
 1783:     execute_command(<<"muc_light">>, <<"kickUser">>, Vars, Config).
 1784: 
 1785: send_message_to_room(RoomJID, From, Body, Config) ->
 1786:     Vars = #{<<"room">> => RoomJID, <<"from">> => From, <<"body">> => Body},
 1787:     execute_command(<<"muc_light">>, <<"sendMessageToRoom">>, Vars, Config).
 1788: 
 1789: list_user_rooms(User, Config) ->
 1790:     Vars = #{<<"user">> => User},
 1791:     execute_command(<<"muc_light">>, <<"listUserRooms">>, Vars, Config).
 1792: 
 1793: delete_room(RoomJID, Config) ->
 1794:     Vars = #{<<"room">> => RoomJID},
 1795:     execute_command(<<"muc_light">>, <<"deleteRoom">>, Vars, Config).
 1796: 
 1797: get_room_messages(RoomJID, PageSize, Before, Config) ->
 1798:     Vars = #{<<"room">> => RoomJID, <<"pageSize">> => PageSize, <<"before">> => Before},
 1799:     execute_command(<<"muc_light">>, <<"getRoomMessages">>, Vars, Config).
 1800: 
 1801: list_room_users(RoomJID, Config) ->
 1802:     Vars = #{<<"room">> => RoomJID},
 1803:     execute_command(<<"muc_light">>, <<"listRoomUsers">>, Vars, Config).
 1804: 
 1805: get_room_config(RoomJID, Config) ->
 1806:     Vars = #{<<"room">> => RoomJID},
 1807:     execute_command(<<"muc_light">>, <<"getRoomConfig">>, Vars, Config).
 1808: 
 1809: get_user_blocking(UserJID, Config) ->
 1810:     Vars = #{<<"user">> => UserJID},
 1811:     execute_command(<<"muc_light">>, <<"getBlockingList">>, Vars, Config).
 1812: 
 1813: set_blocking(UserJID, Items, Config) ->
 1814:     Vars = #{<<"user">> => UserJID, <<"items">> => prepare_blocking_items_for_query(Items)},
 1815:     execute_command(<<"muc_light">>, <<"setBlockingList">>, Vars, Config).
 1816: 
 1817: user_create_room(User, MUCDomain, Name, Subject, Id, Config) ->
 1818:     Vars = #{<<"mucDomain">> => MUCDomain, <<"name">> => Name, <<"subject">> => Subject,
 1819:              <<"id">> => Id},
 1820:     execute_user_command(<<"muc_light">>, <<"createRoom">>, User, Vars, Config).
 1821: 
 1822: user_create_room_with_options(User, MUCDomain, Name, Subject, Id, CustomFields, Config) ->
 1823:     Vars = #{<<"mucDomain">> => MUCDomain, <<"name">> => Name, <<"subject">> => Subject,
 1824:              <<"id">> => Id, <<"options">> => format_options(CustomFields)},
 1825:     execute_user_command(<<"muc_light">>, <<"createRoom">>, User, Vars, Config).
 1826: 
 1827: user_change_room_configuration(User, RoomJID, Name, Subject, Config) ->
 1828:     Vars = #{<<"room">> => RoomJID, <<"name">> => Name, <<"subject">> => Subject},
 1829:     execute_user_command(<<"muc_light">>, <<"changeRoomConfiguration">>, User, Vars, Config).
 1830: 
 1831: user_change_room_configuration_with_custom_fields(User, RoomJID, Name, Subject, Config, Options) ->
 1832:     Vars = #{<<"room">> => RoomJID, <<"name">> => Name, <<"subject">> => Subject,
 1833:              <<"options">> => format_options(Options)},
 1834:     execute_user_command(<<"muc_light">>, <<"changeRoomConfiguration">>, User, Vars, Config).
 1835: 
 1836: format_options(Map) ->
 1837:     [#{<<"key">> => K, <<"value">> => V} || {K, V} <- maps:to_list(Map)].
 1838: 
 1839: user_invite_user(User, RoomJID, Recipient, Config) ->
 1840:     Vars = #{<<"room">> => RoomJID, <<"recipient">> => Recipient},
 1841:     execute_user_command(<<"muc_light">>, <<"inviteUser">>, User, Vars, Config).
 1842: 
 1843: user_delete_room(User, RoomJID, Config) ->
 1844:     Vars = #{<<"room">> => RoomJID},
 1845:     execute_user_command(<<"muc_light">>, <<"deleteRoom">>, User, Vars, Config).
 1846: 
 1847: user_kick_user(User, RoomJID, QueriedUser, Config) ->
 1848:     Vars = #{<<"room">> => RoomJID, <<"user">> => QueriedUser},
 1849:     execute_user_command(<<"muc_light">>, <<"kickUser">>, User, Vars, Config).
 1850: 
 1851: user_send_message_to_room(User, RoomJID, Body, Config) ->
 1852:     Vars = #{<<"room">> => RoomJID, <<"body">> => Body},
 1853:     execute_user_command(<<"muc_light">>, <<"sendMessageToRoom">>, User, Vars, Config).
 1854: 
 1855: user_get_room_messages(User, RoomJID, PageSize, Before, Config) ->
 1856:     Vars = #{<<"room">> => RoomJID, <<"pageSize">> => PageSize, <<"before">> => Before},
 1857:     execute_user_command(<<"muc_light">>, <<"getRoomMessages">>, User, Vars, Config).
 1858: 
 1859: user_list_rooms(User, Config) ->
 1860:     execute_user_command(<<"muc_light">>, <<"listRooms">>, User, #{}, Config).
 1861: 
 1862: user_list_room_users(User, RoomJID, Config) ->
 1863:     Vars = #{<<"room">> => RoomJID},
 1864:     execute_user_command(<<"muc_light">>, <<"listRoomUsers">>, User, Vars, Config).
 1865: 
 1866: user_get_room_config(User, RoomJID, Config) ->
 1867:     Vars = #{<<"room">> => RoomJID},
 1868:     execute_user_command(<<"muc_light">>, <<"getRoomConfig">>, User, Vars, Config).
 1869: 
 1870: user_get_blocking(User, Config) ->
 1871:     execute_user_command(<<"muc_light">>, <<"getBlockingList">>, User, #{}, Config).
 1872: 
 1873: user_set_blocking(User, Items, Config) ->
 1874:     Vars = #{<<"items">> => prepare_blocking_items_for_query(Items)},
 1875:     execute_user_command(<<"muc_light">>, <<"setBlockingList">>, User, Vars, Config).
 1876: 
 1877: user_get_muc_room_messages(User, RoomJID, PageSize, Before, Config) ->
 1878:     Vars = #{<<"room">> => jid:to_binary(RoomJID), <<"pageSize">> => PageSize,
 1879:                 <<"before">> => Before},
 1880:     execute_user_command(<<"muc">>, <<"getRoomMessages">>, User, Vars, Config).
 1881: 
 1882: send_message_to_muc_room(User, Room, Body, Resource, Config) ->
 1883:     Vars = #{room => jid:to_binary(Room), body => Body, resource => Resource},
 1884:     execute_user_command(<<"muc">>, <<"sendMessageToRoom">>, User, Vars, Config).
 1885: 
 1886: enter_muc_room(RoomJID, User, Nick) ->
 1887:     JID = jid:to_binary(jid:replace_resource(RoomJID, Nick)),
 1888:     Pres = escalus_stanza:to(escalus_stanza:presence(<<"available">>,
 1889:         [#xmlel{ name = <<"x">>, attrs=[{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}]}]),
 1890:         JID),
 1891:     escalus:send(User, Pres),
 1892:     escalus:wait_for_stanza(User).