1: -module(graphql_offline_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]). 7: -import(domain_helper, [host_type/0, domain/0]). 8: -import(graphql_helper, [execute_command/4, get_ok_value/2, get_err_code/1, user_to_bin/1, 9: get_unauthorized/1, get_not_loaded/1, get_coercion_err_msg/1]). 10: -import(config_parser_helper, [mod_config/2]). 11: -import(mongooseimctl_helper, [mongooseimctl/3, rpc_call/3]). 12: 13: -include_lib("eunit/include/eunit.hrl"). 14: 15: -record(offline_msg, {us, timestamp, expire, from, to, packet, permanent_fields = []}). 16: 17: suite() -> 18: require_rpc_nodes([mim]) ++ escalus:suite(). 19: 20: all() -> 21: [{group, admin_http}, 22: {group, admin_cli}, 23: {group, domain_admin}]. 24: 25: groups() -> 26: [{admin_http, [], admin_groups()}, 27: {admin_cli, [], admin_groups()}, 28: {domain_admin, [], domain_admin_groups()}, 29: {admin_offline, [], admin_offline_tests()}, 30: {admin_offline_not_configured, [], admin_offline_not_configured_tests()}, 31: {domain_admin_offline, [], domain_admin_offline_tests()}, 32: {domain_admin_offline_not_configured, [], domain_admin_offline_not_configured_tests()}]. 33: 34: admin_groups() -> 35: [{group, admin_offline}, 36: {group, admin_offline_not_configured}]. 37: 38: domain_admin_groups() -> 39: [{group, domain_admin_offline}, 40: {group, domain_admin_offline_not_configured}]. 41: 42: admin_offline_tests() -> 43: [admin_delete_expired_messages_test, 44: admin_delete_old_messages_test, 45: admin_delete_expired_messages2_test, 46: admin_delete_old_messages2_test, 47: admin_delete_old_messages_invalid_days, 48: admin_delete_expired_messages_no_domain_test, 49: admin_delete_old_messages_no_domain_test]. 50: 51: admin_offline_not_configured_tests() -> 52: [admin_delete_expired_messages_offline_not_configured_test, 53: admin_delete_old_messages_offline_not_configured_test]. 54: 55: domain_admin_offline_tests() -> 56: [admin_delete_expired_messages_test, 57: admin_delete_old_messages_test, 58: admin_delete_expired_messages2_test, 59: admin_delete_old_messages2_test, 60: admin_delete_old_messages_invalid_days, 61: domain_admin_delete_expired_messages_no_permission_test, 62: domain_admin_delete_old_messages_no_permission_test]. 63: 64: domain_admin_offline_not_configured_tests() -> 65: [admin_delete_expired_messages_offline_not_configured_test, 66: admin_delete_old_messages_offline_not_configured_test]. 67: 68: init_per_suite(Config) -> 69: Config1 = dynamic_modules:save_modules(host_type(), Config), 70: Config2 = ejabberd_node_utils:init(mim(), Config1), 71: escalus:init_per_suite(Config2). 72: 73: -spec create_config(atom()) -> [{mod_offline, gen_mod:module_opts()}]. 74: create_config(Backend) -> 75: [{mod_offline, mod_config(mod_offline, #{backend => Backend})}]. 76: 77: end_per_suite(Config) -> 78: dynamic_modules:restore_modules(Config), 79: escalus:end_per_suite(Config). 80: 81: init_per_group(admin_http, Config) -> 82: graphql_helper:init_admin_handler(Config); 83: init_per_group(admin_cli, Config) -> 84: graphql_helper:init_admin_cli(Config); 85: init_per_group(domain_admin, Config) -> 86: graphql_helper:init_domain_admin_handler(Config); 87: init_per_group(GroupName, Config) when GroupName =:= admin_offline; 88: GroupName =:= domain_admin_offline -> 89: HostType = host_type(), 90: Backend = mongoose_helper:get_backend_mnesia_rdbms(HostType), 91: ModConfig = create_config(Backend), 92: dynamic_modules:ensure_modules(HostType, ModConfig), 93: [{backend, Backend} | escalus:init_per_suite(Config)]; 94: init_per_group(admin_offline_not_configured, Config) -> 95: dynamic_modules:ensure_modules(host_type(), [{mod_offline, stopped}]), 96: Config; 97: init_per_group(domain_admin_offline_not_configured, Config) -> 98: dynamic_modules:ensure_modules(host_type(), [{mod_offline, stopped}]), 99: Config. 100: 101: end_per_group(GroupName, _Config) when GroupName =:= admin_http; 102: GroupName =:= admin_cli; 103: GroupName =:= domain_admin -> 104: graphql_helper:clean(); 105: end_per_group(_, _Config) -> 106: ok. 107: 108: init_per_testcase(CaseName, Config) -> 109: escalus:init_per_testcase(CaseName, Config). 110: 111: end_per_testcase(CaseName, Config) -> 112: escalus:end_per_testcase(CaseName, Config), 113: escalus_fresh:clean(). 114: 115: % Admin test cases 116: 117: admin_delete_expired_messages_test(Config) -> 118: Result = delete_expired_messages(domain(), Config), 119: ParsedResult = get_ok_value([data, offline, deleteExpiredMessages], Result), 120: ?assertEqual(<<"Removed 0 messages">>, ParsedResult). 121: 122: admin_delete_old_messages_test(Config) -> 123: Result = delete_old_messages(domain(), 2, Config), 124: ParsedResult = get_ok_value([data, offline, deleteOldMessages], Result), 125: ?assertEqual(<<"Removed 0 messages">>, ParsedResult). 126: 127: admin_delete_expired_messages2_test(Config) -> 128: escalus:fresh_story_with_config(Config, [{mike, 1}, {kate, 1}], 129: fun admin_delete_expired_messages2_test/3). 130: 131: admin_delete_expired_messages2_test(Config, JidMike, JidKate) -> 132: admin_delete_expired_messages2(Config, JidMike, JidKate, domain()), 133: admin_delete_expired_messages2(Config, JidMike, JidKate, unprep(domain())). 134: 135: admin_delete_expired_messages2(Config, JidMike, JidKate, Domain) -> 136: generate_message(JidMike, JidKate, 2, 1), 137: generate_message(JidMike, JidKate, 5, -1), % not expired yet 138: Result = delete_expired_messages(Domain, Config), 139: ParsedResult = get_ok_value([data, offline, deleteExpiredMessages], Result), 140: ?assertEqual(<<"Removed 1 messages">>, ParsedResult). 141: 142: admin_delete_old_messages2_test(Config) -> 143: escalus:fresh_story_with_config(Config, [{mike, 1}, {kate, 1}], 144: fun admin_delete_old_messages2_test/3). 145: 146: admin_delete_old_messages2_test(Config, JidMike, JidKate) -> 147: admin_delete_old_messages2(Config, JidMike, JidKate, domain()), 148: admin_delete_old_messages2(Config, JidMike, JidKate, unprep(domain())). 149: 150: admin_delete_old_messages_invalid_days(Config) -> 151: Result = delete_old_messages(domain(), -1, Config), 152: ParsedResult = get_coercion_err_msg(Result), 153: ?assertMatch({_, _}, binary:match(ParsedResult, <<"Value is not a positive integer">>)), 154: Result2 = delete_old_messages(domain(), 0, Config), 155: ParsedResult2 = get_coercion_err_msg(Result2), 156: ?assertMatch({_, _}, binary:match(ParsedResult2, <<"Value is not a positive integer">>)). 157: 158: admin_delete_old_messages2(Config, JidMike, JidKate, Domain) -> 159: generate_message(JidMike, JidKate, 2, 1), % not old enough 160: generate_message(JidMike, JidKate, 5, -1), 161: generate_message(JidMike, JidKate, 7, 5), 162: Result = delete_old_messages(Domain, 3, Config), 163: ParsedResult = get_ok_value([data, offline, deleteOldMessages], Result), 164: ?assertEqual(<<"Removed 2 messages">>, ParsedResult). 165: 166: admin_delete_expired_messages_no_domain_test(Config) -> 167: Result = delete_expired_messages(<<"AAAA">>, Config), 168: ?assertEqual(<<"domain_not_found">>, get_err_code(Result)). 169: 170: admin_delete_old_messages_no_domain_test(Config) -> 171: Result = delete_old_messages(<<"AAAA">>, 2, Config), 172: ?assertEqual(<<"domain_not_found">>, get_err_code(Result)). 173: 174: admin_delete_expired_messages_offline_not_configured_test(Config) -> 175: get_not_loaded(delete_expired_messages(domain(), Config)), 176: get_not_loaded(delete_expired_messages(unprep(domain()), Config)). 177: 178: admin_delete_old_messages_offline_not_configured_test(Config) -> 179: get_not_loaded(delete_old_messages(domain(), 2, Config)), 180: get_not_loaded(delete_old_messages(unprep(domain()), 2, Config)). 181: 182: %% Domain admin test cases 183: 184: domain_admin_delete_expired_messages_no_permission_test(Config) -> 185: get_unauthorized(delete_expired_messages(<<"AAAA">>, Config)), 186: get_unauthorized(delete_expired_messages(domain_helper:secondary_domain(), Config)). 187: 188: domain_admin_delete_old_messages_no_permission_test(Config) -> 189: get_unauthorized(delete_old_messages(<<"AAAA">>, 2, Config)), 190: get_unauthorized(delete_old_messages(domain_helper:secondary_domain(), 2, Config)). 191: 192: %% Commands 193: 194: delete_expired_messages(Domain, Config) -> 195: Vars = #{<<"domain">> => Domain}, 196: execute_command(<<"offline">>, <<"deleteExpiredMessages">>, Vars, Config). 197: 198: delete_old_messages(Domain, Days, Config) -> 199: Vars = #{<<"domain">> => Domain, <<"days">> => Days}, 200: execute_command(<<"offline">>, <<"deleteOldMessages">>, Vars, Config). 201: 202: %% Helpers 203: 204: generate_message(JidMike, JidKate, TimestampDaysAgo, TimestampExpiringDaysAgo) -> 205: JidRecordMike = jid:from_binary(user_to_bin(JidMike)), 206: JidRecordKate = jid:from_binary(user_to_bin(JidKate)), 207: Domain = domain(), 208: Msg1 = escalus_stanza:chat_to(<<"kate@", Domain/binary>>, "Rolling stones"), 209: OldTimestamp = fallback_timestamp(TimestampDaysAgo, os:system_time(microsecond)), 210: ExpirationTime = fallback_timestamp(TimestampExpiringDaysAgo, os:system_time(microsecond)), 211: OfflineOld = generate_offline_expired_message(JidRecordMike, 212: JidRecordKate, Msg1, 213: OldTimestamp, 214: ExpirationTime), 215: {LUser, LServer} = jid:to_lus(JidRecordKate), 216: rpc_call(mod_offline_backend, write_messages, [host_type(), LUser, LServer, [OfflineOld]]). 217: 218: generate_offline_expired_message(From, To, Msg, TimeStamp, ExpirationTime) -> 219: {LUser, LServer} = jid:to_lus(To), 220: #offline_msg{us = {LUser, LServer}, timestamp = TimeStamp, 221: expire = ExpirationTime, from = From, to = To, packet = Msg}. 222: 223: fallback_timestamp(HowManyDays, TS_MicroSeconds) -> 224: HowManySeconds = HowManyDays * 86400, 225: HowManyMicroSeconds = erlang:convert_time_unit(HowManySeconds, second, microsecond), 226: TS_MicroSeconds - HowManyMicroSeconds.