laravel-webrtc/tests/RelaySignalingHandlerTest.php

133 lines
4.6 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace Blax\WebRtc\Tests;
use Blax\WebRtc\Signaling\RelaySignalingHandler;
use Blax\WebRtc\Tests\Fixtures\FakePeer;
use PHPUnit\Framework\TestCase;
final class RelaySignalingHandlerTest extends TestCase
{
public function test_welcomes_a_peer_on_connect_with_its_id(): void
{
$handler = new RelaySignalingHandler;
$a = new FakePeer('a');
$handler->onOpen($a);
$this->assertSame(['type' => 'welcome', 'peer' => 'a'], $a->lastJson());
}
public function test_join_returns_existing_peers_and_notifies_them(): void
{
$handler = new RelaySignalingHandler;
$a = new FakePeer('a');
$b = new FakePeer('b');
$handler->onOpen($a);
$handler->onOpen($b);
$handler->onMessage($a, $this->json(['type' => 'join', 'room' => 'lobby']));
$handler->onMessage($b, $this->json(['type' => 'join', 'room' => 'lobby']));
// b learns 'a' is already there
$this->assertSame(['type' => 'joined', 'room' => 'lobby', 'peers' => ['a']], $b->lastJson());
// a is told b joined
$this->assertContains(['type' => 'peer-joined', 'room' => 'lobby', 'peer' => 'b'], $a->jsonMessages());
}
public function test_relay_forwards_the_payload_to_the_target_with_the_sender(): void
{
$handler = new RelaySignalingHandler;
$a = new FakePeer('a');
$b = new FakePeer('b');
$handler->onOpen($a);
$handler->onOpen($b);
$handler->onMessage($a, $this->json(['type' => 'relay', 'to' => 'b', 'data' => ['sdp' => 'OFFER']]));
$this->assertSame(['type' => 'relay', 'from' => 'a', 'data' => ['sdp' => 'OFFER']], $b->lastJson());
}
public function test_relay_to_an_unknown_peer_errors_the_sender(): void
{
$handler = new RelaySignalingHandler;
$a = new FakePeer('a');
$handler->onOpen($a);
$handler->onMessage($a, $this->json(['type' => 'relay', 'to' => 'ghost', 'data' => []]));
$this->assertSame('error', $a->lastJson()['type']);
}
public function test_leave_notifies_the_remaining_peers(): void
{
$handler = new RelaySignalingHandler;
$a = new FakePeer('a');
$b = new FakePeer('b');
$handler->onOpen($a);
$handler->onOpen($b);
$handler->onMessage($a, $this->json(['type' => 'join', 'room' => 'lobby']));
$handler->onMessage($b, $this->json(['type' => 'join', 'room' => 'lobby']));
$handler->onMessage($b, $this->json(['type' => 'leave']));
$this->assertContains(['type' => 'peer-left', 'peer' => 'b'], $a->jsonMessages());
$this->assertSame(['type' => 'left'], $b->lastJson());
}
public function test_disconnect_leaves_the_room_and_forgets_the_peer(): void
{
$handler = new RelaySignalingHandler;
$a = new FakePeer('a');
$b = new FakePeer('b');
$handler->onOpen($a);
$handler->onOpen($b);
$handler->onMessage($a, $this->json(['type' => 'join', 'room' => 'lobby']));
$handler->onMessage($b, $this->json(['type' => 'join', 'room' => 'lobby']));
$handler->onClose($b);
$this->assertContains(['type' => 'peer-left', 'peer' => 'b'], $a->jsonMessages());
$this->assertFalse($handler->peers()->has('b'));
}
public function test_broadcast_reaches_the_rest_of_the_room_only(): void
{
$handler = new RelaySignalingHandler;
$peers = [new FakePeer('a'), new FakePeer('b'), new FakePeer('c')];
foreach ($peers as $p) {
$handler->onOpen($p);
$handler->onMessage($p, $this->json(['type' => 'join', 'room' => 'r']));
}
[$a, $b, $c] = $peers;
$handler->onMessage($a, $this->json(['type' => 'broadcast', 'data' => ['x' => 1]]));
$expected = ['type' => 'broadcast', 'from' => 'a', 'data' => ['x' => 1]];
$this->assertContains($expected, $b->jsonMessages());
$this->assertContains($expected, $c->jsonMessages());
$this->assertNotContains($expected, $a->jsonMessages());
}
public function test_invalid_json_and_unknown_type_are_errors(): void
{
$handler = new RelaySignalingHandler;
$a = new FakePeer('a');
$handler->onOpen($a);
$handler->onMessage($a, 'not json');
$this->assertSame('error', $a->lastJson()['type']);
$handler->onMessage($a, $this->json(['type' => 'wat']));
$this->assertSame('error', $a->lastJson()['type']);
}
/** @param array<string,mixed> $data */
private function json(array $data): string
{
return (string) json_encode($data);
}
}