Anmelden
DE
apps/caramail-chat / tests / ChatClientTest.php · commit 6eebcdb
<?phpnamespace Tests;use App\Chat\ChatClient;use App\Chat\Member;use App\Net\FakeLink;use PHPUnit\Framework\TestCase;/** The client's side of the protocol, frame by frame, without a network. */final class ChatClientTest extends TestCase{    private FakeLink $link;    private ChatClient $chat;    /** @var list<array{0: string, 1: array}> */    private array $events = [];    protected function setUp(): void    {        $this->link = new FakeLink();        $this->chat = new ChatClient($this->link, 'n=Ada&a=30&s=0&v=Lyon');        foreach (['logged', 'room', 'say', 'private', 'members', 'rooms', 'found', 'count', 'gone', 'ended', 'ejection'] as $e) {            $this->chat->on($e, fn (...$args) => $this->events[] = [$e, $args]);        }        $this->link->open();    }    private function last(string $event): array    {        foreach (array_reverse($this->events) as [$e, $args]) {            if ($e === $event) {                return $args;            }        }        self::fail("no $event");    }    public function testTheClientIntroducesItselfWithItsTempid(): void    {        self::assertSame(["0\t0\tn=Ada&a=30&s=0&v=Lyon"], $this->link->take());    }    public function testAfterTheLoginItAsksWhatTheAppletAskedAndEntersTheRoom(): void    {        $this->link->take();        $this->link->serverSays('0', '1:2:3:0', '197', '0', 'Ada');        self::assertSame(['1:2:3:0', 'Ada'], $this->last('logged'));        self::assertSame(["82\t1:2:3:0", "84\t", "200\t4", "200\t5", "20\tSalon\t0"], $this->link->take());    }    public function testEnteringARoomAsksForItsMembers(): void    {        $this->link->serverSays('20', '0', 'Musique', '?', 'Bob');        self::assertSame(['Musique', 'Bob', 0], $this->last('room'));        self::assertContains("85\t", $this->link->take());    }    public function testTheMembersOfTheRoomAndWhoComesAndGoes(): void    {        $this->link->serverSays('85', '-1', '1:1:1:0', '0', 'Lea', '0', '23', '0', 'Lyon', '2:2:2:0', '1', 'Modo', '0', '40', '1', '?');        /** @var list<Member> $members */        $members = $this->last('members')[0];        self::assertSame(['Lea', 'Modo'], array_map(fn (Member $m) => $m->nickname, $members));        self::assertSame('', $members[1]->city, '"?" is the applet\'s empty field');        self::assertTrue($members[1]->isAdmin());        $this->link->serverSays('85', '1', '1:1:1:0');        self::assertCount(1, $this->last('members')[0]);    }    public function testEmptyFieldsVanishAsInTheAppletsTokenizer(): void    {        $this->link->serverBytes("70\t9:9:9:0\t0\t\tBob\t0100Salut\t\n");        self::assertSame(['9:9:9:0', 'Bob', '0100Salut'], $this->last('say'));    }    public function testPrivateMessagesAndTheirEcho(): void    {        $this->link->serverSays('72', '5:5:5:0', '0', 'Lea', '0100Coucou');        self::assertSame(['5:5:5:0', 'Lea', '0100Coucou', false], $this->last('private'));        $this->link->serverSays('73', '5:5:5:0', '0', 'Lea', '0100Re');        self::assertTrue($this->last('private')[3]);    }    public function testASearchWithBothSexesHasASexColumn(): void    {        $this->link->serverSays('56', '-2:-2:-2', '1:1:1:0', 'Lea', '0', '23', '0', 'Lyon', 'Accueil', '0', '2:2:2:0', 'Max', '0', '31', '1', 'Lille', '?', '2');        /** @var list<Member> $found */        $found = $this->last('found')[1];        self::assertSame(['Lea', 0, 'Accueil'], [$found[0]->nickname, $found[0]->sex, $found[0]->where]);        self::assertSame(['Max', 1, ''], [$found[1]->nickname, $found[1]->sex, $found[1]->where]);    }    public function testASearchForWomenHasNoSexColumn(): void    {        $this->link->serverSays('56', '-2:0:0', '1:1:1:0', 'Lea', '0', '23', 'Lyon', 'Accueil', '0');        self::assertSame(0, $this->last('found')[1][0]->sex);    }    public function testTheRoomsLists(): void    {        $this->link->serverSays('94', 'Accueil', '?', 'admin', '4', 'Musique', '?', 'admin', '0');        self::assertSame(['94', [['name' => 'Accueil', 'creator' => 'admin', 'count' => 4], ['name' => 'Musique', 'creator' => 'admin', 'count' => 0]]], $this->last('rooms'));    }    public function testThePingIsAnswered(): void    {        $this->link->take();        $this->link->serverSays('667');        self::assertSame(["667\t"], $this->link->take());    }    public function testAnEjectionEndsTheSession(): void    {        $this->link->serverSays('0', '1:2:3:0', '197', '0', 'Ada');        $this->link->serverSays('555', '7:7:7:0', 'Modo');        self::assertSame(['ejected-by', 'Modo'], $this->last('ended'));        self::assertTrue($this->link->closed);    }    public function testAFrameCutInTwoIsPutBackTogether(): void    {        $this->link->serverBytes("199\t4");        $this->link->serverBytes("2\n");        self::assertSame([42], $this->last('count'));    }}