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: 63: server() -> 64: [server_status, 65: server_is_started]. 66: 67: suite() -> 68: require_rpc_nodes([mim]) ++ escalus:suite(). 69: 70: init_per_suite(Config) -> 71: Node = mim(), 72: Config1 = ejabberd_node_utils:init(Node, Config), 73: Config1. 74: 75: end_per_suite(_Config) -> 76: ok. 77: 78: init_per_testcase(CaseName, Config) -> 79: escalus:init_per_testcase(CaseName, Config). 80: 81: end_per_testcase(CaseName, Config) -> 82: escalus:end_per_testcase(CaseName, Config). 83: 84: %%-------------------------------------------------------------------- 85: %% mongoose_graphql tests 86: %%-------------------------------------------------------------------- 87: 88: can_execute_admin_queries_with_permissions(Config) -> 89: Query = "query { checkAuth { authStatus } }", 90: Res = mongooseimctl("graphql", [Query], Config), 91: ?assertMatch({_, 0}, Res), 92: Data = element(1, Res), 93: ?assertNotEqual(nomatch, string:find(Data, "AUTHORIZED")). 94: 95: can_handle_execution_error(Config) -> 96: Query = "{}", 97: Res = mongooseimctl("graphql", [Query], Config), 98: ?assertMatch({_, 1}, Res), 99: Data = element(1, Res), 100: ?assertNotEqual(nomatch, string:find(Data, "parser_error")). 101: 102: graphql_wrong_arguments_number(Config) -> 103: ExpectedFragment = "This command requires", 104: ResNoArgs = mongooseimctl("graphql", [], Config), 105: ?assertMatch({_, 1}, ResNoArgs), 106: Data1 = element(1, ResNoArgs), 107: ?assertNotEqual(nomatch, string:find(Data1, ExpectedFragment)), 108: 109: ResTooManyArgs = mongooseimctl("graphql", ["{}", "{}"], Config), 110: ?assertMatch({_, 1}, ResTooManyArgs), 111: Data2 = element(1, ResTooManyArgs), 112: ?assertNotEqual(nomatch, string:find(Data2, ExpectedFragment)). 113: 114: %% Generic GraphQL command tests 115: %% Specific commands are tested in graphql_*_SUITE 116: 117: graphql_error_unknown_command_with_args(Config) -> 118: {Res, 1} = mongooseimctl("account", ["makeCoffee", "--strength", "medium"], Config), 119: ?assertMatch({match, _}, re:run(Res, "Unknown command")), 120: expect_existing_commands(Res). 121: 122: graphql_error_unknown_command_without_args(Config) -> 123: {Res, 1} = mongooseimctl("account", ["makeCoffee"], Config), 124: ?assertMatch({match, _}, re:run(Res, "Unknown command")), 125: expect_existing_commands(Res). 126: 127: graphql_error_unknown_category_with_args(Config) -> 128: {Res, 1} = mongooseimctl("cafe", ["makeCoffee"], Config), 129: ?assertMatch({match, _}, re:run(Res, "Unknown category")), 130: expect_category_list(Res). 131: 132: graphql_error_unknown_category_without_args(Config) -> 133: {Res, 1} = mongooseimctl("cafe", [], Config), 134: ?assertMatch({match, _}, re:run(Res, "Unknown category")), 135: expect_category_list(Res). 136: 137: graphql_no_command(Config) -> 138: %% Not an error - lists commands in the given category 139: {Res, 0} = mongooseimctl("account", [], Config), 140: expect_existing_commands(Res). 141: 142: graphql_error_invalid_args(Config) -> 143: {Res, 1} = mongooseimctl("account", ["countUsers", "now"], Config), 144: ?assertMatch({match, _}, re:run(Res, "Could not parse")), 145: expect_command_arguments(Res). 146: 147: graphql_error_invalid_arg_value(Config) -> 148: {Res, 1} = mongooseimctl("vcard", ["setVcard", "--user", "user@host", "--vcard", "x"], Config), 149: %% vCard should be provided in JSON 150: ?assertMatch({match, _}, re:run(Res, "Invalid value 'x' of argument 'vcard'")), 151: ?assertMatch({match, _}, re:run(Res, "vcard\s+VcardInput!")). 152: 153: graphql_error_no_arg_value(Config) -> 154: {Res, 1} = mongooseimctl("account", ["countUsers", "--domain"], Config), 155: ?assertMatch({match, _}, re:run(Res, "Could not parse")), 156: expect_command_arguments(Res). 157: 158: graphql_error_missing_args(Config) -> 159: {Res, 1} = mongooseimctl("account", ["countUsers"], Config), 160: ?assertMatch({match, _}, re:run(Res, "Missing mandatory arguments")), 161: expect_command_arguments(Res). 162: 163: graphql_error_unknown_arg(Config) -> 164: {Res, 1} = mongooseimctl("account", ["countUsers", "--domain", "localhost", 165: "--x", "y"], Config), 166: ?assertMatch({match, _}, re:run(Res, "Unknown argument")), 167: expect_command_arguments(Res). 168: 169: graphql_arg_help(Config) -> 170: {Res, 0} = mongooseimctl("account", ["countUsers", "--help"], Config), 171: expect_command_arguments(Res). 172: 173: graphql_command(Config) -> 174: {ResJSON, 0} = mongooseimctl("account", ["countUsers", "--domain", "localhost"], Config), 175: #{<<"data">> := Data} = rest_helper:decode(ResJSON, #{return_maps => true}), 176: ?assertMatch(#{<<"account">> := #{<<"countUsers">> := _}}, Data). 177: 178: expect_existing_commands(Res) -> 179: ?assertMatch({match, _}, re:run(Res, "countUsers")). 180: 181: expect_command_arguments(Res) -> 182: ?assertMatch({match, _}, re:run(Res, "domain\s+DomainName!")). 183: 184: %%----------------------------------------------------------------- 185: %% Help tests 186: %%----------------------------------------------------------------- 187: 188: default_help(Config) -> 189: #{node := Node} = mim(), 190: CtlCmd = distributed_helper:ctl_path(Node, Config), 191: {Res, 2} = mongooseimctl_helper:run(CtlCmd, []), 192: expect_category_list(Res). 193: 194: %%----------------------------------------------------------------- 195: %% Server management tests 196: %%----------------------------------------------------------------- 197: 198: server_status(Config) -> 199: {Res, 0} = mongooseimctl("status", [], Config), 200: ?assertMatch({match, _}, re:run(Res, "Erlang VM status: started")). 201: 202: server_is_started(Config) -> 203: %% Wait for the server to start, but it is already running 204: {Res, 0} = mongooseimctl("started", [], Config), 205: %% Expect only whitespace 206: ?assertMatch(nomatch, re:run(Res, "\S")). 207: 208: %%----------------------------------------------------------------- 209: %% Helpers 210: %%----------------------------------------------------------------- 211: 212: expect_category_list(Res) -> 213: ?assertMatch({match, _}, re:run(Res, "Usage")), 214: ?assertMatch({match, _}, re:run(Res, "account\s+Account management")).