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:     gen_hook:start_link(),
   27:     C.
   28: 
   29: end_per_suite(_C) ->
   30:     mnesia:stop(),
   31:     mnesia:delete_schema([node()]),
   32:     meck:unload(),
   33:     [mongoose_config:unset_opt(Key) || {Key, _Value} <- opts()],
   34:     ok.
   35: 
   36: opts() ->
   37:     [{all_metrics_are_global, false},
   38:      {routing_modules, [xmpp_router_a, xmpp_router_b, xmpp_router_c]}].
   39: 
   40: registering(_C) ->
   41:     Dom = <<"aaa.bbb.com">>,
   42:     ejabberd_router:register_component(Dom, mongoose_packet_handler:new(?MODULE)),
   43:     Lookup = ejabberd_router:lookup_component(Dom),
   44:     ?assertMatch([#external_component{}], Lookup),
   45:     ejabberd_router:unregister_component(Dom),
   46:     ?assertMatch([], ejabberd_router:lookup_component(Dom)),
   47:     ok.
   48: 
   49: registering_with_local(_C) ->
   50:     gen_hook:start_link(),
   51:     Dom = <<"aaa.bbb.com">>,
   52:     ThisNode = node(),
   53:     AnotherNode = 'another@nohost',
   54:     Handler = mongoose_packet_handler:new(?MODULE), %% This handler is only for testing!
   55:     ejabberd_router:register_component(Dom, Handler),
   56:     %% we can find it globally
   57:     ?assertMatch([#external_component{node = ThisNode}], ejabberd_router:lookup_component(Dom)),
   58:     %% and for this node
   59:     ?assertMatch([#external_component{node = ThisNode}],
   60:                  ejabberd_router:lookup_component(Dom, ThisNode)),
   61:     %% but not for another node
   62:     ?assertMatch([], ejabberd_router:lookup_component(Dom, AnotherNode)),
   63:     %% once we unregister it is not available
   64:     ejabberd_router:unregister_component(Dom),
   65:     ?assertMatch([], ejabberd_router:lookup_component(Dom)),
   66:     ?assertMatch([], ejabberd_router:lookup_component(Dom, ThisNode)),
   67:     ?assertMatch([], ejabberd_router:lookup_component(Dom, AnotherNode)),
   68:     %% we can register from both nodes
   69:     ejabberd_router:register_component(Dom, ThisNode, Handler),
   70:     %% passing node here is only for testing
   71:     ejabberd_router:register_component(Dom, AnotherNode, Handler),
   72:     %% both are reachable locally
   73:     ?assertMatch([#external_component{node = ThisNode}],
   74:                  ejabberd_router:lookup_component(Dom, ThisNode)),
   75:     ?assertMatch([#external_component{node = AnotherNode}],
   76:                  ejabberd_router:lookup_component(Dom, AnotherNode)),
   77:     %% if we try global lookup we get two handlers
   78:     ?assertMatch([_, _], ejabberd_router:lookup_component(Dom)),
   79:     %% we unregister one and the result is:
   80:     ejabberd_router:unregister_component(Dom),
   81:     ?assertMatch([], ejabberd_router:lookup_component(Dom, ThisNode)),
   82:     ?assertMatch([#external_component{node = AnotherNode}],
   83:                  ejabberd_router:lookup_component(Dom)),
   84:     ?assertMatch([#external_component{node = AnotherNode}],
   85:                  ejabberd_router:lookup_component(Dom, AnotherNode)),
   86:     ok.
   87: 
   88: process_packet(_From, _To, _Packet, _Extra) ->
   89:     exit(process_packet_called).