1: -module(component_reg_SUITE).
    2: -compile([export_all, nowarn_export_all]).
    3: 
    4: -include_lib("exml/include/exml.hrl").
    5: -include_lib("eunit/include/eunit.hrl").
    6: -include("mongoose.hrl").
    7: -include("external_component.hrl").
    8: 
    9: all() ->
   10:     [ registering, registering_with_local ].
   11: 
   12: init_per_suite(C) ->
   13:     {ok, _} = application:ensure_all_started(jid),
   14:     ok = mnesia:create_schema([node()]),
   15:     ok = mnesia:start(),
   16:     [mongoose_config:set_opt(Key, Value) || {Key, Value} <- opts()],
   17:     meck:new(mongoose_domain_api, [no_link]),
   18:     meck:expect(mongoose_domain_api, get_host_type,
   19:                 fun(_) -> {error, not_found} end),
   20:     application:ensure_all_started(exometer_core),
   21:     gen_hook:start_link(),
   22:     ejabberd_router:start_link(),
   23:     C.
   24: 
   25: init_per_testcase(_, C) ->
   26:     mongoose_router:start(),
   27:     gen_hook:start_link(),
   28:     C.
   29: 
   30: end_per_suite(_C) ->
   31:     mnesia:stop(),
   32:     mnesia:delete_schema([node()]),
   33:     meck:unload(),
   34:     [mongoose_config:unset_opt(Key) || {Key, _Value} <- opts()],
   35:     ok.
   36: 
   37: opts() ->
   38:     [{all_metrics_are_global, false},
   39:      {routing_modules, [xmpp_router_a, xmpp_router_b, xmpp_router_c]}].
   40: 
   41: registering(_C) ->
   42:     Dom = <<"aaa.bbb.com">>,
   43:     ejabberd_router:register_component(Dom, mongoose_packet_handler:new(?MODULE)),
   44:     Lookup = ejabberd_router:lookup_component(Dom),
   45:     ?assertMatch([#external_component{}], Lookup),
   46:     ejabberd_router:unregister_component(Dom),
   47:     ?assertMatch([], ejabberd_router:lookup_component(Dom)),
   48:     ok.
   49: 
   50: registering_with_local(_C) ->
   51:     gen_hook:start_link(),
   52:     Dom = <<"aaa.bbb.com">>,
   53:     ThisNode = node(),
   54:     AnotherNode = 'another@nohost',
   55:     Handler = mongoose_packet_handler:new(?MODULE), %% This handler is only for testing!
   56:     ejabberd_router:register_component(Dom, Handler),
   57:     %% we can find it globally
   58:     ?assertMatch([#external_component{node = ThisNode}], ejabberd_router:lookup_component(Dom)),
   59:     %% and for this node
   60:     ?assertMatch([#external_component{node = ThisNode}],
   61:                  ejabberd_router:lookup_component(Dom, ThisNode)),
   62:     %% but not for another node
   63:     ?assertMatch([], ejabberd_router:lookup_component(Dom, AnotherNode)),
   64:     %% once we unregister it is not available
   65:     ejabberd_router:unregister_component(Dom),
   66:     ?assertMatch([], ejabberd_router:lookup_component(Dom)),
   67:     ?assertMatch([], ejabberd_router:lookup_component(Dom, ThisNode)),
   68:     ?assertMatch([], ejabberd_router:lookup_component(Dom, AnotherNode)),
   69:     %% we can register from both nodes
   70:     ejabberd_router:register_component(Dom, ThisNode, Handler),
   71:     %% passing node here is only for testing
   72:     ejabberd_router:register_component(Dom, AnotherNode, Handler),
   73:     %% both are reachable locally
   74:     ?assertMatch([#external_component{node = ThisNode}],
   75:                  ejabberd_router:lookup_component(Dom, ThisNode)),
   76:     ?assertMatch([#external_component{node = AnotherNode}],
   77:                  ejabberd_router:lookup_component(Dom, AnotherNode)),
   78:     %% if we try global lookup we get two handlers
   79:     ?assertMatch([_, _], ejabberd_router:lookup_component(Dom)),
   80:     %% we unregister one and the result is:
   81:     ejabberd_router:unregister_component(Dom),
   82:     ?assertMatch([], ejabberd_router:lookup_component(Dom, ThisNode)),
   83:     ?assertMatch([#external_component{node = AnotherNode}],
   84:                  ejabberd_router:lookup_component(Dom)),
   85:     ?assertMatch([#external_component{node = AnotherNode}],
   86:                  ejabberd_router:lookup_component(Dom, AnotherNode)),
   87:     ok.
   88: 
   89: process_packet(_From, _To, _Packet, _Extra) ->
   90:     exit(process_packet_called).