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:end_per_suite(Config).
   51: 
   52: init_per_group(admin_handler, Config) ->
   53:     graphql_helper:init_admin_handler(Config);
   54: init_per_group(user_handler, Config) ->
   55:     Config1 = escalus:create_users(Config, escalus:get_users([alice])),
   56:     [{schema_endpoint, user} | Config1];
   57: init_per_group(_, Config) ->
   58:     Config.
   59: 
   60: end_per_group(user_handler, Config) ->
   61:     escalus:delete_users(Config, escalus:get_users([alice]));
   62: end_per_group(_, _Config) ->
   63:     ok.
   64: 
   65: init_per_testcase(CaseName, Config) ->
   66:     escalus:init_per_testcase(CaseName, Config).
   67: 
   68: end_per_testcase(CaseName, Config) ->
   69:     escalus:end_per_testcase(CaseName, Config).
   70: 
   71: can_connect_to_admin(_Config) ->
   72:     ?assertMatch({{<<"400">>, <<"Bad Request">>}, _}, execute(admin, #{}, undefined)).
   73: 
   74: can_connect_to_user(_Config) ->
   75:     ?assertMatch({{<<"400">>, <<"Bad Request">>}, _}, execute(user, #{}, undefined)).
   76: 
   77: can_load_graphiql(Config) ->
   78:     Ep = ?config(schema_endpoint, Config),
   79:     {Status, Html} = get_graphiql_website(Ep),
   80:     ?assertEqual({<<"200">>, <<"OK">>}, Status),
   81:     ?assertNotEqual(nomatch, binary:match(Html, <<"Loading...">>)).
   82: 
   83: user_checks_auth(Config) ->
   84:     Ep = ?config(schema_endpoint, Config),
   85:     Body = #{query => "{ checkAuth { username authStatus } }"},
   86:     StatusData = execute(Ep, Body, undefined),
   87:     ?assertUserAuth(null, 'UNAUTHORIZED', StatusData).
   88: 
   89: auth_user_checks_auth(Config) ->
   90:     escalus:fresh_story(
   91:         Config, [{alice, 1}],
   92:         fun(Alice) ->
   93:             Password = user_password(alice),
   94:             AliceJID = escalus_client:short_jid(Alice),
   95:             Ep = ?config(schema_endpoint, Config),
   96:             Body = #{query => "{ checkAuth { username authStatus } }"},
   97:             StatusData = execute(Ep, Body, {AliceJID, Password}),
   98:             ?assertUserAuth(AliceJID, 'AUTHORIZED', StatusData)
   99:         end).
  100: 
  101: admin_checks_auth(Config) ->
  102:     Ep = ?config(schema_endpoint, Config),
  103:     Body = #{query => "{ checkAuth }"},
  104:     StatusData = execute(Ep, Body, undefined),
  105:     ?assertAdminAuth('UNAUTHORIZED', StatusData).
  106: 
  107: auth_admin_checks_auth(Config) ->
  108:     Ep = ?config(schema_endpoint, Config),
  109:     Opts = ?config(listener_opts, Config),
  110:     User = proplists:get_value(username, Opts),
  111:     Password = proplists:get_value(password, Opts),
  112:     Body = #{query => "{ checkAuth }"},
  113:     StatusData = execute(Ep, Body, {User, Password}),
  114:     ?assertAdminAuth('AUTHORIZED', StatusData).
  115: 
  116: %% Helpers
  117: 
  118: assert_auth(Auth, {Status, Data}) ->
  119:     ?assertEqual({<<"200">>, <<"OK">>}, Status),
  120:     ?assertMatch(#{<<"data">> := #{<<"checkAuth">> := Auth}}, Data).
  121: 
  122: user_password(User) ->
  123:     [{User, Props}] = escalus:get_users([User]),
  124:     proplists:get_value(password, Props).
  125: 
  126: get_graphiql_website(EpName) ->
  127:     Request =
  128:       #{port => graphql_helper:get_listener_port(EpName),
  129:         role => {graphql, atom_to_binary(EpName)},
  130:         method => <<"GET">>,
  131:         headers => [{<<"Accept">>, <<"text/html">>}],
  132:         return_maps => true,
  133:         path => "/graphql"},
  134:     rest_helper:make_request(Request).