Skip to content

Commit

Permalink
Implement forget_room
Browse files Browse the repository at this point in the history
  • Loading branch information
NelsonVides committed Feb 15, 2022
1 parent a5d19a0 commit bf93c2c
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 13 deletions.
92 changes: 83 additions & 9 deletions big_tests/tests/smart_markers_SUITE.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
-module(smart_markers_SUITE).
-compile([export_all, nowarn_export_all]).

-include("muc_light.hrl").

-import(distributed_helper, [mim/0, rpc/4, subhost_pattern/1]).
-import(domain_helper, [host_type/0]).

Expand All @@ -14,7 +16,8 @@ all() ->

all_cases() ->
[
{group, one2one}
{group, one2one},
{group, muclight}
].

groups() ->
Expand All @@ -23,27 +26,41 @@ groups() ->
[
marker_is_stored,
remove_markers_when_removed_user
]},
{muclight, [],
[
marker_is_stored_for_room,
markers_are_removed_when_room_is_removed
]}
].

suite() ->
escalus:suite().

init_per_suite(Config0) ->
HostType = host_type(),
Config1 = dynamic_modules:save_modules(HostType, Config0),
dynamic_modules:ensure_modules(HostType, [{mod_smart_markers, [{backend, rdbms}]}]),
escalus:init_per_suite(Config1).
init_per_suite(Config) ->
escalus:init_per_suite(Config).

end_per_suite(Config) ->
escalus_fresh:clean(),
dynamic_modules:restore_modules(Config),
escalus:end_per_suite(Config).

init_per_group(_, Config) ->
init_per_group(GroupName, Config) ->
ok = dynamic_modules:ensure_modules(host_type(), group_to_module(GroupName)),
Config.

group_to_module(one2one) ->
[{mod_smart_markers, [{backend, rdbms}]}];
group_to_module(muclight) ->
[{mod_smart_markers, [{backend, rdbms}]},
{mod_muc_light,
[{host, subhost_pattern(muc_light_helper:muc_host_pattern())},
{backend, rdbms}]}].

end_per_group(muclight, Config) ->
muc_light_helper:clear_db(host_type()),
end_per_group(generic, Config);
end_per_group(_, Config) ->
escalus_fresh:clean(),
dynamic_modules:restore_modules(Config),
Config.

init_per_testcase(Name, Config) ->
Expand Down Expand Up @@ -78,12 +95,69 @@ remove_markers_when_removed_user(Config) ->
mongoose_helper:wait_until(fun() -> length(fetch_markers_for_users(BobJid, AliceJid)) end, 0)
end).

marker_is_stored_for_room(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}, {kate, 1}],
fun(Alice, Bob, Kate) ->
Users = [Alice, Bob, Kate],
RoomId = create_room(Alice, [Bob, Kate], Config),
RoomBinJid = muc_light_helper:room_bin_jid(RoomId),
one_marker_in_room(Users, RoomBinJid, Alice, Bob),
BobJid = jid:from_binary(escalus_client:full_jid(Bob)),
mongoose_helper:wait_until(
fun() -> length(fetch_markers_for_users(BobJid, jid:from_binary(RoomBinJid))) > 0 end, true)
end).

markers_are_removed_when_room_is_removed(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) ->
Users = [Alice, Bob],
RoomId = create_room(Alice, [Bob], Config),
RoomBinJid = muc_light_helper:room_bin_jid(RoomId),
RoomJid = jid:from_binary(RoomBinJid),
one_marker_in_room(Users, RoomBinJid, Alice, Bob),
BobJid = jid:from_binary(escalus_client:full_jid(Bob)),
mongoose_helper:wait_until(
fun() -> length(fetch_markers_for_users(BobJid, RoomJid)) > 0 end, true),
%% The room is then deleted
delete_room(Alice, Users, RoomBinJid),
[ begin
Jid = jid:from_binary(escalus_client:full_jid(User)),
mongoose_helper:wait_until(
fun() -> length(fetch_markers_for_users(Jid, RoomJid)) end, 0)
end || User <- Users]
end).

