1: %%============================================================================== 2: %% Copyright 2013 Erlang Solutions Ltd. 3: %% 4: %% Licensed under the Apache License, Version 2.0 (the "License"); 5: %% you may not use this file except in compliance with the License. 6: %% You may obtain a copy of the License at 7: %% 8: %% http://www.apache.org/licenses/LICENSE-2.0 9: %% 10: %% Unless required by applicable law or agreed to in writing, software 11: %% distributed under the License is distributed on an "AS IS" BASIS, 12: %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13: %% See the License for the specific language governing permissions and 14: %% limitations under the License. 15: %%============================================================================== 16: -module(mongooseimctl_SUITE). 17: -compile([export_all, nowarn_export_all, nowarn_shadow_vars]). 18: -include_lib("escalus/include/escalus.hrl"). 19: -include_lib("common_test/include/ct.hrl"). 20: -include_lib("exml/include/exml.hrl"). 21: -include_lib("eunit/include/eunit.hrl"). 22: 23: -import(mongooseimctl_helper, [mongooseimctl/3]). 24: -import(distributed_helper, [mim/0, require_rpc_nodes/1]). 25: -import(domain_helper, [domain/0]). 26: 27: %%-------------------------------------------------------------------- 28: %% Suite configuration 29: %%-------------------------------------------------------------------- 30: 31: all() -> 32: [ 33: {group, graphql}, 34: {group, help}, 35: {group, server} 36: ]. 37: 38: groups() -> 39: [{graphql, [], graphql()}, 40: {help, [], help()}, 41: {server, [], server()}]. 42: 43: graphql() -> 44: [graphql_wrong_arguments_number, 45: can_execute_admin_queries_with_permissions, 46: can_handle_execution_error, 47: graphql_error_unknown_command_with_args, 48: graphql_error_unknown_command_without_args, 49: graphql_error_unknown_category_with_args, 50: graphql_error_unknown_category_without_args, 51: graphql_no_command, 52: graphql_error_invalid_args, 53: graphql_error_invalid_arg_value, 54: graphql_error_no_arg_value, 55: graphql_error_missing_args, 56: graphql_error_unknown_arg, 57: graphql_arg_help, 58: graphql_command]. 59: 60: help() -> 61: [default_help, 62: help_with_dual_mode, 63: help_with_long_mode]. 64: 65: server() -> 66: [server_status, 67: server_is_started]. 68: 69: suite() -> 70: require_rpc_nodes([mim]) ++ escalus:suite(). 71: 72: init_per_suite(Config) -> 73: Node = mim(), 74: Config1 = ejabberd_node_utils:init(Node, Config), 75: Config1. 76: 77: end_per_suite(Config) -> 78: Config. 79: 80: init_per_group(_GroupName, Config) -> 81: Config. 82: 83: end_per_group(_GroupName, Config) -> 84: Config. 85: 86: init_per_testcase(CaseName, Config) -> 87: escalus:init_per_testcase(CaseName, Config). 88: 89: end_per_testcase(CaseName, Config) -> 90: escalus:end_per_testcase(CaseName, Config). 91: 92: %%-------------------------------------------------------------------- 93: %% mongoose_graphql tests 94: %%-------------------------------------------------------------------- 95: 96: can_execute_admin_queries_with_permissions(Config) -> 97: Query = "query { checkAuth { authStatus } }", 98: Res = mongooseimctl("graphql", [Query], Config), 99: ?assertMatch({_, 0}, Res), 100: Data = element(1, Res), 101: ?assertNotEqual(nomatch, string:find(Data, "AUTHORIZED")). 102: 103: can_handle_execution_error(Config) -> 104: Query = "{}", 105: Res = mongooseimctl("graphql", [Query], Config), 106: ?assertMatch({_, 1}, Res), 107: Data = element(1, Res), 108: ?assertNotEqual(nomatch, string:find(Data, "parser_error")). 109: 110: graphql_wrong_arguments_number(Config) -> 111: ExpectedFragment = "This command requires", 112: ResNoArgs = mongooseimctl("graphql", [], Config), 113: ?assertMatch({_, 1}, ResNoArgs), 114: Data1 = element(1, ResNoArgs), 115: ?assertNotEqual(nomatch, string:find(Data1, ExpectedFragment)), 116: 117: ResTooManyArgs = mongooseimctl("graphql", ["{}", "{}"], Config), 118: ?assertMatch({_, 1}, ResTooManyArgs), 119: Data2 = element(1, ResTooManyArgs), 120: ?assertNotEqual(nomatch, string:find(Data2, ExpectedFragment)). 121: 122: %% Generic GraphQL command tests 123: %% Specific commands are tested in graphql_*_SUITE 124: 125: graphql_error_unknown_command_with_args(Config) -> 126: {Res, 1} = mongooseimctl("account", ["makeCoffee", "--strength", "medium"], Config), 127: ?assertMatch({match, _}, re:run(Res, "Unknown command")), 128: expect_existing_commands(Res). 129: 130: graphql_error_unknown_command_without_args(Config) -> 131: {Res, 1} = mongooseimctl("account", ["makeCoffee"], Config), 132: ?assertMatch({match, _}, re:run(Res, "Unknown command")), 133: expect_existing_commands(Res). 134: 135: graphql_error_unknown_category_with_args(Config) -> 136: {Res, 1} = mongooseimctl("cafe", ["makeCoffee"], Config), 137: ?assertMatch({match, _}, re:run(Res, "Unknown category")), 138: expect_category_list(Res). 139: 140: graphql_error_unknown_category_without_args(Config) -> 141: {Res, 1} = mongooseimctl("cafe", [], Config), 142: ?assertMatch({match, _}, re:run(Res, "Unknown category")), 143: expect_category_list(Res). 144: 145: graphql_no_command(Config) -> 146: %% Not an error - lists commands in the given category 147: {Res, 0} = mongooseimctl("account", [], Config), 148: expect_existing_commands(Res). 149: 150: graphql_error_invalid_args(Config) -> 151: {Res, 1} = mongooseimctl("account", ["countUsers", "now"], Config), 152: ?assertMatch({match, _}, re:run(Res, "Could not parse")), 153: expect_command_arguments(Res). 154: 155: graphql_error_invalid_arg_value(Config) -> 156: {Res, 1} = mongooseimctl("vcard", ["setVcard", "--user", "user@host", "--vcard", "x"], Config), 157: %% vCard should be provided in JSON 158: ?assertMatch({match, _}, re:run(Res, "Invalid value 'x' of argument 'vcard'")), 159: ?assertMatch({match, _}, re:run(Res, "vcard\s+VcardInput!")). 160: 161: graphql_error_no_arg_value(Config) -> 162: {Res, 1} = mongooseimctl("account", ["countUsers", "--domain"], Config), 163: ?assertMatch({match, _}, re:run(Res, "Could not parse")), 164: expect_command_arguments(Res). 165: 166: graphql_error_missing_args(Config) -> 167: {Res, 1} = mongooseimctl("account", ["countUsers"], Config), 168: ?assertMatch({match, _}, re:run(Res, "Missing mandatory arguments")), 169: expect_command_arguments(Res). 170: 171: graphql_error_unknown_arg(Config) -> 172: {Res, 1} = mongooseimctl("account", ["countUsers", "--domain", "localhost", 173: "--x", "y"], Config), 174: ?assertMatch({match, _}, re:run(Res, "Unknown argument")), 175: expect_command_arguments(Res). 176: 177: graphql_arg_help(Config) -> 178: {Res, 0} = mongooseimctl("account", ["countUsers", "--help"], Config), 179: expect_command_arguments(Res). 180: 181: graphql_command(Config) -> 182: {ResJSON, 0} = mongooseimctl("account", ["countUsers", "--domain", "localhost"], Config), 183: #{<<"data">> := Data} = rest_helper:decode(ResJSON, #{return_maps => true}), 184: ?assertMatch(#{<<"account">> := #{<<"countUsers">> := _}}, Data). 185: 186: expect_existing_commands(Res) -> 187: ?assertMatch({match, _}, re:run(Res, "countUsers")). 188: 189: expect_command_arguments(Res) -> 190: ?assertMatch({match, _}, re:run(Res, "domain\s+DomainName!")). 191: 192: %%----------------------------------------------------------------- 193: %% Help tests 194: %%----------------------------------------------------------------- 195: 196: default_help(Config) -> 197: #{node := Node} = mim(), 198: CtlCmd = distributed_helper:ctl_path(Node, Config), 199: {Res, 2} = mongooseimctl_helper:run(CtlCmd, []), 200: expect_category_list(Res). 201: 202: help_with_dual_mode(Config) -> 203: {Res1, 2} = mongooseimctl("help", ["--dual"], Config), 204: expect_category_list(Res1), 205: {Res2, 2} = mongooseimctl("help", ["--nonexistent"], Config), 206: expect_category_list(Res2), 207: {Res3, 2} = mongooseimctl("help", [], Config), 208: expect_category_list(Res3). 209: 210: help_with_long_mode(Config) -> 211: {Res, 2} = mongooseimctl("help", ["--long"], Config), 212: io:format("Res: ~p", [Res]), 213: ?assertMatch({match, _}, re:run(Res, "Usage")), 214: ?assertMatch({match, _}, re:run(Res, "account \n\s+Account management")). 215: 216: %%----------------------------------------------------------------- 217: %% Server management tests 218: %%----------------------------------------------------------------- 219: 220: server_status(Config) -> 221: {Res, 0} = mongooseimctl("status", [], Config), 222: ?assertMatch({match, _}, re:run(Res, "Erlang VM status: started")). 223: 224: server_is_started(Config) -> 225: %% Wait for the server to start, but it is already running 226: {Res, 0} = mongooseimctl("started", [], Config), 227: %% Expect only whitespace 228: ?assertMatch(nomatch, re:run(Res, "\S")). 229: 230: %%----------------------------------------------------------------- 231: %% Helpers 232: %%----------------------------------------------------------------- 233: 234: expect_category_list(Res) -> 235: ?assertMatch({match, _}, re:run(Res, "Usage")), 236: ?assertMatch({match, _}, re:run(Res, "account\s+Account management")).