<?phpnamespace Tests;use App\Form\ChatForm;use App\Form\LoginForm;use App\Gui\ChatList;use App\Net\FakeLink;use JumPHP\Testing\GameTestCase;/** The windows, used as a member uses them, against a scripted server (FakeLink). */final class ChatWindowTest extends GameTestCase{ private FakeLink $link; protected function setUp(): void { parent::setUp(); \JumPHP\Kernel\Engine::get()->lang->setLang('en'); // the texts checked below are the English ones } private function chat(bool $admin = false): ChatForm { $this->link = new FakeLink(); $this->game->start(ChatForm::class, ['link' => $this->link, 'tempid' => 'n=Ada&a=30&s=0&v=Lyon', 'admin' => $admin]); $this->link->open(); $this->link->serverSays('0', '1:1:1:0', '197', '0', 'Ada'); $this->link->serverSays('20', '0', 'Accueil', '?', 'admin'); $this->link->serverSays('85', '-1', '1:1:1:0', '0', 'Ada', '0', '30', '0', 'Lyon', '2:2:2:0', '0', 'Bob', '0', '28', '1', 'Lille'); $this->link->take(); $this->game->run(2); /** @var ChatForm $form */ $form = $this->game->scene(); return $form; } public function testTheLoginRefusesAnEmptyNickname(): void { $this->game->start(LoginForm::class, ['nickname' => '', 'host' => 'localhost', 'port' => 4500]); /** @var LoginForm $form */ $form = $this->game->scene(); $form->click($form->widget('enter')); self::assertNotSame('', $form->widget('status')->props['text']); self::assertInstanceOf(LoginForm::class, $this->game->scene()); } public function testEnteringTheRoomShowsItsTabAndItsMembers(): void { $form = $this->chat(); self::assertSame('room', $form->tabs->current); self::assertTrue($form->roomPane->visible); /** @var ChatList $members */ $members = $form->widget('members'); self::assertSame(['Ada', 'Bob'], $members->texts()); self::assertSame('30, F, Lyon', $members->items()[0]['tip']); self::assertSame('2 people - 1 F - 1 M', $form->membersCount->props['text']); $this->game->shot('room'); } public function testASentenceTypedIsSentWithItsColourAndSize(): void { $form = $this->chat(); $form->color->selected = 2; // red $form->size->selected = 2; // big = font 02 $form->click($form->widget('line')); $form->type("Bonsoir :-)\n"); $this->game->run(1); self::assertSame(["70\t0202Bonsoir :-)"], $this->link->take()); } public function testTheRoomShowsTheSentencesWithTheirAuthor(): void { $form = $this->chat(); $this->link->serverSays('70', '2:2:2:0', '0', 'Bob', '0101Salut Ada ;-)'); $this->game->run(2); self::assertSame(['Bob> Salut Ada ;-)'], $form->talk->texts()); self::assertTrue($form->talk->items()[0]['bold'], 'a line with my nickname is in bold'); $this->game->shot('sentence'); } public function testAPrivateMessageOpensItsTabAndTheAnswerGoesToItsAuthor(): void { $form = $this->chat(); $this->link->serverSays('72', '2:2:2:0', '0', 'Bob', '0100Coucou'); $this->game->run(1); self::assertTrue($form->tabs->has('pv:2:2:2:0')); self::assertTrue($form->tabs->hasNews('pv:2:2:2:0'), 'a hidden tab with news turns orange'); $form->tabs->choose('pv:2:2:2:0'); $this->game->run(1); self::assertTrue($form->privatePane->visible); self::assertSame(['Bob> Coucou'], $form->pvTalk->texts()); $this->link->take(); $form->click($form->widget('pvLine')); $form->type("Salut toi\n"); self::assertSame(["72\t2:2:2:0\t0100Salut toi"], $this->link->take()); $this->game->shot('private'); } public function testADoubleClickOnAMemberOpensAPrivateTalk(): void { $form = $this->chat(); $form->members->select(1); $form->click($form->widget('privateBtn')); $this->game->run(1); self::assertSame('pv:2:2:2:0', $form->tabs->current); } public function testAClickOnALineAndPrivateMessageAnswerInPrivate(): void { $form = $this->chat(); $this->link->serverSays('70', '2:2:2:0', '0', 'Bob', '0100Salut'); $this->game->run(1); $form->talk->hover = 0; $form->onTalkClick(); self::assertSame('Bob> ', $form->line->props['text']); self::assertTrue($form->privateMsg->props['enabled']); $form->privateMsg->checked = true; $form->onPrivateMsgChange(); self::assertSame('', $form->line->props['text']); $form->click($form->widget('line')); $form->type("en privé\n"); self::assertSame(["72\t2:2:2:0\t0100en privé"], $this->link->take()); } public function testThePhoneGoesToTheMembersAndBackToTheTalk(): void { $form = $this->chat(); $adapt = fn () => $this->adapt(); $form->layoutTo(390, 700); // a phone's width (the frames would lay it out again in the window) $adapt->call($form); self::assertTrue($form->roomSwitch->props['visible']); self::assertTrue($form->roomMain->props['visible']); self::assertFalse($form->roomSide->props['visible']); $form->roomSwitch->choose('members'); $adapt->call($form); self::assertTrue($form->roomSide->props['visible']); self::assertFalse($form->roomMain->props['visible']); self::assertTrue($form->roomSwitch->props['visible'], 'the bar stays: the way back to the talk'); $form->roomSwitch->choose('dialogue'); $adapt->call($form); self::assertTrue($form->roomMain->props['visible']); self::assertFalse($form->roomSide->props['visible']); } public function testOnAPhoneTheLineSitsWithItsButtonAndStaysAboveTheKeyboard(): void { $form = $this->chat(); $adapt = fn () => $this->adapt(); $form->layoutTo(390, 700); $form->setFocus(null); // the page shown on a computer focused its line; a phone waits for a tap $adapt->call($form); self::assertSame([$form->line, $form->send], $form->lineRow->children); self::assertSame('fill', $form->talkBox->props['height']); $form->layoutTo(390, 700); // the next frame lays the new rows out $form->click($form->widget('line')); // typing: the keyboard comes up from the bottom $adapt->call($form); $form->layoutTo(390, 700); self::assertIsInt($form->talkBox->props['height']); self::assertLessThan((fn () => $this->height())->call($form) * 0.5, $form->talkBox->props['height'] * $form->theme->scale); self::assertFalse($form->optsRow->props['visible']); $form->type("ça marche\n"); self::assertSame(["70\t0100ça marche"], $this->link->take()); } public function testAComputerKeepsTheAppletsTwoRows(): void { $form = $this->chat(); $adapt = fn () => $this->adapt(); $form->layoutTo(2400, 1400); // a computer (the tests draw at twice the size: 1200 dp wide) $adapt->call($form); self::assertSame([$form->privateMsg, $form->line], $form->lineRow->children); self::assertFalse($form->roomSwitch->props['visible']); self::assertTrue($form->roomSide->props['visible']); } public function testASlashCommandWritesInPrivate(): void { $form = $this->chat(); $form->click($form->widget('line')); $form->type("/Bob tu es là ?\n"); self::assertSame(["72\tBob:0\t0100tu es là ?"], $this->link->take()); } public function testTheSearchSendsTheApplets56AndListsTheAnswer(): void { $form = $this->chat(); $form->tabs->choose('search'); $this->game->run(1); $this->link->take(); $form->searchText->text = 'bo'; $form->searchSex->selected = 2; // men $form->click($form->widget('searchGo')); self::assertSame(["56\tbo\t-2\t1"], $this->link->take()); $this->link->serverSays('56', '-2:1:1', '2:2:2:0', 'Bob', '0', '28', 'Lille', 'Accueil', '0'); $this->game->run(1); self::assertSame(['Bob - (room Accueil)'], $form->found->texts()); } public function testTheRoomsAreListedAndADoubleClickGoesIn(): void { $form = $this->chat(); $form->tabs->choose('rooms'); $this->link->serverSays('94', 'Musique', '?', 'admin', '3', 'Accueil', '?', 'admin', '2'); $this->game->run(1); self::assertSame(['Accueil (2)', 'Musique (3)'], $form->rooms->texts()); $this->link->take(); $form->onRoomsActivate($form->rooms, 1, $form->rooms->items()[1]); self::assertSame(["40\tMusique\t0"], $this->link->take()); $this->game->shot('rooms'); } public function testALostConnectionIsSaidInTheInfoTab(): void { $form = $this->chat(); $this->link->close(); $this->game->run(1); self::assertSame('info', $form->tabs->current); self::assertTrue($form->optionsPane->visible); self::assertStringContainsString('The connection with the server has been interrupted', implode(' ', $form->info->texts())); } public function testTheRoomsEventsAreTheAppletsInformationMessages(): void { $form = $this->chat(); $this->link->serverSays('76', '1', 'Salon'); $this->link->serverSays('76', '2', 'Bob'); $this->link->serverSays('76', '4', 'Bob'); $this->link->serverSays('550', '1'); $this->link->serverSays('551'); $this->game->run(1); $texts = implode(' | ', $form->info->texts()); foreach (['Welcome to the room Salon', 'Bob has arrived in the room', 'Bob has left the live chat', 'A moderator has been warned', 'No moderator can be reached for the moment.'] as $text) { self::assertStringContainsString($text, $texts); } self::assertTrue($form->tabs->hasNews('info'), 'the Options tab turns orange'); } public function testTheSearchSendsTheAppletsAgeAndSexCodes(): void { $form = $this->chat(); $this->link->take(); $form->searchAge->selected = 1; // 5-10 y.o. $form->searchSex->selected = 3; // don't know $form->onSearchClick(); $form->searchAge->selected = 11; // Others... $form->searchSex->selected = 1; // woman $form->onSearchClick(); self::assertSame(["56\t\t1\t-1", "56\t\t-1\t0"], $this->link->take()); } public function testTheLanguageCanBeChangedInOptionsWithoutLeavingTheChat(): void { $form = $this->chat(); $form->language->selected = 11; // 日本語 $form->onLanguageChange(); $this->game->run(2); self::assertSame('ja', \JumPHP\Kernel\Engine::get()->options->get('lang')); self::assertNotSame('Rooms', $form->tabs->label('rooms')); self::assertTrue($form->chat?->connected); $this->game->shot('japanese'); $form->language->selected = 1; // English, for the other tests $form->onLanguageChange(); } public function testAModeratorCanEject(): void { $form = $this->chat(true); self::assertTrue($form->ejectBtn->visible); $form->members->select(1); $form->click($form->widget('ejectBtn')); self::assertSame(["555\tBob:0"], $this->link->take()); }}