1: %% @doc Tests for the SSE handling of GraphQL subscriptions 2: -module(graphql_sse_SUITE). 3: 4: -compile([export_all, nowarn_export_all]). 5: 6: -import(distributed_helper, [mim/0, require_rpc_nodes/1, rpc/4]). 7: -import(graphql_helper, [get_bad_request/1, get_unauthorized/1, get_method_not_allowed/1, 8: build_request/4, make_creds/1, execute_auth/2, 9: execute_sse/3, execute_user_sse/3, execute_auth_sse/2]). 10: 11: %% common_test callbacks 12: 13: suite() -> 14: require_rpc_nodes([mim]) ++ escalus:suite(). 15: 16: all() -> 17: [{group, admin}, 18: {group, user}]. 19: 20: groups() -> 21: [{admin, [parallel], admin_tests()}, 22: {user, [parallel], user_tests()}]. 23: 24: init_per_suite(Config) -> 25: Config1 = escalus:init_per_suite(Config), 26: application:ensure_all_started(gun), 27: Config1. 28: 29: end_per_suite(Config) -> 30: escalus:end_per_suite(Config). 31: 32: init_per_group(user, Config) -> 33: graphql_helper:init_user(Config); 34: init_per_group(admin, Config) -> 35: graphql_helper:init_admin_handler(Config). 36: 37: end_per_group(user, _Config) -> 38: escalus_fresh:clean(), 39: graphql_helper:clean(); 40: end_per_group(admin, _Config) -> 41: graphql_helper:clean(). 42: 43: init_per_testcase(CaseName, Config) -> 44: escalus:init_per_testcase(CaseName, Config). 45: 46: end_per_testcase(CaseName, Config) -> 47: escalus:end_per_testcase(CaseName, Config). 48: 49: admin_tests() -> 50: [admin_missing_query, 51: admin_invalid_query_string, 52: admin_missing_creds, 53: admin_invalid_creds, 54: admin_invalid_method, 55: admin_invalid_operation_type]. 56: 57: user_tests() -> 58: [user_missing_query, 59: user_invalid_query_string, 60: user_missing_creds, 61: user_invalid_creds, 62: user_invalid_method, 63: user_invalid_operation_type]. 64: 65: %% Test cases and stories 66: 67: admin_missing_query(Config) -> 68: get_bad_request(execute_auth_sse(#{}, Config)). 69: 70: user_missing_query(Config) -> 71: escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_missing_query_story/2). 72: 73: user_missing_query_story(Config, Alice) -> 74: get_bad_request(execute_user_sse(#{}, Alice, Config)). 75: 76: admin_invalid_query_string(_Config) -> 77: Port = graphql_helper:get_listener_port(admin), 78: get_bad_request(sse_helper:connect_to_sse(Port, "/api/graphql/sse?=invalid", undefined, #{})). 79: 80: user_invalid_query_string(Config) -> 81: escalus:fresh_story(Config, [{alice, 1}], fun user_invalid_query_string_story/1). 82: 83: user_invalid_query_string_story(Alice) -> 84: Port = graphql_helper:get_listener_port(user), 85: Creds = make_creds(Alice), 86: get_bad_request(sse_helper:connect_to_sse(Port, "/api/graphql/sse?=invalid", Creds, #{})). 87: 88: admin_missing_creds(_Config) -> 89: get_unauthorized(execute_sse(admin, #{query => doc(), variables => args()}, undefined)). 90: 91: user_missing_creds(_Config) -> 92: get_unauthorized(execute_sse(user, #{query => doc()}, undefined)). 93: 94: admin_invalid_creds(_Config) -> 95: Creds = {<<"invalid">>, <<"creds">>}, 96: get_unauthorized(execute_sse(admin, #{query => doc(), variables => args()}, Creds)). 97: 98: user_invalid_creds(_Config) -> 99: get_unauthorized(execute_sse(user, #{query => doc()}, {<<"invalid">>, <<"creds">>})). 100: 101: admin_invalid_method(_Config) -> 102: #{node := Node} = mim(), 103: Request = build_request(Node, admin, #{query => doc(), variables => args()}, undefined), 104: %% POST was used, while SSE accepts only GET 105: get_method_not_allowed(rest_helper:make_request(Request#{path => "/graphql/sse"})). 106: 107: user_invalid_method(Config) -> 108: escalus:fresh_story(Config, [{alice, 1}], fun user_invalid_method_story/1). 109: 110: user_invalid_method_story(Alice) -> 111: #{node := Node} = mim(), 112: Request = build_request(Node, user, #{query => doc()}, make_creds(Alice)), 113: %% POST was used, while SSE accepts only GET 114: get_method_not_allowed(rest_helper:make_request(Request#{path => "/graphql/sse"})). 115: 116: admin_invalid_operation_type(Config) -> 117: Creds = graphql_helper:make_admin_creds(admin, Config), 118: get_bad_request(execute_sse(admin, #{query => query_doc(), variables => args()}, Creds)). 119: 120: user_invalid_operation_type(Config) -> 121: escalus:fresh_story(Config, [{alice, 1}], fun user_invalid_operation_type_story/1). 122: 123: user_invalid_operation_type_story(Alice) -> 124: get_bad_request(execute_sse(user, #{query => query_doc()}, make_creds(Alice))). 125: 126: %% Helpers 127: 128: %% Subscription - works only with the SSE handler 129: doc() -> 130: graphql_helper:get_doc(<<"stanza">>, <<"subscribeForMessages">>). 131: 132: %% Query - works only with the REST handler 133: query_doc() -> 134: graphql_helper:get_doc(<<"stanza">>, <<"getLastMessages">>). 135: 136: %% Same args used by both operations - only for Admin 137: args() -> 138: #{caller => <<"alice@localhost">>}.