1: -module(graphql_SUITE).
    2: 
    3: -include_lib("common_test/include/ct.hrl").
    4: -include_lib("eunit/include/eunit.hrl").
    5: -include_lib("exml/include/exml.hrl").
    6: 
    7: -compile([export_all, nowarn_export_all]).
    8: 
    9: -import(distributed_helper, [mim/0, require_rpc_nodes/1, rpc/4]).
   10: -import(graphql_helper, [execute/3]).
   11: 
   12: -define(assertAdminAuth(Auth, Data), assert_auth(atom_to_binary(Auth), Data)).
   13: -define(assertUserAuth(Username, Auth, Data),
   14:         assert_auth(#{<<"username">> => Username,
   15:                       <<"authStatus">> => atom_to_binary(Auth)}, Data)).
   16: 
   17: suite() ->
   18:     require_rpc_nodes([mim]) ++ escalus:suite().
   19: 
   20: all() ->
   21:     [{group, cowboy_handler},
   22:      {group, admin_handler},
   23:      {group, user_handler}].
   24: 
   25: groups() ->
   26:     [{cowboy_handler, [parallel], cowboy_handler()},
   27:      {user_handler, [parallel], user_handler()},
   28:      {admin_handler, [parallel], admin_handler()}].
   29: 
   30: cowboy_handler() ->
   31:     [can_connect_to_admin,
   32:      can_connect_to_user].
   33: 
   34: user_handler() ->
   35:     [user_checks_auth,
   36:      auth_user_checks_auth | common_tests()].
   37: admin_handler() ->
   38:     [admin_checks_auth,
   39:      auth_admin_checks_auth | common_tests()].
   40: 
   41: common_tests() ->
   42:     [can_load_graphiql].
   43: 
   44: init_per_suite(Config) ->
   45:     Config1 = escalus:init_per_suite(Config),
   46:     dynamic_modules:save_modules(domain_helper:host_type(), Config1).
   47: 
   48: end_per_suite(Config) ->
   49:     dynamic_modules:restore_modules(Config),
   50:     escalus_fresh:clean(),
   51:     escalus:end_per_suite(Config).
   52: 
   53: init_per_group(admin_handler, Config) ->
   54:     graphql_helper:init_admin_handler(Config);
   55: init_per_group(user_handler, Config) ->
   56:     Config1 = escalus:create_users(Config, escalus:get_users([alice])),
   57:     [{schema_endpoint, user} | Config1];
   58: init_per_group(_, Config) ->
   59:     Config.
   60: 
   61: end_per_group(user_handler, Config) ->
   62:     escalus:delete_users(Config, escalus:get_users([alice]));
   63: end_per_group(_, _Config) ->
   64:     ok.
   65: 
   66: init_per_testcase(CaseName, Config) ->
   67:     escalus:init_per_testcase(CaseName, Config).
   68: 
   69: end_per_testcase(CaseName, Config) ->
   70:     escalus:end_per_testcase(CaseName, Config).
   71: 
   72: can_connect_to_admin(_Config) ->
   73:     ?assertMatch({{<<"400">>, <<"Bad Request">>}, _}, execute(admin, #{}, undefined)).
   74: 
   75: can_connect_to_user(_Config) ->
   76:     ?assertMatch({{<<"400">>, <<"Bad Request">>}, _}, execute(user, #{}, undefined)).
   77: 
   78: can_load_graphiql(Config) ->
   79:     Ep = ?config(schema_endpoint, Config),
   80:     {Status, Html} = get_graphiql_website(Ep),
   81:     ?assertEqual({<<"200">>, <<"OK">>}, Status),
   82:     ?assertNotEqual(nomatch, binary:match(Html, <<"Loading...">>)).
   83: 
   84: user_checks_auth(Config) ->
   85:     Ep = ?config(schema_endpoint, Config),
   86:     Body = #{query => "{ checkAuth { username authStatus } }"},
   87:     StatusData = execute(Ep, Body, undefined),
   88:     ?assertUserAuth(null, 'UNAUTHORIZED', StatusData).
   89: 
   90: auth_user_checks_auth(Config) ->
   91:     escalus:fresh_story(
   92:         Config, [{alice, 1}],
   93:         fun(Alice) ->
   94:             Password = user_password(alice),
   95:             AliceJID = escalus_client:short_jid(Alice),
   96:             Ep = ?config(schema_endpoint, Config),
   97:             Body = #{query => "{ checkAuth { username authStatus } }"},
   98:             StatusData = execute(Ep, Body, {AliceJID, Password}),
   99:             ?assertUserAuth(AliceJID, 'AUTHORIZED', StatusData)
  100:         end).
  101: 
  102: admin_checks_auth(Config) ->
  103:     Ep = ?config(schema_endpoint, Config),
  104:     Body = #{query => "{ checkAuth }"},
  105:     StatusData = execute(Ep, Body, undefined),
  106:     ?assertAdminAuth('UNAUTHORIZED', StatusData).
  107: 
  108: auth_admin_checks_auth(Config) ->
  109:     Ep = ?config(schema_endpoint, Config),
  110:     Opts = ?config(listener_opts, Config),
  111:     User = proplists:get_value(username, Opts),
  112:     Password = proplists:get_value(password, Opts),
  113:     Body = #{query => "{ checkAuth }"},
  114:     StatusData = execute(Ep, Body, {User, Password}),
  115:     ?assertAdminAuth('AUTHORIZED', StatusData).
  116: 
  117: %% Helpers
  118: 
  119: assert_auth(Auth, {Status, Data}) ->
  120:     ?assertEqual({<<"200">>, <<"OK">>}, Status),
  121:     ?assertMatch(#{<<"data">> := #{<<"checkAuth">> := Auth}}, Data).
  122: 
  123: user_password(User) ->
  124:     [{User, Props}] = escalus:get_users([User]),
  125:     proplists:get_value(password, Props).
  126: 
  127: get_graphiql_website(EpName) ->
  128:     Request =
  129:       #{port => graphql_helper:get_listener_port(EpName),
  130:         role => {graphql, atom_to_binary(EpName)},
  131:         method => <<"GET">>,
  132:         headers => [{<<"Accept">>, <<"text/html">>}],
  133:         return_maps => true,
  134:         path => "/graphql"},
  135:     rest_helper:make_request(Request).