Files
fluxer/fluxer_gateway/test/guild_handoff_tests.erl
T

122 lines
4.7 KiB
Erlang

%% SPDX-License-Identifier: AGPL-3.0-or-later
-module(guild_handoff_tests).
-typing([eqwalizer]).
-include_lib("eunit/include/eunit.hrl").
remonitor_transferred_sessions_replaces_stale_refs_test() ->
Pid = spawn(fun session_loop/0),
OldRef = make_ref(),
State0 = #{
sessions => #{
<<"s1">> => #{pid => Pid, mref => OldRef, user_id => 10},
<<"missing_pid">> => #{user_id => 11},
<<"bad">> => bad_session
}
},
State1 = guild_handoff:remonitor_transferred_sessions(State0),
Sessions = maps:get(sessions, State1),
?assertEqual(false, maps:is_key(<<"missing_pid">>, Sessions)),
?assertEqual(false, maps:is_key(<<"bad">>, Sessions)),
Session = maps:get(<<"s1">>, Sessions),
NewRef = maps:get(mref, Session),
?assert(is_reference(NewRef)),
?assertNotEqual(OldRef, NewRef),
Pid ! stop,
receive
{'DOWN', NewRef, process, Pid, _Reason} -> ok
after 1000 ->
?assert(false)
end.
restore_transferred_session_state_rebuilds_connected_counts_test() ->
UserId = 10,
Sessions = #{
<<"s1">> => #{pid => self(), user_id => UserId},
<<"s2">> => #{pid => self(), user_id => UserId, pending_connect => false},
<<"pending">> => #{pid => self(), user_id => 11, pending_connect => true},
<<"bad">> => #{user_id => 12}
},
State0 = #{
sessions => Sessions,
connected_user_ids => sets:new(),
user_session_counts => #{},
presence_subscriptions => #{UserId => 1}
},
State1 = guild_handoff:restore_transferred_session_state(State0),
?assertEqual(#{UserId => 2}, maps:get(user_session_counts, State1)),
Connected = maps:get(connected_user_ids, State1),
?assertEqual(true, sets:is_element(UserId, Connected)),
?assertEqual(false, sets:is_element(11, Connected)),
?assertEqual(3, maps:get(UserId, maps:get(presence_subscriptions, State1))).
export_handoff_state_contains_all_required_keys_test() ->
State = #{
id => 12345,
data => #{<<"guild">> => #{<<"id">> => <<"12345">>}},
sessions => #{
<<"s1">> => #{pid => self(), user_id => 10, mref => make_ref()}
},
voice_states => #{<<"conn1">> => #{<<"user_id">> => 10}},
virtual_channel_access => #{},
virtual_channel_access_pending => #{},
virtual_channel_access_preserve => #{},
virtual_channel_access_move_pending => #{}
},
Exported = guild_handoff:export_handoff_state(State),
?assertEqual(ok, guild_handoff:validate_handoff_state(Exported)),
?assertEqual(12345, maps:get(id, Exported)),
?assert(is_map(maps:get(data, Exported))),
?assert(is_map(maps:get(sessions, Exported))),
?assert(is_map(maps:get(voice_states, Exported))),
Session = maps:get(<<"s1">>, maps:get(sessions, Exported)),
?assertEqual(false, maps:is_key(mref, Session)).
export_handoff_state_omits_pending_member_list_batch_test() ->
State = #{
id => 12345,
data => #{<<"guild">> => #{<<"id">> => <<"12345">>}},
sessions => #{},
voice_states => #{},
pending_member_list_sync_batch => #{
timer_ref => make_ref(),
pending_list_ids => #{<<"500">> => true}
}
},
Exported = guild_handoff:export_handoff_state(State),
?assertNot(maps:is_key(pending_member_list_sync_batch, Exported)).
validate_handoff_state_rejects_missing_keys_test() ->
?assertMatch({error, _}, guild_handoff:validate_handoff_state(#{})),
?assertMatch({error, _}, guild_handoff:validate_handoff_state(#{id => 1})),
?assertMatch({error, [not_a_map]}, guild_handoff:validate_handoff_state(not_a_map)).
validate_handoff_state_rejects_bad_types_test() ->
BadState = #{id => <<"not_int">>, data => #{}, sessions => #{}, voice_states => #{}},
?assertMatch({error, [id]}, guild_handoff:validate_handoff_state(BadState)).
export_import_roundtrip_preserves_data_test() ->
State = #{
id => 54321,
data => #{<<"guild">> => #{<<"id">> => <<"54321">>}, <<"channels">> => []},
sessions => #{},
voice_states => #{<<"c1">> => #{<<"user_id">> => 1, <<"channel_id">> => 100}},
virtual_channel_access => #{10 => sets:from_list([20])},
virtual_channel_access_pending => #{},
virtual_channel_access_preserve => #{},
virtual_channel_access_move_pending => #{}
},
Exported = guild_handoff:export_handoff_state(State),
?assertEqual(ok, guild_handoff:validate_handoff_state(Exported)),
ExportedVoice = maps:get(voice_states, Exported),
?assertEqual(1, maps:size(ExportedVoice)),
?assert(maps:is_key(<<"c1">>, ExportedVoice)).
session_loop() ->
receive
stop -> ok
after infinity ->
ok
end.