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