1: -module(graphql_stats_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, secondary_domain/0]).
    8: -import(graphql_helper, [execute_command/4, get_ok_value/2, get_unauthorized/1]).
    9: -import(mongooseimctl_helper, [mongooseimctl/3, rpc_call/3]).
   10: 
   11: -include_lib("common_test/include/ct.hrl").
   12: -include_lib("eunit/include/eunit.hrl").
   13: 
   14: suite() ->
   15:     require_rpc_nodes([mim]) ++ escalus:suite().
   16: 
   17: all() ->
   18:     [{group, admin_stats_http},
   19:      {group, admin_stats_cli},
   20:      {group, domain_admin_stats}].
   21: 
   22: groups() ->
   23:     [{admin_stats_http, [], admin_stats_tests()},
   24:      {admin_stats_cli, [], admin_stats_tests()},
   25:      {domain_admin_stats, [], domain_admin_tests()}].
   26: 
   27: admin_stats_tests() ->
   28:     [admin_stats_global_test,
   29:      admin_stats_global_with_users_test,
   30:      admin_stats_domain_test,
   31:      admin_stats_domain_with_users_test,
   32:      admin_stats_domain_without_users_test].
   33: 
   34: domain_admin_tests() ->
   35:     [domain_admin_stats_global_test,
   36:      admin_stats_domain_test,
   37:      admin_stats_domain_with_users_test,
   38:      domain_admin_stats_domain_no_permission_test].
   39: 
   40: init_per_suite(Config) ->
   41:     Config1 = ejabberd_node_utils:init(mim(), Config),
   42:     Config2 = [{auth_mods, mongoose_helper:auth_modules()} | Config1],
   43:     escalus:init_per_suite(Config2).
   44: 
   45: end_per_suite(Config) ->
   46:     escalus:end_per_suite(Config).
   47: 
   48: init_per_group(admin_stats_http, Config) ->
   49:     graphql_helper:init_admin_handler(Config);
   50: init_per_group(admin_stats_cli, Config) ->
   51:     graphql_helper:init_admin_cli(Config);
   52: init_per_group(domain_admin_stats, Config) ->
   53:     graphql_helper:init_domain_admin_handler(Config).
   54: 
   55: end_per_group(_, _Config) ->
   56:     graphql_helper:clean(),
   57:     escalus_fresh:clean().
   58: 
   59: init_per_testcase(CaseName = admin_stats_domain_without_users_test, Config) ->
   60:     case lists:member(ejabberd_auth_ldap, ?config(auth_mods, Config)) of
   61:         true ->
   62:             {skip, not_supported_with_ldap};
   63:         false ->
   64:             escalus:init_per_testcase(CaseName, Config)
   65:     end;
   66: init_per_testcase(CaseName, Config) ->
   67:     escalus:init_per_testcase(CaseName, Config).
   68: 
   69: end_per_testcase(CaseName, Config) ->
   70:     escalus_fresh:clean(),
   71:     escalus:end_per_testcase(CaseName, Config).
   72: 
   73: % Admin test cases
   74: 
   75: admin_stats_global_test(Config) ->
   76:     Result = get_ok_value([data, stat, globalStats], get_stats(Config)),
   77:     #{<<"uptimeSeconds">> := UptimeSeconds, <<"registeredUsers">> := RegisteredUsers,
   78:       <<"onlineUsersNode">> := OnlineUsersNode, <<"onlineUsers">> := OnlineUsers,
   79:       <<"incomingS2S">> := IncomingS2S, <<"outgoingS2S">> := OutgoingS2S} = Result,
   80:     ?assert(is_not_negative_integer(UptimeSeconds)),
   81:     ?assertEqual(0, RegisteredUsers),
   82:     ?assertEqual(0, OnlineUsersNode),
   83:     ?assertEqual(0, OnlineUsers),
   84:     ?assert(is_not_negative_integer(IncomingS2S)),
   85:     ?assert(is_not_negative_integer(OutgoingS2S)).
   86: 
   87: admin_stats_global_with_users_test(Config) ->
   88:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_stats_global_with_users_test/2).
   89: 
   90: admin_stats_global_with_users_test(Config, _Alice) ->
   91:     Result = get_ok_value([data, stat, globalStats], get_stats(Config)),
   92:     #{<<"uptimeSeconds">> := UptimeSeconds, <<"registeredUsers">> := RegisteredUsers,
   93:       <<"onlineUsersNode">> := OnlineUsersNode, <<"onlineUsers">> := OnlineUsers,
   94:       <<"incomingS2S">> := IncomingS2S, <<"outgoingS2S">> := OutgoingS2S} = Result,
   95:     ?assert(is_not_negative_integer(UptimeSeconds)),
   96:     ?assert(RegisteredUsers > 0),
   97:     ?assertEqual(1, OnlineUsersNode),
   98:     ?assertEqual(1, OnlineUsers),
   99:     ?assert(is_not_negative_integer(IncomingS2S)),
  100:     ?assert(is_not_negative_integer(OutgoingS2S)).
  101: 
  102: admin_stats_domain_test(Config) ->
  103:     Result1 = get_ok_value([data, stat, domainStats], get_domain_stats(domain(), Config)),
  104:     ?assertMatch(#{<<"registeredUsers">> := 0, <<"onlineUsers">> := 0}, Result1),
  105:     Result2 = get_ok_value([data, stat, domainStats], get_domain_stats(unprep(domain()), Config)),
  106:     ?assertMatch(#{<<"registeredUsers">> := 0, <<"onlineUsers">> := 0}, Result2).
  107: 
  108: admin_stats_domain_with_users_test(Config) ->
  109:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_stats_domain_with_users_test/2).
  110: 
  111: admin_stats_domain_with_users_test(Config, _Alice) ->
  112:     Result1 = get_ok_value([data, stat, domainStats], get_domain_stats(domain(), Config)),
  113:     ?assertMatch(#{<<"registeredUsers">> := 1, <<"onlineUsers">> := 1}, Result1),
  114:     Result2 = get_ok_value([data, stat, domainStats], get_domain_stats(unprep(domain()), Config)),
  115:     ?assertMatch(#{<<"registeredUsers">> := 1, <<"onlineUsers">> := 1}, Result2).
  116: 
  117: admin_stats_domain_without_users_test(Config) ->
  118:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  119:                                     fun admin_stats_domain_without_users_test/2).
  120: 
  121: admin_stats_domain_without_users_test(Config, _Alice) ->
  122:     %% Alice's session is at domain, not secondary_domain
  123:     Result = get_ok_value([data, stat, domainStats], get_domain_stats(secondary_domain(), Config)),
  124:     ?assertMatch(#{<<"registeredUsers">> := 0, <<"onlineUsers">> := 0}, Result).
  125: 
  126: % Domain admin test cases
  127: 
  128: domain_admin_stats_global_test(Config) ->
  129:     get_unauthorized(get_stats(Config)).
  130: 
  131: domain_admin_stats_domain_no_permission_test(Config) ->
  132:     get_unauthorized(get_domain_stats(secondary_domain(), Config)),
  133:     get_unauthorized(get_domain_stats(unprep(secondary_domain()), Config)).
  134: 
  135: % Commands
  136: 
  137: get_stats(Config) ->
  138:     execute_command(<<"stat">>, <<"globalStats">>, #{}, Config).
  139: 
  140: get_domain_stats(Domain, Config) ->
  141:     Vars = #{domain => Domain},
  142:     execute_command(<<"stat">>, <<"domainStats">>, Vars, Config).
  143: 
  144: % Helpers
  145: 
  146: is_not_negative_integer(Number) when is_integer(Number), Number >= 0 ->
  147:     true;
  148: is_not_negative_integer(_) ->
  149:     false.