1: %%==============================================================================
    2: %% Copyright 2012 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(adhoc_SUITE).
   17: -compile([export_all, nowarn_export_all]).
   18: 
   19: -include_lib("escalus/include/escalus.hrl").
   20: -include_lib("common_test/include/ct.hrl").
   21: -include_lib("eunit/include/eunit.hrl").
   22: 
   23: -import(domain_helper, [host_type/0, domain/0]).
   24: 
   25: %%--------------------------------------------------------------------
   26: %% Suite configuration
   27: %%--------------------------------------------------------------------
   28: 
   29: -define(NS_COMMANDS, <<"http://jabber.org/protocol/commands">>).
   30: 
   31: all() ->
   32:     [{group, disco_visible},
   33:      {group, adhoc}].
   34: 
   35: groups() ->
   36:     [{adhoc, [parallel], common_disco_cases() ++ hidden_disco_cases() ++ [ping]},
   37:      {disco_visible, [parallel], common_disco_cases() ++ visible_disco_cases()}].
   38: 
   39: common_disco_cases() ->
   40:     [disco_info,
   41:      disco_info_sm,
   42:      disco_info_commands,
   43:      disco_info_sm_commands,
   44:      disco_info_ping,
   45:      disco_items_commands].
   46: 
   47: hidden_disco_cases() ->
   48:     [disco_items_hidden,
   49:      disco_items_sm_hidden].
   50: 
   51: visible_disco_cases() ->
   52:     [disco_items_visible,
   53:      disco_items_sm_visible].
   54: 
   55: suite() ->
   56:     escalus:suite().
   57: 
   58: init_per_suite(Config) ->
   59:     escalus:init_per_suite(Config).
   60: 
   61: end_per_suite(Config) ->
   62:     escalus_fresh:clean(),
   63:     escalus:end_per_suite(Config).
   64: 
   65: init_per_group(GroupName, Config) ->
   66:     Config1 = init_modules(GroupName, Config),
   67:     escalus:create_users(Config1, escalus:get_users([alice, bob])).
   68: 
   69: end_per_group(GroupName, Config) ->
   70:     restore_modules(GroupName, Config),
   71:     escalus:delete_users(Config, escalus:get_users([alice, bob])).
   72: 
   73: init_per_testcase(CaseName, Config) ->
   74:     escalus:init_per_testcase(CaseName, Config).
   75: 
   76: end_per_testcase(CaseName, Config) ->
   77:     escalus:end_per_testcase(CaseName, Config).
   78: 
   79: init_modules(GroupName, Config) ->
   80:     Config1 = escalus:init_per_suite(dynamic_modules:save_modules(host_type(), Config)),
   81:     dynamic_modules:ensure_modules(host_type(), [{mod_adhoc, adhoc_opts(GroupName)}]),
   82:     Config1.
   83: 
   84: restore_modules(_GroupName, Config) ->
   85:     dynamic_modules:restore_modules(Config).
   86: 
   87: adhoc_opts(disco_visible) ->
   88:     #{iqdisc => one_queue, report_commands_node => true};
   89: adhoc_opts(_GroupName) ->
   90:     #{iqdisc => one_queue, report_commands_node => false}.
   91: 
   92: %%--------------------------------------------------------------------
   93: %% Adhoc tests
   94: %%--------------------------------------------------------------------
   95: 
   96: disco_info(Config) ->
   97:     escalus:fresh_story(Config, [{alice, 1}],
   98:         fun(Alice) ->
   99:                 Server = escalus_client:server(Alice),
  100:                 escalus:send(Alice, escalus_stanza:disco_info(Server)),
  101:                 Stanza = escalus:wait_for_stanza(Alice),
  102:                 escalus:assert(has_feature, [?NS_COMMANDS], Stanza),
  103:                 escalus:assert(is_stanza_from, [domain()], Stanza)
  104:         end).
  105: 
  106: disco_info_sm(Config) ->
  107:     escalus:fresh_story(Config, [{alice, 1}],
  108:         fun(Alice) ->
  109:                 AliceJid = escalus_client:short_jid(Alice),
  110:                 escalus:send(Alice, escalus_stanza:disco_info(AliceJid)),
  111:                 Stanza = escalus:wait_for_stanza(Alice),
  112:                 escalus:assert(has_feature, [?NS_COMMANDS], Stanza),
  113:                 escalus:assert(is_stanza_from, [AliceJid], Stanza)
  114:         end).
  115: 
  116: disco_info_commands(Config) ->
  117:     escalus:fresh_story(Config, [{alice, 1}],
  118:         fun(Alice) ->
  119:                 Server = escalus_client:server(Alice),
  120:                 escalus:send(Alice, escalus_stanza:disco_info(Server, ?NS_COMMANDS)),
  121:                 Stanza = escalus:wait_for_stanza(Alice),
  122:                 escalus:assert(has_identity, [<<"automation">>, <<"command-list">>], Stanza),
  123:                 escalus:assert(is_stanza_from, [domain()], Stanza)
  124:         end).
  125: 
  126: disco_info_sm_commands(Config) ->
  127:     escalus:fresh_story(Config, [{alice, 1}],
  128:         fun(Alice) ->
  129:                 AliceJid = escalus_client:short_jid(Alice),
  130:                 escalus:send(Alice, escalus_stanza:disco_info(AliceJid, ?NS_COMMANDS)),
  131:                 Stanza = escalus:wait_for_stanza(Alice),
  132:                 escalus:assert(has_identity, [<<"automation">>, <<"command-list">>], Stanza),
  133:                 escalus:assert(is_stanza_from, [AliceJid], Stanza)
  134:         end).
  135: 
  136: disco_info_ping(Config) ->
  137:     escalus:fresh_story(Config, [{alice, 1}],
  138:         fun(Alice) ->
  139:                 Server = escalus_client:server(Alice),
  140:                 escalus:send(Alice, escalus_stanza:disco_info(Server, <<"ping">>)),
  141:                 Stanza = escalus:wait_for_stanza(Alice),
  142:                 escalus:assert(has_identity, [<<"automation">>, <<"command-node">>], Stanza),
  143:                 escalus:assert(has_feature, [?NS_COMMANDS], Stanza),
  144:                 escalus:assert(is_stanza_from, [domain()], Stanza)
  145:         end).
  146: 
  147: disco_items_hidden(Config) ->
  148:     escalus:fresh_story(Config, [{alice, 1}],
  149:         fun(Alice) ->
  150:                 Server = escalus_client:server(Alice),
  151:                 escalus:send(Alice, escalus_stanza:disco_items(Server)),
  152:                 Stanza = escalus:wait_for_stanza(Alice),
  153:                 Query = exml_query:subelement(Stanza, <<"query">>),
  154:                 ?assertEqual(undefined,
  155:                              exml_query:subelement_with_attr(Query, <<"node">>, ?NS_COMMANDS)),
  156:                 escalus:assert(is_stanza_from, [domain()], Stanza)
  157:         end).
  158: 
  159: disco_items_sm_hidden(Config) ->
  160:     escalus:fresh_story(Config, [{alice, 1}],
  161:         fun(Alice) ->
  162:                 AliceJid = escalus_client:short_jid(Alice),
  163:                 escalus:send(Alice, escalus_stanza:disco_items(AliceJid)),
  164:                 Stanza = escalus:wait_for_stanza(Alice),
  165:                 Query = exml_query:subelement(Stanza, <<"query">>),
  166:                 ?assertEqual(undefined,
  167:                              exml_query:subelement_with_attr(Query, <<"node">>, ?NS_COMMANDS)),
  168:                 escalus:assert(is_stanza_from, [AliceJid], Stanza)
  169:         end).
  170: 
  171: disco_items_visible(Config) ->
  172:     escalus:fresh_story(Config, [{alice, 1}],
  173:         fun(Alice) ->
  174:                 Server = escalus_client:server(Alice),
  175:                 escalus:send(Alice, escalus_stanza:disco_items(Server)),
  176:                 Stanza = escalus:wait_for_stanza(Alice),
  177:                 Query = exml_query:subelement(Stanza, <<"query">>),
  178:                 Item = exml_query:subelement_with_attr(Query, <<"node">>, ?NS_COMMANDS),
  179:                 ?assertEqual(Server, exml_query:attr(Item, <<"jid">>)),
  180:                 escalus:assert(is_stanza_from, [domain()], Stanza)
  181:         end).
  182: 
  183: disco_items_sm_visible(Config) ->
  184:     escalus:fresh_story(Config, [{alice, 1}],
  185:         fun(Alice) ->
  186:                 AliceJid = escalus_client:short_jid(Alice),
  187:                 escalus:send(Alice, escalus_stanza:disco_items(AliceJid)),
  188:                 Stanza = escalus:wait_for_stanza(Alice),
  189:                 Query = exml_query:subelement(Stanza, <<"query">>),
  190:                 Item = exml_query:subelement_with_attr(Query, <<"node">>, ?NS_COMMANDS),
  191:                 ?assertEqual(AliceJid, exml_query:attr(Item, <<"jid">>)),
  192:                 escalus:assert(is_stanza_from, [AliceJid], Stanza)
  193:         end).
  194: 
  195: disco_items_commands(Config) ->
  196:     escalus:fresh_story(Config, [{alice, 1}],
  197:         fun(Alice) ->
  198:                 Server = escalus_client:server(Alice),
  199:                 escalus:send(Alice, escalus_stanza:disco_items(Server, ?NS_COMMANDS)),
  200:                 Stanza = escalus:wait_for_stanza(Alice),
  201:                 Query = exml_query:subelement(Stanza, <<"query">>),
  202:                 Item = exml_query:subelement_with_attr(Query, <<"node">>, <<"ping">>),
  203:                 ?assertEqual(Server, exml_query:attr(Item, <<"jid">>)),
  204:                 escalus:assert(is_stanza_from, [domain()], Stanza)
  205:         end).
  206: 
  207: ping(Config) ->
  208:     escalus:fresh_story(Config, [{alice, 1}],
  209:         fun(Alice) ->
  210:                 %% Alice pings the server using adhoc command
  211:                 escalus_client:send(Alice, escalus_stanza:to(
  212:                                              escalus_stanza:adhoc_request(<<"ping">>),
  213:                                              domain())),
  214:                 %% Server replies to Alice with pong
  215:                 AdHocResp = escalus_client:wait_for_stanza(Alice),
  216:                 escalus:assert(is_adhoc_response, [<<"ping">>, <<"completed">>],
  217:                                AdHocResp)
  218:         end).