1: %%%------------------------------------------------------------------- 2: %%% @author bartek 3: %%% @copyright (C) 2017, <COMPANY> 4: %%% @doc 5: %%% 6: %%% @end 7: %%% Created : 21. Apr 2017 16:09 8: %%%------------------------------------------------------------------- 9: -module(roster_SUITE). 10: -author("bartek"). 11: 12: -include_lib("eunit/include/eunit.hrl"). 13: -include("ejabberd_c2s.hrl"). 14: -include("mongoose.hrl"). 15: -include_lib("exml/include/exml_stream.hrl"). 16: -include_lib("mod_roster.hrl"). 17: -compile([export_all, nowarn_export_all]). 18: 19: -define(_eq(E, I), ?_assertEqual(E, I)). 20: -define(eq(E, I), ?assertEqual(E, I)). 21: -define(am(E, I), ?assertMatch(E, I)). 22: -define(ne(E, I), ?assert(E =/= I)). 23: 24: -define(ACC_PARAMS, #{location => ?LOCATION, 25: lserver => domain(), 26: host_type => host_type(), 27: element => undefined}). 28: 29: -define(HOST_TYPE, <<"test type">>). 30: 31: all() -> [ 32: roster_old, 33: roster_old_with_filter, 34: roster_new, 35: roster_case_insensitive 36: ]. 37: 38: init_per_suite(C) -> 39: ok = mnesia:create_schema([node()]), 40: ok = mnesia:start(), 41: {ok, _} = application:ensure_all_started(jid), 42: {ok, _} = application:ensure_all_started(exometer_core), 43: meck:new(gen_iq_handler, [no_link]), 44: meck:expect(gen_iq_handler, add_iq_handler_for_domain, fun(_, _, _, _, _, _) -> ok end), 45: meck:expect(gen_iq_handler, remove_iq_handler_for_domain, fun(_, _, _) -> ok end), 46: meck:new(mongoose_domain_api, [no_link]), 47: meck:expect(mongoose_domain_api, get_domain_host_type, fun(_) -> {ok, host_type()} end), 48: [mongoose_config:set_opt(Key, Value) || {Key, Value} <- opts()], 49: C. 50: 51: end_per_suite(C) -> 52: [mongoose_config:unset_opt(Key) || {Key, _Value} <- opts()], 53: meck:unload(), 54: mnesia:stop(), 55: mnesia:delete_schema([node()]), 56: C. 57: 58: opts() -> 59: [{hosts, []}, 60: {all_metrics_are_global, false}]. 61: 62: init_per_testcase(_TC, C) -> 63: init_ets(), 64: gen_hook:start_link(), 65: gen_mod:start(), 66: gen_mod:start_module(host_type(), mod_roster, []), 67: C. 68: 69: end_per_testcase(_TC, C) -> 70: Acc = mongoose_acc:new(?ACC_PARAMS), 71: mod_roster:remove_user(Acc, a(), domain()), 72: gen_mod:stop_module(host_type(), mod_roster), 73: delete_ets(), 74: C. 75: 76: 77: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78: %%%%%%%%%%%%%%%%%%%%%%%%%%% TESTS %%%%%%%%%%%%%%%%%%%%%%% 79: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 80: 81: 82: roster_old(_C) -> 83: R1 = get_roster_old(), 84: ?assertEqual(length(R1), 0), 85: ok = mod_roster:set_items(host_type(), alice_jid(), addbob_stanza()), 86: assert_state_old(none, none), 87: subscription(out, subscribe), 88: assert_state_old(none, out), 89: ok. 90: 91: roster_old_with_filter(_C) -> 92: R1 = get_roster_old(), 93: ?assertEqual(0, length(R1)), 94: ok = mod_roster:set_items(host_type(), alice_jid(), addbob_stanza()), 95: assert_state_old(none, none), 96: subscription(in, subscribe), 97: R2 = get_roster_old(), 98: ?assertEqual(0, length(R2)), 99: R3 = get_full_roster(), 100: ?assertEqual(1, length(R3)), 101: ok. 102: 103: roster_new(_C) -> 104: R1 = mod_roster:get_roster_entry(host_type(), alice_jid(), bob_ljid(), short), 105: ?assertEqual(does_not_exist, R1), 106: ok = mod_roster:set_items(host_type(), alice_jid(), addbob_stanza()), 107: assert_state_old(none, none), 108: ct:pal("get_roster_old(): ~p", [get_roster_old()]), 109: R2 = mod_roster:get_roster_entry(host_type(), alice_jid(), bob_ljid(), short), 110: ?assertMatch(#roster{}, R2), % is not guaranteed to contain full info 111: R3 = mod_roster:get_roster_entry(host_type(), alice_jid(), bob_ljid(), full), 112: assert_state(R3, none, none, [<<"friends">>]), 113: subscription(out, subscribe), 114: R4 = mod_roster:get_roster_entry(host_type(), alice_jid(), bob_ljid(), full), 115: assert_state(R4, none, out, [<<"friends">>]). 116: 117: 118: roster_case_insensitive(_C) -> 119: ok = mod_roster:set_items(host_type(), alice_jid(), addbob_stanza()), 120: R1 = get_roster_old(), 121: ?assertEqual(1, length(R1)), 122: R2 = get_roster_old(ae()), 123: ?assertEqual(1, length(R2)), 124: R3 = mod_roster:get_roster_entry(host_type(), alice_jid(), bob_ljid(), full), 125: assert_state(R3, none, none, [<<"friends">>]), 126: R3 = mod_roster:get_roster_entry(host_type(), alicE_jid(), bob_ljid(), full), 127: assert_state(R3, none, none, [<<"friends">>]), 128: ok. 129: 130: 131: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 132: %%%%%%%%%%%%%%%%%%%%%%%%%% HELPERS %%%%%%%%%%%%%%%%%%%%%% 133: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 134: 135: assert_state(Rentry, Subscription, Ask, Groups) -> 136: ?assertEqual(Subscription, Rentry#roster.subscription), 137: ?assertEqual(Ask, Rentry#roster.ask), 138: ?assertEqual(Groups, Rentry#roster.groups). 139: 140: subscription(Direction, Type) -> 141: TFun = fun() -> 142: mod_roster:process_subscription_t(host_type(), Direction, alice_jid(), 143: bob_jid(), Type, <<>>) 144: end, 145: {atomic, _} = mod_roster:transaction(host_type(), TFun). 146: 147: get_roster_old() -> 148: get_roster_old(a()). 149: 150: get_roster_old(User) -> 151: Acc = mongoose_acc:new(?ACC_PARAMS), 152: Acc1 = mod_roster:get_user_roster(Acc, jid:make(User, domain(), <<>>)), 153: mongoose_acc:get(roster, items, Acc1). 154: 155: get_full_roster() -> 156: Acc0 = mongoose_acc:new(?ACC_PARAMS), 157: Acc1 = mongoose_acc:set(roster, show_full_roster, true, Acc0), 158: Acc2 = mod_roster:get_user_roster(Acc1, alice_jid()), 159: mongoose_acc:get(roster, items, Acc2). 160: 161: assert_state_old(Subscription, Ask) -> 162: [Rentry] = get_roster_old(), 163: ?assertEqual(Subscription, Rentry#roster.subscription), 164: ?assertEqual(Ask, Rentry#roster.ask). 165: 166: init_ets() -> 167: catch ets:new(mongoose_services, [named_table]), 168: ok. 169: 170: delete_ets() -> 171: catch ets:delete(mongoose_services), 172: ok. 173: 174: alice_jid() -> 175: jid:make(a(), domain(), <<>>). 176: 177: alicE_jid() -> 178: jid:make(ae(), domain(), <<>>). 179: 180: a() -> <<"alice">>. 181: ae() -> <<"alicE">>. 182: 183: domain() -> <<"localhost">>. 184: 185: bob() -> <<"bob@localhost">>. 186: 187: bob_jid() -> 188: jid:make(<<"bob">>, domain(), <<>>). 189: 190: bob_ljid() -> 191: jid:to_lower(bob_jid()). 192: 193: host_type() -> <<"test type">>. 194: 195: addbob_stanza() -> 196: #xmlel{children = [ 197: #xmlel{ 198: attrs = [{<<"jid">>, bob()}], 199: children = [ 200: #xmlel{name = <<"group">>, 201: children = [ 202: #xmlcdata{content = <<"friends">>} 203: ]} 204: ]} 205: ] 206: }.