Discord-Client
view release on metacpan or search on metacpan
t/09-gateway-invariants.t view on Meta::CPAN
sub {
my $session = Discord::Client::Gateway::Session->new(
token => 'FAKE',
random => sub { 0.25 }
);
$session->opened;
# Invalid input must not leave timers or authentication partially configured.
T2->like(
T2->dies(
sub {
$session->receive(
{
op => 10,
d => { heartbeat_interval => $case->{value} },
}
);
}
),
qr/invalid heartbeat interval/,
'HELLO is rejected for the expected reason'
);
T2->is( $session->state, 'awaiting_hello', 'handshake remains available' );
T2->is( $session->heartbeat_interval_ms, undef, 'no interval is installed' );
# After rejecting bad input, the same session must still accept a valid HELLO.
my $actions = $session->receive( { op => 10, d => { heartbeat_interval => 1000 } } );
T2->is(
$actions->[0],
{
action => 'heartbeat_schedule',
first_delay_ms => 250,
interval_ms => 1000,
},
'a subsequent valid HELLO schedules the expected heartbeat'
);
T2->is( $actions->[1]{payload}{op}, 2, 'authentication starts after valid input' );
}
);
}
}
);
T2->subtest(
'shard payload and fatal session cleanup',
sub {
# Shard identity belongs in Identify, while fatal closure must discard resume state.
my $session = Discord::Client::Gateway::Session->new(
token => 'FAKE',
shard => [ 1, 2 ],
random => sub { 0 }
);
$session->opened;
T2->is(
$session->receive( { op => 10, d => { heartbeat_interval => 1000 } } )->[1]{payload}{d}{shard},
[ 1, 2 ],
'Identify carries shard'
);
$session = ready();
$session->closed(4004);
T2->ok( !$session->can_resume, 'fatal close clears credentials for resume' );
}
);
T2->done_testing;
( run in 0.671 second using v1.01-cache-2.11-cpan-3f962061493 )