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_with_auto_backend/1]). 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() -> [{mod_offline, gen_mod:module_opts()}]. 74: create_config() -> 75: [{mod_offline, mod_config_with_auto_backend(mod_offline)}]. 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: dynamic_modules:ensure_modules(HostType, create_config()), 91: escalus:init_per_suite(Config); 92: init_per_group(admin_offline_not_configured, Config) -> 93: dynamic_modules:ensure_modules(host_type(), [{mod_offline, stopped}]), 94: Config; 95: init_per_group(domain_admin_offline_not_configured, Config) -> 96: dynamic_modules:ensure_modules(host_type(), [{mod_offline, stopped}]), 97: Config. 98: 99: end_per_group(GroupName, _Config) when GroupName =:= admin_http; 100: GroupName =:= admin_cli; 101: GroupName =:= domain_admin -> 102: graphql_helper:clean(); 103: end_per_group(_, _Config) -> 104: ok. 105: 106: init_per_testcase(CaseName, Config) -> 107: escalus:init_per_testcase(CaseName, Config). 108: 109: end_per_testcase(CaseName, Config) -> 110: escalus:end_per_testcase(CaseName, Config), 111: escalus_fresh:clean(). 112: 113: % Admin test cases 114: 115: admin_delete_expired_messages_test(Config) -> 116: Result = delete_expired_messages(domain(), Config), 117: ParsedResult = get_ok_value([data, offline, deleteExpiredMessages], Result), 118: ?assertEqual(<<"Removed 0 messages">>, ParsedResult). 119: 120: admin_delete_old_messages_test(Config) -> 121: Result = delete_old_messages(domain(), 2, Config), 122: ParsedResult = get_ok_value([data, offline, deleteOldMessages], Result), 123: ?assertEqual(<<"Removed 0 messages">>, ParsedResult). 124: 125: admin_delete_expired_messages2_test(Config) -> 126: escalus:fresh_story_with_config(Config, [{mike, 1}, {kate, 1}], 127: fun admin_delete_expired_messages2_test/3). 128: 129: admin_delete_expired_messages2_test(Config, JidMike, JidKate) -> 130: admin_delete_expired_messages2(Config, JidMike, JidKate, domain()), 131: admin_delete_expired_messages2(Config, JidMike, JidKate, unprep(domain())). 132: 133: admin_delete_expired_messages2(Config, JidMike, JidKate, Domain) -> 134: generate_message(JidMike, JidKate, 2, 1), 135: generate_message(JidMike, JidKate, 5, -1), % not expired yet 136: Result = delete_expired_messages(Domain, Config), 137: ParsedResult = get_ok_value([data, offline, deleteExpiredMessages], Result), 138: ?assertEqual(<<"Removed 1 messages">>, ParsedResult). 139: 140: admin_delete_old_messages2_test(Config) -> 141: escalus:fresh_story_with_config(Config, [{mike, 1}, {kate, 1}], 142: fun admin_delete_old_messages2_test/3). 143: 144: admin_delete_old_messages2_test(Config, JidMike, JidKate) -> 145: admin_delete_old_messages2(Config, JidMike, JidKate, domain()), 146: admin_delete_old_messages2(Config, JidMike, JidKate, unprep(domain())). 147: 148: admin_delete_old_messages_invalid_days(Config) -> 149: Result = delete_old_messages(domain(), -1, Config), 150: ParsedResult = get_coercion_err_msg(Result), 151: ?assertMatch({_, _}, binary:match(ParsedResult, <<"Value is not a positive integer">>)), 152: Result2 = delete_old_messages(domain(), 0, Config), 153: ParsedResult2 = get_coercion_err_msg(Result2), 154: ?assertMatch({_, _}, binary:match(ParsedResult2, <<"Value is not a positive integer">>)). 155: 156: admin_delete_old_messages2(Config, JidMike, JidKate, Domain) -> 157: generate_message(JidMike, JidKate, 2, 1), % not old enough 158: generate_message(JidMike, JidKate, 5, -1), 159: generate_message(JidMike, JidKate, 7, 5), 160: Result = delete_old_messages(Domain, 3, Config), 161: ParsedResult = get_ok_value([data, offline, deleteOldMessages], Result), 162: ?assertEqual(<<"Removed 2 messages">>, ParsedResult). 163: 164: admin_delete_expired_messages_no_domain_test(Config) -> 165: Result = delete_expired_messages(<<"AAAA">>, Config), 166: ?assertEqual(<<"domain_not_found">>, get_err_code(Result)). 167: 168: admin_delete_old_messages_no_domain_test(Config) -> 169: Result = delete_old_messages(<<"AAAA">>, 2, Config), 170: ?assertEqual(<<"domain_not_found">>, get_err_code(Result)). 171: 172: admin_delete_expired_messages_offline_not_configured_test(Config) -> 173: get_not_loaded(delete_expired_messages(domain(), Config)), 174: get_not_loaded(delete_expired_messages(unprep(domain()), Config)). 175: 176: admin_delete_old_messages_offline_not_configured_test(Config) -> 177: get_not_loaded(delete_old_messages(domain(), 2, Config)), 178: get_not_loaded(delete_old_messages(unprep(domain()), 2, Config)). 179: 180: %% Domain admin test cases 181: 182: domain_admin_delete_expired_messages_no_permission_test(Config) -> 183: get_unauthorized(delete_expired_messages(<<"AAAA">>, Config)), 184: get_unauthorized(delete_expired_messages(domain_helper:secondary_domain(), Config)). 185: 186: domain_admin_delete_old_messages_no_permission_test(Config) -> 187: get_unauthorized(delete_old_messages(<<"AAAA">>, 2, Config)), 188: get_unauthorized(delete_old_messages(domain_helper:secondary_domain(), 2, Config)). 189: 190: %% Commands 191: 192: delete_expired_messages(Domain, Config) -> 193: Vars = #{<<"domain">> => Domain}, 194: execute_command(<<"offline">>, <<"deleteExpiredMessages">>, Vars, Config). 195: 196: delete_old_messages(Domain, Days, Config) -> 197: Vars = #{<<"domain">> => Domain, <<"days">> => Days}, 198: execute_command(<<"offline">>, <<"deleteOldMessages">>, Vars, Config). 199: 200: %% Helpers 201: 202: generate_message(JidMike, JidKate, TimestampDaysAgo, TimestampExpiringDaysAgo) -> 203: JidRecordMike = jid:from_binary(user_to_bin(JidMike)), 204: JidRecordKate = jid:from_binary(user_to_bin(JidKate)), 205: Domain = domain(), 206: Msg1 = escalus_stanza:chat_to(<<"kate@", Domain/binary>>, "Rolling stones"), 207: OldTimestamp = fallback_timestamp(TimestampDaysAgo, os:system_time(microsecond)), 208: ExpirationTime = fallback_timestamp(TimestampExpiringDaysAgo, os:system_time(microsecond)), 209: OfflineOld = generate_offline_expired_message(JidRecordMike, 210: JidRecordKate, Msg1, 211: OldTimestamp, 212: ExpirationTime), 213: {LUser, LServer} = jid:to_lus(JidRecordKate), 214: rpc_call(mod_offline_backend, write_messages, [host_type(), LUser, LServer, [OfflineOld]]). 215: 216: generate_offline_expired_message(From, To, Msg, TimeStamp, ExpirationTime) -> 217: {LUser, LServer} = jid:to_lus(To), 218: #offline_msg{us = {LUser, LServer}, timestamp = TimeStamp, 219: expire = ExpirationTime, from = From, to = To, packet = Msg}. 220: 221: fallback_timestamp(HowManyDays, TS_MicroSeconds) -> 222: HowManySeconds = HowManyDays * 86400, 223: HowManyMicroSeconds = erlang:convert_time_unit(HowManySeconds, second, microsecond), 224: TS_MicroSeconds - HowManyMicroSeconds.