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: 
   17: -module(shared_roster_SUITE).
   18: -compile([export_all, nowarn_export_all]).
   19: 
   20: -define(USERS, [alice, bob]).
   21: 
   22: -import(distributed_helper, [mim/0,
   23:                              require_rpc_nodes/1,
   24:                              rpc/4]).
   25: 
   26: -import(domain_helper, [host_type/0]).
   27: 
   28: %%--------------------------------------------------------------------
   29: %% Suite configuration
   30: %%--------------------------------------------------------------------
   31: 
   32: all() ->
   33:     [{group, shared_roster}].
   34: 
   35: groups() ->
   36:     G = [{shared_roster, [sequence], [receive_presences,
   37:                                       get_contacts,
   38:                                       delete_user,
   39:                                       add_user]}],
   40:     ct_helper:repeat_all_until_all_ok(G).
   41: 
   42: suite() ->
   43:     require_rpc_nodes([mim]) ++ escalus:suite().
   44: 
   45: %%--------------------------------------------------------------------
   46: %% Init & teardown
   47: %%--------------------------------------------------------------------
   48: 
   49: init_per_suite(Config0) ->
   50:     Config = dynamic_modules:save_modules(host_type(), Config0),
   51:     case get_auth_method() of
   52:         ldap ->
   53:             start_roster_module(ldap),
   54:             escalus:init_per_suite([{escalus_user_db, {module, ldap_helper}},
   55:                                     {ldap_auth, true} | Config]);
   56:         _ ->
   57:             escalus:init_per_suite([{ldap_auth, false} | Config])
   58:     end.
   59: 
   60: end_per_suite(Config) ->
   61:     dynamic_modules:restore_modules(Config),
   62:     escalus:end_per_suite(Config).
   63: 
   64: init_per_group(_, Config) ->
   65:     escalus:create_users(Config, escalus:get_users(?USERS)).
   66: 
   67: end_per_group(_, Config) ->
   68:     escalus:delete_users(Config, escalus:get_users(?USERS)).
   69: 
   70: init_per_testcase(CaseName,Config) ->
   71:     case proplists:get_value(ldap_auth, Config) of
   72:         false ->
   73:             {skip, no_shared_roster_available};
   74:         _ ->
   75:             escalus:init_per_testcase(CaseName,Config)
   76:     end.
   77: 
   78: end_per_testcase(CaseName,Config) ->
   79:     escalus:end_per_testcase(CaseName,Config).
   80: 
   81: %%--------------------------------------------------------------------
   82: %% Tests
   83: %%--------------------------------------------------------------------
   84: 
   85: %% Receive presences from roster people
   86: receive_presences(Config) ->
   87:     escalus:story(Config,[{alice, 1}],fun(Alice) ->
   88:         % Bob becomes available
   89:         {ok, Bob} = escalus_client:start_for(Config, bob, <<"res1">>),
   90:         escalus:send(Bob, escalus_stanza:presence(<<"available">>)),
   91: 
   92:         % Alice receives presence from Bob
   93:         ReceivedA = escalus:wait_for_stanza(Alice),
   94:         escalus:assert(is_presence,ReceivedA),
   95:         escalus_assert:is_stanza_from(Bob,ReceivedA),
   96: 
   97:         no_stanzas([Alice]),
   98:         escalus_client:stop(Config, Bob)
   99:     end).
  100: 
  101: get_contacts(Config) ->
  102:     escalus:story(Config,[{alice, 1}],fun(Alice) ->
  103:         % Alice sends get_roster iq
  104:         escalus_client:send(Alice, escalus_stanza:roster_get()),
  105:         Roster=escalus_client:wait_for_stanza(Alice),
  106: 
  107:         % Roster contains all created users excluding Alice
  108:         escalus:assert(is_roster_result,Roster),
  109:         NumOfOtherUsers = length(escalus_users:get_users(?USERS))-1,
  110:         escalus:assert(count_roster_items,[NumOfOtherUsers],Roster)
  111:     end).
  112: 
  113: delete_user(Config) ->
  114:     NumOfOtherUsers = length(escalus_users:get_users(?USERS)) - 2,
  115:     %% wait to invalidate the roster group cache
  116:     timer:sleep(1200),
  117:     escalus:delete_users(Config, escalus:get_users([bob])),
  118:     escalus:story(Config, [{alice, 1}], fun(Alice) ->
  119:         escalus_client:send(Alice, escalus_stanza:roster_get()),
  120:         Roster=escalus_client:wait_for_stanza(Alice),
  121: 
  122:         escalus:assert(is_roster_result, Roster),
  123:         escalus:assert(count_roster_items, [NumOfOtherUsers], Roster)
  124:     end).
  125: 
  126: add_user(Config) ->
  127:     escalus:create_users(Config, escalus:get_users([bob])),
  128:     timer:sleep(1200),
  129:     escalus:story(Config, [{alice, 1}], fun(Alice) ->
  130:         NumOfOtherUsers = length(escalus_users:get_users(?USERS)) - 1,
  131: 
  132:         escalus_client:send(Alice, escalus_stanza:roster_get()),
  133:         Roster=escalus_client:wait_for_stanza(Alice),
  134: 
  135:         escalus:assert(is_roster_result, Roster),
  136:         escalus:assert(count_roster_items, [NumOfOtherUsers], Roster)
  137:     end).
  138: 
  139: %%--------------------------------------------------------------------
  140: %% Helpers
  141: %%--------------------------------------------------------------------
  142: 
  143: start_roster_module(ldap) ->
  144:     dynamic_modules:ensure_modules(host_type(), [{mod_shared_roster_ldap, get_ldap_opts()}]);
  145: start_roster_module(_) ->
  146:     ok.
  147: 
  148: get_auth_method() ->
  149:     HT = host_type(),
  150:     case rpc(mim(), mongoose_config, get_opt, [[{auth, HT}, methods], []]) of
  151:         [Method|_] ->
  152:             Method;
  153:         _ ->
  154:             none
  155:     end.
  156: 
  157: get_ldap_opts() ->
  158:     Opts = #{base => <<"ou=Users,dc=esl,dc=com">>,
  159:              groupattr => <<"ou">>,
  160:              memberattr => <<"cn">>,
  161:              userdesc => <<"cn">>,
  162:              filter => <<"(objectClass=inetOrgPerson)">>,
  163:              rfilter => <<"(objectClass=inetOrgPerson)">>,
  164:              group_cache_validity => 1,
  165:              user_cache_validity => 1},
  166:     maps:merge(config_parser_helper:default_mod_config(mod_shared_roster_ldap), Opts).
  167: 
  168: no_stanzas(Users) ->
  169:     lists:foreach(fun escalus_assert:has_no_stanzas/1, Users).