refactor progress
This commit is contained in:
@@ -21,123 +21,533 @@
|
||||
is_guild_unavailable_for_user/2,
|
||||
is_user_staff/2,
|
||||
check_unavailability_transition/2,
|
||||
handle_unavailability_transition/2
|
||||
handle_unavailability_transition/2,
|
||||
get_cached_unavailability_mode/1,
|
||||
is_guild_unavailable_for_user_from_cache/2,
|
||||
update_unavailability_cache_for_state/1
|
||||
]).
|
||||
|
||||
-import(guild_permissions, [find_member_by_user_id/2]).
|
||||
-import(guild_data, [get_guild_state/2]).
|
||||
-type guild_state() :: map().
|
||||
-type user_id() :: integer().
|
||||
-type guild_id() :: integer().
|
||||
-type unavailability_mode() ::
|
||||
available
|
||||
| unavailable_for_everyone
|
||||
| unavailable_for_everyone_but_staff.
|
||||
-type transition_result() :: {unavailable_enabled, boolean()} | unavailable_disabled | no_change.
|
||||
|
||||
-define(GUILD_UNAVAILABILITY_CACHE, guild_unavailability_cache).
|
||||
-define(STAFF_USER_FLAG, 16#1).
|
||||
|
||||
-ifdef(TEST).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-endif.
|
||||
|
||||
-spec is_guild_unavailable_for_user(user_id(), guild_state()) -> boolean().
|
||||
is_guild_unavailable_for_user(UserId, State) ->
|
||||
Data = maps:get(data, State),
|
||||
Guild = maps:get(<<"guild">>, Data),
|
||||
Features = maps:get(<<"features">>, Guild, []),
|
||||
|
||||
HasUnavailableForEveryone = lists:member(<<"UNAVAILABLE_FOR_EVERYONE">>, Features),
|
||||
HasUnavailableForEveryoneButStaff =
|
||||
lists:member(<<"UNAVAILABLE_FOR_EVERYONE_BUT_STAFF">>, Features),
|
||||
|
||||
case {HasUnavailableForEveryone, HasUnavailableForEveryoneButStaff} of
|
||||
{true, _} ->
|
||||
case get_unavailability_mode_from_state(State) of
|
||||
unavailable_for_everyone ->
|
||||
true;
|
||||
{false, true} ->
|
||||
unavailable_for_everyone_but_staff ->
|
||||
not is_user_staff(UserId, State);
|
||||
{false, false} ->
|
||||
available ->
|
||||
false
|
||||
end.
|
||||
|
||||
-spec is_user_staff(user_id(), guild_state()) -> boolean().
|
||||
is_user_staff(UserId, State) ->
|
||||
case find_member_by_user_id(UserId, State) of
|
||||
undefined ->
|
||||
case is_user_staff_from_sessions(UserId, State) of
|
||||
true ->
|
||||
true;
|
||||
false ->
|
||||
false;
|
||||
Member ->
|
||||
User = maps:get(<<"user">>, Member, #{}),
|
||||
Flags = utils:binary_to_integer_safe(maps:get(<<"flags">>, User, <<"0">>)),
|
||||
(Flags band 16#1) =:= 16#1
|
||||
end.
|
||||
|
||||
check_unavailability_transition(OldState, NewState) ->
|
||||
OldData = maps:get(data, OldState),
|
||||
OldGuild = maps:get(<<"guild">>, OldData),
|
||||
OldFeatures = maps:get(<<"features">>, OldGuild, []),
|
||||
|
||||
NewData = maps:get(data, NewState),
|
||||
NewGuild = maps:get(<<"guild">>, NewData),
|
||||
NewFeatures = maps:get(<<"features">>, NewGuild, []),
|
||||
|
||||
OldUnavailableForEveryone = lists:member(<<"UNAVAILABLE_FOR_EVERYONE">>, OldFeatures),
|
||||
NewUnavailableForEveryone = lists:member(<<"UNAVAILABLE_FOR_EVERYONE">>, NewFeatures),
|
||||
|
||||
OldUnavailableForEveryoneButStaff =
|
||||
lists:member(<<"UNAVAILABLE_FOR_EVERYONE_BUT_STAFF">>, OldFeatures),
|
||||
NewUnavailableForEveryoneButStaff =
|
||||
lists:member(<<"UNAVAILABLE_FOR_EVERYONE_BUT_STAFF">>, NewFeatures),
|
||||
|
||||
OldIsUnavailable = OldUnavailableForEveryone orelse OldUnavailableForEveryoneButStaff,
|
||||
NewIsUnavailable = NewUnavailableForEveryone orelse NewUnavailableForEveryoneButStaff,
|
||||
|
||||
case {OldIsUnavailable, NewIsUnavailable} of
|
||||
{false, true} ->
|
||||
{unavailable_enabled, NewUnavailableForEveryoneButStaff};
|
||||
{true, false} ->
|
||||
unavailable_disabled;
|
||||
_ ->
|
||||
case
|
||||
{OldUnavailableForEveryoneButStaff, NewUnavailableForEveryoneButStaff,
|
||||
OldUnavailableForEveryone, NewUnavailableForEveryone}
|
||||
of
|
||||
{true, false, false, true} ->
|
||||
{unavailable_enabled, false};
|
||||
{false, true, true, false} ->
|
||||
{unavailable_enabled, true};
|
||||
_ ->
|
||||
no_change
|
||||
undefined ->
|
||||
case guild_permissions:find_member_by_user_id(UserId, State) of
|
||||
undefined ->
|
||||
false;
|
||||
Member ->
|
||||
User = maps:get(<<"user">>, Member, #{}),
|
||||
is_user_staff_from_user_data(User)
|
||||
end
|
||||
end.
|
||||
|
||||
handle_unavailability_transition(OldState, NewState) ->
|
||||
GuildId = maps:get(id, NewState),
|
||||
UnavailablePayload = #{
|
||||
<<"id">> => integer_to_binary(GuildId),
|
||||
<<"unavailable">> => true
|
||||
},
|
||||
-spec is_user_staff_from_sessions(user_id(), guild_state()) -> boolean() | undefined.
|
||||
is_user_staff_from_sessions(UserId, State) ->
|
||||
Sessions = maps:get(sessions, State, #{}),
|
||||
maps:fold(
|
||||
fun(_SessionId, SessionData, Acc) ->
|
||||
case Acc of
|
||||
undefined ->
|
||||
SessionUserId = maps:get(user_id, SessionData, undefined),
|
||||
SessionIsStaff = maps:get(is_staff, SessionData, undefined),
|
||||
case {SessionUserId =:= UserId, SessionIsStaff} of
|
||||
{true, true} ->
|
||||
true;
|
||||
{true, false} ->
|
||||
false;
|
||||
_ ->
|
||||
undefined
|
||||
end;
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
end,
|
||||
undefined,
|
||||
Sessions
|
||||
).
|
||||
|
||||
-spec get_cached_unavailability_mode(guild_id()) -> unavailability_mode().
|
||||
get_cached_unavailability_mode(GuildId) ->
|
||||
ensure_unavailability_cache_table(),
|
||||
case ets:lookup(?GUILD_UNAVAILABILITY_CACHE, GuildId) of
|
||||
[{GuildId, Mode}] ->
|
||||
normalize_unavailability_mode(Mode);
|
||||
[] ->
|
||||
available
|
||||
end.
|
||||
|
||||
-spec is_guild_unavailable_for_user_from_cache(guild_id(), map()) -> boolean().
|
||||
is_guild_unavailable_for_user_from_cache(GuildId, UserData) ->
|
||||
case get_cached_unavailability_mode(GuildId) of
|
||||
unavailable_for_everyone ->
|
||||
true;
|
||||
unavailable_for_everyone_but_staff ->
|
||||
not is_user_staff_from_user_data(UserData);
|
||||
available ->
|
||||
false
|
||||
end.
|
||||
|
||||
-spec update_unavailability_cache_for_state(guild_state()) -> unavailability_mode().
|
||||
update_unavailability_cache_for_state(State) ->
|
||||
GuildId = maps:get(id, State),
|
||||
Mode = get_unavailability_mode_from_state(State),
|
||||
set_cached_unavailability_mode(GuildId, Mode),
|
||||
Mode.
|
||||
|
||||
-spec check_unavailability_transition(guild_state(), guild_state()) -> transition_result().
|
||||
check_unavailability_transition(OldState, NewState) ->
|
||||
OldMode = get_unavailability_mode_from_state(OldState),
|
||||
NewMode = get_unavailability_mode_from_state(NewState),
|
||||
case {OldMode, NewMode} of
|
||||
{available, unavailable_for_everyone} ->
|
||||
{unavailable_enabled, false};
|
||||
{available, unavailable_for_everyone_but_staff} ->
|
||||
{unavailable_enabled, true};
|
||||
{unavailable_for_everyone, available} ->
|
||||
unavailable_disabled;
|
||||
{unavailable_for_everyone_but_staff, available} ->
|
||||
unavailable_disabled;
|
||||
{unavailable_for_everyone_but_staff, unavailable_for_everyone} ->
|
||||
{unavailable_enabled, false};
|
||||
{unavailable_for_everyone, unavailable_for_everyone_but_staff} ->
|
||||
{unavailable_enabled, true};
|
||||
_ ->
|
||||
no_change
|
||||
end.
|
||||
|
||||
-spec handle_unavailability_transition(guild_state(), guild_state()) -> guild_state().
|
||||
handle_unavailability_transition(OldState, NewState) ->
|
||||
_ = update_unavailability_cache_for_state(NewState),
|
||||
GuildId = maps:get(id, NewState),
|
||||
case check_unavailability_transition(OldState, NewState) of
|
||||
{unavailable_enabled, StaffOnly} ->
|
||||
Sessions = maps:get(sessions, NewState, #{}),
|
||||
lists:foreach(
|
||||
fun({_SessionId, SessionData}) ->
|
||||
UserId = maps:get(user_id, SessionData),
|
||||
Pid = maps:get(pid, SessionData),
|
||||
|
||||
ShouldBeUnavailable =
|
||||
case StaffOnly of
|
||||
true -> not is_user_staff(UserId, NewState);
|
||||
false -> true
|
||||
end,
|
||||
|
||||
case ShouldBeUnavailable of
|
||||
true ->
|
||||
gen_server:cast(Pid, {dispatch, guild_delete, UnavailablePayload});
|
||||
false ->
|
||||
ok
|
||||
end
|
||||
end,
|
||||
maps:to_list(Sessions)
|
||||
);
|
||||
disconnect_ineligible_sessions(StaffOnly, NewState, GuildId);
|
||||
unavailable_disabled ->
|
||||
Sessions = maps:get(sessions, NewState, #{}),
|
||||
GuildId = maps:get(id, NewState),
|
||||
BulkPresences = presence_utils:collect_guild_member_presences(NewState),
|
||||
lists:foreach(
|
||||
fun({_SessionId, SessionData}) ->
|
||||
UserId = maps:get(user_id, SessionData),
|
||||
Pid = maps:get(pid, SessionData),
|
||||
GuildState = get_guild_state(UserId, NewState),
|
||||
gen_server:cast(Pid, {dispatch, guild_create, GuildState}),
|
||||
presence_utils:send_presence_bulk(Pid, GuildId, UserId, BulkPresences)
|
||||
case maps:get(pending_connect, SessionData, false) of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
UserId = maps:get(user_id, SessionData),
|
||||
Pid = maps:get(pid, SessionData),
|
||||
GuildState = guild_data:get_guild_state(UserId, NewState),
|
||||
gen_server:cast(Pid, {dispatch, guild_create, GuildState}),
|
||||
presence_utils:send_presence_bulk(Pid, GuildId, UserId, BulkPresences)
|
||||
end
|
||||
end,
|
||||
maps:to_list(Sessions)
|
||||
);
|
||||
),
|
||||
NewState;
|
||||
no_change ->
|
||||
NewState
|
||||
end.
|
||||
|
||||
-spec disconnect_ineligible_sessions(boolean(), guild_state(), guild_id()) -> guild_state().
|
||||
disconnect_ineligible_sessions(StaffOnly, State, GuildId) ->
|
||||
Sessions = maps:get(sessions, State, #{}),
|
||||
{FinalState, _DisconnectedUsers} = lists:foldl(
|
||||
fun({SessionId, SessionData}, {AccState, ProcessedUsers}) ->
|
||||
UserId = maps:get(user_id, SessionData),
|
||||
case should_disconnect_user(UserId, StaffOnly, AccState) of
|
||||
true ->
|
||||
Pid = maps:get(pid, SessionData, undefined),
|
||||
maybe_send_guild_leave(Pid, GuildId),
|
||||
{VoiceState, UpdatedUsers} =
|
||||
maybe_disconnect_voice_for_user(UserId, ProcessedUsers, AccState),
|
||||
NewState = guild_sessions:remove_session(SessionId, VoiceState),
|
||||
{NewState, UpdatedUsers};
|
||||
false ->
|
||||
{AccState, ProcessedUsers}
|
||||
end
|
||||
end,
|
||||
{State, sets:new()},
|
||||
maps:to_list(Sessions)
|
||||
),
|
||||
FinalState.
|
||||
|
||||
-spec should_disconnect_user(user_id(), boolean(), guild_state()) -> boolean().
|
||||
should_disconnect_user(UserId, true, State) ->
|
||||
not is_user_staff(UserId, State);
|
||||
should_disconnect_user(_UserId, false, _State) ->
|
||||
true.
|
||||
|
||||
-spec maybe_send_guild_leave(pid() | undefined, guild_id()) -> ok.
|
||||
maybe_send_guild_leave(Pid, GuildId) when is_pid(Pid) ->
|
||||
gen_server:cast(Pid, {guild_leave, GuildId, forced_unavailable}),
|
||||
ok;
|
||||
maybe_send_guild_leave(_Pid, _GuildId) ->
|
||||
ok.
|
||||
|
||||
-spec maybe_disconnect_voice_for_user(user_id(), sets:set(user_id()), guild_state()) ->
|
||||
{guild_state(), sets:set(user_id())}.
|
||||
maybe_disconnect_voice_for_user(UserId, ProcessedUsers, State) ->
|
||||
case sets:is_element(UserId, ProcessedUsers) of
|
||||
true ->
|
||||
{State, ProcessedUsers};
|
||||
false ->
|
||||
{reply, _Result, VoiceState} = guild_voice_disconnect:disconnect_voice_user(
|
||||
#{user_id => UserId, connection_id => null},
|
||||
State
|
||||
),
|
||||
{VoiceState, sets:add_element(UserId, ProcessedUsers)}
|
||||
end.
|
||||
|
||||
-spec ensure_unavailability_cache_table() -> ok.
|
||||
ensure_unavailability_cache_table() ->
|
||||
case ets:whereis(?GUILD_UNAVAILABILITY_CACHE) of
|
||||
undefined ->
|
||||
try ets:new(?GUILD_UNAVAILABILITY_CACHE, [named_table, public, set, {read_concurrency, true}]) of
|
||||
_ -> ok
|
||||
catch
|
||||
error:badarg -> ok
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
-spec set_cached_unavailability_mode(guild_id(), unavailability_mode()) -> ok.
|
||||
set_cached_unavailability_mode(GuildId, available) ->
|
||||
ensure_unavailability_cache_table(),
|
||||
ets:delete(?GUILD_UNAVAILABILITY_CACHE, GuildId),
|
||||
ok;
|
||||
set_cached_unavailability_mode(GuildId, Mode) ->
|
||||
ensure_unavailability_cache_table(),
|
||||
ets:insert(?GUILD_UNAVAILABILITY_CACHE, {GuildId, Mode}),
|
||||
ok.
|
||||
|
||||
-spec normalize_unavailability_mode(term()) -> unavailability_mode().
|
||||
normalize_unavailability_mode(unavailable_for_everyone) ->
|
||||
unavailable_for_everyone;
|
||||
normalize_unavailability_mode(unavailable_for_everyone_but_staff) ->
|
||||
unavailable_for_everyone_but_staff;
|
||||
normalize_unavailability_mode(_) ->
|
||||
available.
|
||||
|
||||
-spec get_unavailability_mode_from_state(guild_state()) -> unavailability_mode().
|
||||
get_unavailability_mode_from_state(State) ->
|
||||
Data = maps:get(data, State, #{}),
|
||||
Guild = maps:get(<<"guild">>, Data, #{}),
|
||||
Features = maps:get(<<"features">>, Guild, []),
|
||||
get_unavailability_mode_from_features(Features).
|
||||
|
||||
-spec get_unavailability_mode_from_features(term()) -> unavailability_mode().
|
||||
get_unavailability_mode_from_features(Features) when is_list(Features) ->
|
||||
HasUnavailableForEveryone = lists:member(<<"UNAVAILABLE_FOR_EVERYONE">>, Features),
|
||||
HasUnavailableForEveryoneButStaff =
|
||||
lists:member(<<"UNAVAILABLE_FOR_EVERYONE_BUT_STAFF">>, Features),
|
||||
case {HasUnavailableForEveryone, HasUnavailableForEveryoneButStaff} of
|
||||
{true, _} ->
|
||||
unavailable_for_everyone;
|
||||
{false, true} ->
|
||||
unavailable_for_everyone_but_staff;
|
||||
{false, false} ->
|
||||
available
|
||||
end;
|
||||
get_unavailability_mode_from_features(_) ->
|
||||
available.
|
||||
|
||||
-spec is_user_staff_from_user_data(map()) -> boolean().
|
||||
is_user_staff_from_user_data(UserData) when is_map(UserData) ->
|
||||
case parse_is_staff_value(maps:get(<<"is_staff">>, UserData, undefined)) of
|
||||
undefined ->
|
||||
is_user_staff_from_flags(UserData);
|
||||
IsStaff ->
|
||||
IsStaff
|
||||
end;
|
||||
is_user_staff_from_user_data(_) ->
|
||||
false.
|
||||
|
||||
-spec parse_is_staff_value(term()) -> boolean() | undefined.
|
||||
parse_is_staff_value(true) ->
|
||||
true;
|
||||
parse_is_staff_value(false) ->
|
||||
false;
|
||||
parse_is_staff_value(<<"true">>) ->
|
||||
true;
|
||||
parse_is_staff_value(<<"false">>) ->
|
||||
false;
|
||||
parse_is_staff_value(_) ->
|
||||
undefined.
|
||||
|
||||
-spec is_user_staff_from_flags(map()) -> boolean().
|
||||
is_user_staff_from_flags(UserData) ->
|
||||
FlagsValue = maps:get(<<"flags">>, UserData, 0),
|
||||
Flags = type_conv:to_integer(FlagsValue),
|
||||
case Flags of
|
||||
undefined ->
|
||||
false;
|
||||
Value when is_integer(Value) ->
|
||||
(Value band ?STAFF_USER_FLAG) =:= ?STAFF_USER_FLAG
|
||||
end.
|
||||
|
||||
-ifdef(TEST).
|
||||
|
||||
-spec cleanup_unavailability_cache(guild_id()) -> ok.
|
||||
cleanup_unavailability_cache(GuildId) ->
|
||||
set_cached_unavailability_mode(GuildId, available).
|
||||
|
||||
disconnect_ineligible_sessions_staff_only_test() ->
|
||||
Parent = self(),
|
||||
GuildId = 99001,
|
||||
NonStaffPid = start_session_capture(non_staff, Parent),
|
||||
StaffPid = start_session_capture(staff, Parent),
|
||||
try
|
||||
BaseState = state_for_unavailability_transition_test(GuildId, NonStaffPid, StaffPid),
|
||||
OldState = BaseState,
|
||||
NewState = BaseState#{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => [<<"UNAVAILABLE_FOR_EVERYONE_BUT_STAFF">>]
|
||||
},
|
||||
<<"members">> => [
|
||||
#{<<"user">> => #{<<"id">> => <<"1001">>, <<"flags">> => <<"0">>}},
|
||||
#{<<"user">> => #{<<"id">> => <<"1002">>, <<"flags">> => <<"1">>}}
|
||||
]
|
||||
}
|
||||
},
|
||||
UpdatedState = handle_unavailability_transition(OldState, NewState),
|
||||
Sessions = maps:get(sessions, UpdatedState, #{}),
|
||||
?assertEqual(1, map_size(Sessions)),
|
||||
?assert(maps:is_key(<<"staff">>, Sessions)),
|
||||
?assertEqual(unavailable_for_everyone_but_staff, get_cached_unavailability_mode(GuildId)),
|
||||
receive
|
||||
{non_staff, {'$gen_cast', {guild_leave, GuildId, forced_unavailable}}} -> ok
|
||||
after 1000 ->
|
||||
?assert(false)
|
||||
end,
|
||||
receive
|
||||
{staff, {'$gen_cast', {guild_leave, GuildId, forced_unavailable}}} ->
|
||||
?assert(false)
|
||||
after 200 ->
|
||||
ok
|
||||
end
|
||||
after
|
||||
cleanup_unavailability_cache(GuildId),
|
||||
NonStaffPid ! stop,
|
||||
StaffPid ! stop
|
||||
end.
|
||||
|
||||
disconnect_ineligible_sessions_everyone_test() ->
|
||||
Parent = self(),
|
||||
GuildId = 99002,
|
||||
UserOnePid = start_session_capture(user_one, Parent),
|
||||
UserTwoPid = start_session_capture(user_two, Parent),
|
||||
try
|
||||
BaseState = state_for_unavailability_transition_test(GuildId, UserOnePid, UserTwoPid),
|
||||
OldState = BaseState,
|
||||
NewState = BaseState#{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => [<<"UNAVAILABLE_FOR_EVERYONE">>]
|
||||
},
|
||||
<<"members">> => [
|
||||
#{<<"user">> => #{<<"id">> => <<"1001">>, <<"flags">> => <<"0">>}},
|
||||
#{<<"user">> => #{<<"id">> => <<"1002">>, <<"flags">> => <<"1">>}}
|
||||
]
|
||||
}
|
||||
},
|
||||
UpdatedState = handle_unavailability_transition(OldState, NewState),
|
||||
?assertEqual(#{}, maps:get(sessions, UpdatedState, #{})),
|
||||
?assertEqual(unavailable_for_everyone, get_cached_unavailability_mode(GuildId)),
|
||||
receive
|
||||
{user_one, {'$gen_cast', {guild_leave, GuildId, forced_unavailable}}} -> ok
|
||||
after 1000 ->
|
||||
?assert(false)
|
||||
end,
|
||||
receive
|
||||
{user_two, {'$gen_cast', {guild_leave, GuildId, forced_unavailable}}} -> ok
|
||||
after 1000 ->
|
||||
?assert(false)
|
||||
end
|
||||
after
|
||||
cleanup_unavailability_cache(GuildId),
|
||||
UserOnePid ! stop,
|
||||
UserTwoPid ! stop
|
||||
end.
|
||||
|
||||
is_guild_unavailable_for_user_from_cache_is_staff_test() ->
|
||||
GuildId = 99003,
|
||||
try
|
||||
set_cached_unavailability_mode(GuildId, unavailable_for_everyone_but_staff),
|
||||
?assertEqual(
|
||||
true,
|
||||
is_guild_unavailable_for_user_from_cache(
|
||||
GuildId,
|
||||
#{<<"is_staff">> => false}
|
||||
)
|
||||
),
|
||||
?assertEqual(
|
||||
false,
|
||||
is_guild_unavailable_for_user_from_cache(
|
||||
GuildId,
|
||||
#{<<"is_staff">> => true}
|
||||
)
|
||||
)
|
||||
after
|
||||
cleanup_unavailability_cache(GuildId)
|
||||
end.
|
||||
|
||||
-spec start_session_capture(atom(), pid()) -> pid().
|
||||
start_session_capture(Tag, Parent) ->
|
||||
spawn(fun() -> session_capture_loop(Tag, Parent) end).
|
||||
|
||||
-spec session_capture_loop(atom(), pid()) -> ok.
|
||||
session_capture_loop(Tag, Parent) ->
|
||||
receive
|
||||
stop ->
|
||||
ok;
|
||||
{'$gen_cast', Msg} ->
|
||||
Parent ! {Tag, {'$gen_cast', Msg}},
|
||||
session_capture_loop(Tag, Parent);
|
||||
_Other ->
|
||||
session_capture_loop(Tag, Parent)
|
||||
end.
|
||||
|
||||
-spec state_for_unavailability_transition_test(guild_id(), pid(), pid()) -> guild_state().
|
||||
state_for_unavailability_transition_test(GuildId, NonStaffPid, StaffPid) ->
|
||||
#{
|
||||
id => GuildId,
|
||||
sessions => #{
|
||||
<<"non_staff">> => #{
|
||||
session_id => <<"non_staff">>,
|
||||
user_id => 1001,
|
||||
pid => NonStaffPid,
|
||||
mref => make_ref(),
|
||||
active_guilds => sets:new(),
|
||||
user_roles => [],
|
||||
bot => false,
|
||||
is_staff => false,
|
||||
previous_passive_updates => #{},
|
||||
previous_passive_channel_versions => #{},
|
||||
previous_passive_voice_states => #{}
|
||||
},
|
||||
<<"staff">> => #{
|
||||
session_id => <<"staff">>,
|
||||
user_id => 1002,
|
||||
pid => StaffPid,
|
||||
mref => make_ref(),
|
||||
active_guilds => sets:new(),
|
||||
user_roles => [],
|
||||
bot => false,
|
||||
is_staff => true,
|
||||
previous_passive_updates => #{},
|
||||
previous_passive_channel_versions => #{},
|
||||
previous_passive_voice_states => #{}
|
||||
}
|
||||
},
|
||||
presence_subscriptions => #{},
|
||||
member_list_subscriptions => #{},
|
||||
member_subscriptions => guild_subscriptions:init_state(),
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => []
|
||||
},
|
||||
<<"members">> => [
|
||||
#{<<"user">> => #{<<"id">> => <<"1001">>, <<"flags">> => <<"0">>}},
|
||||
#{<<"user">> => #{<<"id">> => <<"1002">>, <<"flags">> => <<"1">>}}
|
||||
]
|
||||
},
|
||||
voice_states => #{},
|
||||
pending_voice_connections => #{}
|
||||
}.
|
||||
|
||||
is_guild_unavailable_for_user_unavailable_for_everyone_test() ->
|
||||
State = #{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => [<<"UNAVAILABLE_FOR_EVERYONE">>]
|
||||
},
|
||||
<<"members">> => []
|
||||
}
|
||||
},
|
||||
?assertEqual(true, is_guild_unavailable_for_user(123, State)).
|
||||
|
||||
is_guild_unavailable_for_user_available_test() ->
|
||||
State = #{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => []
|
||||
},
|
||||
<<"members">> => []
|
||||
}
|
||||
},
|
||||
?assertEqual(false, is_guild_unavailable_for_user(123, State)).
|
||||
|
||||
check_unavailability_transition_no_change_test() ->
|
||||
State = #{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => []
|
||||
}
|
||||
}
|
||||
},
|
||||
?assertEqual(no_change, check_unavailability_transition(State, State)).
|
||||
|
||||
check_unavailability_transition_enabled_test() ->
|
||||
OldState = #{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => []
|
||||
}
|
||||
}
|
||||
},
|
||||
NewState = #{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => [<<"UNAVAILABLE_FOR_EVERYONE">>]
|
||||
}
|
||||
}
|
||||
},
|
||||
?assertEqual({unavailable_enabled, false}, check_unavailability_transition(OldState, NewState)).
|
||||
|
||||
check_unavailability_transition_disabled_test() ->
|
||||
OldState = #{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => [<<"UNAVAILABLE_FOR_EVERYONE">>]
|
||||
}
|
||||
}
|
||||
},
|
||||
NewState = #{
|
||||
data => #{
|
||||
<<"guild">> => #{
|
||||
<<"features">> => []
|
||||
}
|
||||
}
|
||||
},
|
||||
?assertEqual(unavailable_disabled, check_unavailability_transition(OldState, NewState)).
|
||||
|
||||
-endif.
|
||||
|
||||
Reference in New Issue
Block a user