1: -module(graphql_domain_SUITE). 2: 3: -include_lib("eunit/include/eunit.hrl"). 4: 5: -compile([export_all, nowarn_export_all]). 6: 7: -import(distributed_helper, [mim/0, require_rpc_nodes/1, rpc/4]). 8: -import(graphql_helper, [execute_command/4, get_ok_value/2, get_err_msg/1, skip_null_fields/1, 9: execute_domain_admin_command/4, get_unauthorized/1, get_coercion_err_msg/1]). 10: 11: -define(HOST_TYPE, <<"dummy auth">>). 12: -define(SECOND_HOST_TYPE, <<"test type">>). 13: -define(EXAMPLE_DOMAIN, <<"example.com">>). 14: -define(SECOND_EXAMPLE_DOMAIN, <<"second.example.com">>). 15: -define(DOMAIN_ADMIN_EXAMPLE_DOMAIN, <<"domain-admin.example.com">>). 16: 17: suite() -> 18: require_rpc_nodes([mim]) ++ escalus:suite(). 19: 20: all() -> 21: [{group, domain_http}, 22: {group, domain_cli}, 23: {group, domain_admin_tests}]. 24: 25: groups() -> 26: [{domain_http, [sequence], domain_tests()}, 27: {domain_cli, [sequence], domain_tests()}, 28: {domain_admin_tests, [sequence], domain_admin_tests()}]. 29: 30: domain_tests() -> 31: [create_domain, 32: unknown_host_type_error_formatting, 33: add_static_domain_error_formatting, 34: remove_static_domain_error_formatting, 35: enable_static_domain_error_formatting, 36: disable_static_domain_error_formatting, 37: domain_duplicate_error_formatting, 38: domain_not_found_error_formatting_after_mutation_disable_domain, 39: domain_not_found_error_formatting_after_mutation_enable_domain, 40: domain_not_found_error_formatting_after_query, 41: wrong_host_type_error_formatting, 42: invalid_domain_name_error, 43: disable_domain, 44: enable_domain, 45: get_domains_by_host_type, 46: get_domain_details, 47: delete_domain, 48: request_delete_domain, 49: get_domains_after_deletion, 50: set_domain_password, 51: set_nonexistent_domain_password, 52: delete_domain_password, 53: delete_nonexistent_domain_password 54: ]. 55: 56: domain_admin_tests() -> 57: [domain_admin_get_domain_details, 58: domain_admin_set_domain_password, 59: domain_admin_create_domain_no_permission, 60: domain_admin_disable_domain_no_permission, 61: domain_admin_enable_domain_no_permission, 62: domain_admin_get_domains_by_host_type_no_permission, 63: domain_admin_get_domain_details_no_permission, 64: domain_admin_delete_domain_no_permission, 65: domain_admin_set_domain_password_no_permission, 66: domain_admin_delete_domain_password_no_permission 67: ]. 68: 69: init_per_suite(Config) -> 70: case mongoose_helper:is_rdbms_enabled(?HOST_TYPE) of 71: true -> 72: Config1 = ejabberd_node_utils:init(mim(), Config), 73: escalus:init_per_suite(Config1); 74: false -> 75: {skip, require_rdbms} 76: end. 77: 78: end_per_suite(Config) -> 79: escalus_fresh:clean(), 80: escalus:end_per_suite(Config). 81: 82: init_per_group(domain_http, Config) -> 83: graphql_helper:init_admin_handler(Config); 84: init_per_group(domain_cli, Config) -> 85: graphql_helper:init_admin_cli(Config); 86: init_per_group(domain_admin_tests, Config) -> 87: domain_helper:insert_persistent_domain(mim(), ?DOMAIN_ADMIN_EXAMPLE_DOMAIN, ?HOST_TYPE), 88: domain_helper:insert_domain(mim(), ?DOMAIN_ADMIN_EXAMPLE_DOMAIN, ?HOST_TYPE), 89: graphql_helper:init_domain_admin_handler(Config, ?DOMAIN_ADMIN_EXAMPLE_DOMAIN). 90: 91: end_per_group(domain_admin_tests, _Config) -> 92: domain_helper:delete_domain(mim(), ?DOMAIN_ADMIN_EXAMPLE_DOMAIN), 93: domain_helper:delete_persistent_domain(mim(), ?DOMAIN_ADMIN_EXAMPLE_DOMAIN, ?HOST_TYPE); 94: end_per_group(_GroupName, _Config) -> 95: graphql_helper:clean(). 96: 97: init_per_testcase(CaseName, Config) -> 98: escalus:init_per_testcase(CaseName, Config). 99: 100: end_per_testcase(CaseName, Config) -> 101: escalus:end_per_testcase(CaseName, Config). 102: 103: create_domain(Config) -> 104: create_domain(?EXAMPLE_DOMAIN, Config), 105: create_domain(?SECOND_EXAMPLE_DOMAIN, Config). 106: 107: create_domain(DomainName, Config) -> 108: Result = add_domain(DomainName, ?HOST_TYPE, Config), 109: ParsedResult = get_ok_value([data, domain, addDomain], Result), 110: ?assertEqual(#{<<"domain">> => DomainName, 111: <<"hostType">> => ?HOST_TYPE, 112: <<"status">> => null}, ParsedResult). 113: 114: unknown_host_type_error_formatting(Config) -> 115: DomainName = ?EXAMPLE_DOMAIN, 116: HostType = <<"NonExistingHostType">>, 117: Result = add_domain(DomainName, HostType, Config), 118: ?assertEqual(<<"Unknown host type">>, get_err_msg(Result)), 119: Result2 = get_domains_by_host_type(HostType, Config), 120: ?assertEqual(<<"Unknown host type">>, get_err_msg(Result2)). 121: 122: add_static_domain_error_formatting(Config) -> 123: DomainName = <<"localhost">>, 124: Result = add_domain(DomainName, ?HOST_TYPE, Config), 125: ?assertEqual(<<"Domain is static">>, get_err_msg(Result)). 126: 127: remove_static_domain_error_formatting(Config) -> 128: DomainName = <<"localhost">>, 129: Result = remove_domain(DomainName, ?HOST_TYPE, Config), 130: ?assertEqual(<<"Domain is static">>, get_err_msg(Result)). 131: 132: enable_static_domain_error_formatting(Config) -> 133: DomainName = <<"localhost">>, 134: Result = enable_domain(DomainName, Config), 135: ?assertEqual(<<"Domain is static">>, get_err_msg(Result)). 136: 137: disable_static_domain_error_formatting(Config) -> 138: DomainName = <<"localhost">>, 139: Result = disable_domain(DomainName, Config), 140: ?assertEqual(<<"Domain is static">>, get_err_msg(Result)). 141: 142: domain_duplicate_error_formatting(Config) -> 143: DomainName = ?EXAMPLE_DOMAIN, 144: Result = add_domain(DomainName, ?SECOND_HOST_TYPE, Config), 145: ?assertMatch(<<"Domain already exists">>, get_err_msg(Result)). 146: 147: domain_not_found_error_formatting_after_mutation_enable_domain(Config) -> 148: DomainName = <<"NonExistingDomain">>, 149: Result = enable_domain(DomainName, Config), 150: domain_not_found_error_formatting(Result). 151: 152: domain_not_found_error_formatting_after_mutation_disable_domain(Config) -> 153: DomainName = <<"NonExistingDomain">>, 154: Result = disable_domain(DomainName, Config), 155: domain_not_found_error_formatting(Result). 156: 157: domain_not_found_error_formatting_after_query(Config) -> 158: DomainName = <<"NonExistingDomain">>, 159: Result = get_domain_details(DomainName, Config), 160: domain_not_found_error_formatting(Result). 161: 162: wrong_host_type_error_formatting(Config) -> 163: Result = remove_domain(?EXAMPLE_DOMAIN, ?SECOND_HOST_TYPE, Config), 164: ?assertEqual(<<"Wrong host type was provided">>, get_err_msg(Result)). 165: 166: invalid_domain_name_error(Config) -> 167: %% One operation tested, because they all use the DomainName type 168: Result1 = add_domain(<<>>, ?HOST_TYPE, Config), 169: get_coercion_err_msg(Result1), 170: TooLong = binary:copy(<<$a>>, 1024), 171: Result2 = add_domain(TooLong, ?HOST_TYPE, Config), 172: get_coercion_err_msg(Result2). 173: 174: disable_domain(Config) -> 175: Result = disable_domain(?EXAMPLE_DOMAIN, Config), 176: ParsedResult = get_ok_value([data, domain, disableDomain], Result), 177: ?assertMatch(#{<<"domain">> := ?EXAMPLE_DOMAIN, <<"status">> := <<"DISABLED">>}, ParsedResult), 178: {ok, Domain} = rpc(mim(), mongoose_domain_sql, select_domain, [?EXAMPLE_DOMAIN]), 179: ?assertEqual(#{host_type => ?HOST_TYPE, status => disabled}, Domain). 180: 181: enable_domain(Config) -> 182: Result = enable_domain(?EXAMPLE_DOMAIN, Config), 183: ParsedResult = get_ok_value([data, domain, enableDomain], Result), 184: ?assertMatch(#{<<"domain">> := ?EXAMPLE_DOMAIN, <<"status">> := <<"ENABLED">>}, ParsedResult). 185: 186: get_domains_by_host_type(Config) -> 187: Result = get_domains_by_host_type(?HOST_TYPE, Config), 188: ParsedResult = get_ok_value([data, domain, domainsByHostType], Result), 189: ?assertEqual(lists:sort([?EXAMPLE_DOMAIN, ?SECOND_EXAMPLE_DOMAIN]), 190: lists:sort(ParsedResult)). 191: 192: get_domain_details(Config) -> 193: Result = get_domain_details(?EXAMPLE_DOMAIN, Config), 194: ParsedResult = get_ok_value([data, domain, domainDetails], Result), 195: ?assertEqual(#{<<"domain">> => ?EXAMPLE_DOMAIN, 196: <<"hostType">> => ?HOST_TYPE, 197: <<"status">> => <<"ENABLED">>}, ParsedResult). 198: 199: delete_domain(Config) -> 200: Result1 = remove_domain(?EXAMPLE_DOMAIN, ?HOST_TYPE, Config), 201: ParsedResult1 = get_ok_value([data, domain, removeDomain], Result1), 202: ?assertEqual(#{<<"domain">> => ?EXAMPLE_DOMAIN, 203: <<"hostType">> => ?HOST_TYPE, 204: <<"status">> => <<"DELETED">>}, 205: ParsedResult1), 206: Result2 = remove_domain(?EXAMPLE_DOMAIN, ?HOST_TYPE, Config), 207: domain_not_found_error_formatting(Result2). 208: 209: request_delete_domain(Config) -> 210: Result1 = request_remove_domain(?SECOND_EXAMPLE_DOMAIN, ?HOST_TYPE, Config), 211: ParsedResult1 = get_ok_value([data, domain, requestRemoveDomain], Result1), 212: ?assertEqual(#{<<"domain">> => ?SECOND_EXAMPLE_DOMAIN, 213: <<"hostType">> => ?HOST_TYPE, 214: <<"status">> => <<"DELETING">>}, 215: ParsedResult1), 216: F = fun() -> 217: Result = get_domain_details(?EXAMPLE_DOMAIN, Config), 218: domain_not_found_error_formatting(Result) 219: end, 220: mongoose_helper:wait_until(F, ok, #{time_left => timer:seconds(5)}), 221: Result2 = request_remove_domain(?EXAMPLE_DOMAIN, ?HOST_TYPE, Config), 222: domain_not_found_error_formatting(Result2). 223: 224: get_domains_after_deletion(Config) -> 225: Result = get_domains_by_host_type(?HOST_TYPE, Config), 226: ParsedResult = get_ok_value([data, domain, domainsByHostType], Result), 227: ?assertEqual([], ParsedResult). 228: 229: set_domain_password(Config) -> 230: Result = set_domain_password(domain_helper:domain(), <<"secret">>, Config), 231: ParsedResult = get_ok_value([data, domain, setDomainPassword], Result), 232: ?assertNotEqual(nomatch, binary:match(ParsedResult, <<"successfully">>)). 233: 234: set_nonexistent_domain_password(Config) -> 235: Domain = <<"unknown-domain.com">>, 236: Result = set_domain_password(Domain, <<"secret">>, Config), 237: domain_not_found_error_formatting(Result). 238: 239: delete_domain_password(Config) -> 240: Result = delete_domain_password(domain_helper:domain(), Config), 241: ParsedResult = get_ok_value([data, domain, deleteDomainPassword], Result), 242: ?assertNotEqual(nomatch, binary:match(ParsedResult, <<"successfully">>)), 243: Result2 = delete_domain_password(domain_helper:domain(), Config), 244: domain_password_not_found_error_formatting(Result2). 245: 246: delete_nonexistent_domain_password(Config) -> 247: Domain = <<"unknown-domain.com">>, 248: Result = delete_domain_password(Domain, Config), 249: domain_password_not_found_error_formatting(Result). 250: 251: domain_admin_get_domain_details(Config) -> 252: Result = get_domain_details(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, Config), 253: ParsedResult = get_ok_value([data, domain, domainDetails], Result), 254: ?assertEqual(#{<<"domain">> => ?DOMAIN_ADMIN_EXAMPLE_DOMAIN, 255: <<"hostType">> => ?HOST_TYPE, 256: <<"status">> => <<"ENABLED">>}, ParsedResult). 257: 258: domain_admin_set_domain_password(Config) -> 259: Result = set_domain_password(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, <<"secret">>, Config), 260: ParsedResult = get_ok_value([data, domain, setDomainPassword], Result), 261: ?assertNotEqual(nomatch, binary:match(ParsedResult, <<"successfully">>)). 262: 263: domain_admin_create_domain_no_permission(Config) -> 264: get_unauthorized(add_domain(?EXAMPLE_DOMAIN, ?HOST_TYPE, Config)), 265: get_unauthorized(add_domain(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, ?HOST_TYPE, Config)). 266: 267: domain_admin_disable_domain_no_permission(Config) -> 268: get_unauthorized(disable_domain(?EXAMPLE_DOMAIN, Config)), 269: get_unauthorized(disable_domain(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, Config)). 270: 271: domain_admin_enable_domain_no_permission(Config) -> 272: get_unauthorized(enable_domain(?EXAMPLE_DOMAIN, Config)), 273: get_unauthorized(enable_domain(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, Config)). 274: 275: domain_admin_get_domains_by_host_type_no_permission(Config) -> 276: get_unauthorized(get_domains_by_host_type(?HOST_TYPE, Config)), 277: get_unauthorized(get_domains_by_host_type(domain_helper:host_type(), Config)). 278: 279: domain_admin_get_domain_details_no_permission(Config) -> 280: get_unauthorized(get_domain_details(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, Config)), 281: get_unauthorized(get_domain_details(?EXAMPLE_DOMAIN, Config)). 282: 283: domain_admin_set_domain_password_no_permission(Config) -> 284: get_unauthorized(set_domain_password(?EXAMPLE_DOMAIN, <<"secret">>, Config)), 285: get_unauthorized(set_domain_password(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, <<"secret">>, Config)). 286: 287: domain_admin_delete_domain_no_permission(Config) -> 288: get_unauthorized(remove_domain(?EXAMPLE_DOMAIN, ?HOST_TYPE, Config)), 289: get_unauthorized(remove_domain(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, ?HOST_TYPE, Config)). 290: 291: domain_admin_delete_domain_password_no_permission(Config) -> 292: get_unauthorized(delete_domain_password(?EXAMPLE_DOMAIN, Config)), 293: get_unauthorized(delete_domain_password(?DOMAIN_ADMIN_EXAMPLE_DOMAIN, Config)). 294: 295: %% Commands 296: 297: add_domain(Domain, HostType, Config) -> 298: Vars = #{domain => Domain, hostType => HostType}, 299: execute_command(<<"domain">>, <<"addDomain">>, Vars, Config). 300: 301: enable_domain(Domain, Config) -> 302: Vars = #{domain => Domain}, 303: execute_command(<<"domain">>, <<"enableDomain">>, Vars, Config). 304: 305: disable_domain(Domain, Config) -> 306: Vars = #{domain => Domain}, 307: execute_command(<<"domain">>, <<"disableDomain">>, Vars, Config). 308: 309: get_domain_details(Domain, Config) -> 310: Vars = #{domain => Domain}, 311: execute_command(<<"domain">>, <<"domainDetails">>, Vars, Config). 312: 313: remove_domain(Domain, HostType, Config) -> 314: Vars = #{domain => Domain, hostType => HostType}, 315: execute_command(<<"domain">>, <<"removeDomain">>, Vars, Config). 316: 317: request_remove_domain(Domain, HostType, Config) -> 318: Vars = #{domain => Domain, hostType => HostType}, 319: execute_command(<<"domain">>, <<"requestRemoveDomain">>, Vars, Config). 320: 321: get_domains_by_host_type(HostType, Config) -> 322: Vars = #{hostType => HostType}, 323: execute_command(<<"domain">>, <<"domainsByHostType">>, Vars, Config). 324: 325: set_domain_password(Domain, Password, Config) -> 326: Vars = #{domain => Domain, password => Password}, 327: execute_command(<<"domain">>, <<"setDomainPassword">>, Vars, Config). 328: 329: delete_domain_password(Domain, Config) -> 330: Vars = #{domain => Domain}, 331: execute_command(<<"domain">>, <<"deleteDomainPassword">>, Vars, Config). 332: 333: %% Helpers 334: 335: domain_not_found_error_formatting(Result) -> 336: ?assertMatch(<<"Given domain does not exist", _/binary>>, get_err_msg(Result)). 337: 338: domain_password_not_found_error_formatting(Result) -> 339: ?assertEqual(<<"Domain password does not exist">>, get_err_msg(Result)).