%%% helpers
fetch_markers_for_users(From, To) ->
MRs = rpc(mim(), mod_smart_markers_backend, get_chat_markers,
[host_type(), To, undefined, 0]),
[MR || #{from := FR} = MR <- MRs, jid:are_bare_equal(From, FR)].

create_room(Owner, Members, Config) ->
RoomId = muc_helper:fresh_room_name(),
MucHost = muc_light_helper:muc_host(),
muc_light_helper:create_room(RoomId, MucHost, Owner, Members, Config, muc_light_helper:ver(1)),
RoomId.

delete_room(Owner, Users, RoomBinJid) ->
Destroy = escalus_stanza:to(escalus_stanza:iq_set(?NS_MUC_LIGHT_DESTROY, []), RoomBinJid),
escalus:send(Owner, Destroy),
AffUsersChanges = [{User, none} || User <- Users ],
muc_light_helper:verify_aff_bcast([], AffUsersChanges, [?NS_MUC_LIGHT_DESTROY]),
escalus:assert(is_iq_result, escalus:wait_for_stanza(Owner)).

one_marker_in_room(Users, RoomBinJid, Writer, Marker) ->
MsgId = escalus_stanza:id(),
Msg = escalus_stanza:set_id(
escalus_stanza:groupchat_to(RoomBinJid, <<"Hello">>), MsgId),
escalus:send(Writer, Msg),
[ escalus:wait_for_stanza(User) || User <- Users],
ChatMarker = escalus_stanza:setattr(
escalus_stanza:chat_marker(RoomBinJid, <<"displayed">>, MsgId),
<<"type">>, <<"groupchat">>),
escalus:send(Marker, ChatMarker),
[ escalus:wait_for_stanza(User) || User <- Users],
MsgId.

send_message_respond_marker(MsgWriter, MarkerAnswerer) ->
Body = <<"Hello">>,
MsgId = escalus_stanza:id(),
Expand Down
14 changes: 11 additions & 3 deletions src/smart_markers/mod_smart_markers.erl
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@
-export([get_chat_markers/3]).

%% Hook handlers
-export([user_send_packet/4, remove_user/3, remove_domain/3]).
-ignore_xref([user_send_packet/4, remove_user/3, remove_domain/3]).
-export([user_send_packet/4, remove_user/3, remove_domain/3, forget_room/4]).
-ignore_xref([user_send_packet/4, remove_user/3, remove_domain/3, forget_room/4]).

%%--------------------------------------------------------------------
%% Type declarations
Expand Down Expand Up @@ -110,7 +110,9 @@ supported_features() ->
hooks(HostType) ->
[{user_send_packet, HostType, ?MODULE, user_send_packet, 90},
{remove_user, HostType, ?MODULE, remove_user, 60},
{remove_domain, HostType, ?MODULE, remove_domain, 60}].
{remove_domain, HostType, ?MODULE, remove_domain, 60},
{forget_room, HostType, ?MODULE, forget_room, 85}
].

-spec user_send_packet(mongoose_acc:t(), jid:jid(), jid:jid(), exml:element()) ->
mongoose_acc:t().
Expand All @@ -135,6 +137,12 @@ remove_domain(Acc, HostType, Domain) ->
mod_smart_markers_backend:remove_domain(HostType, Domain),
Acc.

-spec forget_room(mongoose_hooks:simple_acc(), mongooseim:host_type(), jid:lserver(), jid:luser()) ->
mongoose_hooks:simple_acc().
forget_room(Acc, HostType, RoomS, RoomU) ->
mod_smart_markers_backend:remove_to(HostType, jid:make_noprep(RoomU, RoomS, <<>>)),
Acc.

%%--------------------------------------------------------------------
%% Other API
%%--------------------------------------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions src/smart_markers/mod_smart_markers_backend.erl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
-export([get_chat_markers/4]).
-export([remove_domain/2]).
-export([remove_user/2]).
-export([remove_to/2]).

%%--------------------------------------------------------------------
%% DB backend behaviour definition
Expand All @@ -31,6 +32,8 @@

-callback remove_user(mongooseim:host_type(), jid:jid()) -> term().

-callback remove_to(mongooseim:host_type(), jid:jid()) -> term().

-spec init(mongooseim:host_type(), gen_mod:module_opts()) -> ok.
init(HostType, Opts) ->
FOpts = add_default_backend(Opts),
Expand Down Expand Up @@ -65,6 +68,14 @@ remove_user(HostType, User) ->
Args = [HostType, User],
mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args).

%% @doc remove all markers a user was ever sent
%% Useful for example for `forget_room', when we need to drop all knowledge
%% other users had of this room
-spec remove_to(mongooseim:host_type(), jid:jid()) -> term().
remove_to(HostType, To) ->
Args = [HostType, To],
mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args).

add_default_backend(Opts) ->
case lists:keyfind(backend, 2, Opts) of
false -> [{backend, rdbms} | Opts];
Expand Down
8 changes: 7 additions & 1 deletion src/smart_markers/mod_smart_markers_rdbms.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
-include("jlib.hrl").

-export([init/2, update_chat_marker/2, get_chat_markers/4]).
-export([remove_domain/2, remove_user/2]).
-export([remove_domain/2, remove_user/2, remove_to/2]).

%%--------------------------------------------------------------------
%% API
Expand All @@ -31,6 +31,8 @@ init(HostType, _) ->
[lserver], <<"DELETE FROM smart_markers WHERE lserver=?">>),
mongoose_rdbms:prepare(markers_remove_user, smart_markers,
[lserver, from_luser], <<"DELETE FROM smart_markers WHERE lserver=? AND from_luser=?">>),
mongoose_rdbms:prepare(markers_remove_to, smart_markers,
[to_jid], <<"DELETE FROM smart_markers WHERE to_jid=?">>),
ok.

%%% @doc
Expand Down Expand Up @@ -83,6 +85,10 @@ remove_domain(HostType, Domain) ->
remove_user(HostType, #jid{luser = LU, lserver = LS}) ->
mongoose_rdbms:execute_successfully(HostType, markers_remove_user, [LS, LU]).

-spec remove_to(mongooseim:host_type(), jid:jid()) -> mongoose_rdbms:query_result().
remove_to(HostType, To) ->
mongoose_rdbms:execute_successfully(HostType, markers_remove_to, [encode_jid(To)]).

%%--------------------------------------------------------------------
%% local functions
%%--------------------------------------------------------------------
Expand Down

0 comments on commit bf93c2c

Please sign in to comment.