client->request('GET', '/'); self::assertResponseIsSuccessful(); self::assertSelectorTextContains('.empty-title', 'There are no books'); } public function testListIsPaginated(): void { for ($id = 1; $id <= 11; ++$id) { $this->createBook($id, 'Book ' . $id); } $crawler = $this->client->request('GET', '/list'); self::assertCount(10, $crawler->filter('.tile')); $crawler = $this->client->request('GET', '/list?page=2'); self::assertCount(1, $crawler->filter('.tile')); } public function testBookCanBeAddedWithPrefilledForm(): void { $crawler = $this->client->request('GET', '/add/form?id=7&title=Prefilled'); self::assertResponseIsSuccessful(); $form = $crawler->selectButton('Save')->form(); self::assertSame('7', $form['book[id]']->getValue()); self::assertSame('Prefilled', $form['book[title]']->getValue()); $form['book[author]'] = 'Someone'; $form['book[isbn]'] = '978-83-7384-345-5'; $this->client->submit($form); self::assertResponseRedirects('/book/7'); self::assertSame('9788373843455', $this->findBook(7)?->getIsbn()); } public function testIsbnIsStoredAsATypedLabelAndCanBeClearedInTheForm(): void { $this->createBook(1)->setIsbn('9788373843455'); $this->entityManager()->flush(); $book = $this->findBook(1); self::assertSame(LabelType::ISBN, $book?->getLabels()->first()->getType()); $crawler = $this->client->request('GET', '/book/1/edit'); $form = $crawler->selectButton('Save')->form(); $form['book[isbn]'] = ''; $this->client->submit($form); self::assertCount(0, $this->findBook(1)?->getLabels() ?? []); } public function testIsbn10IsSavedAsIsbn13(): void { $crawler = $this->client->request('GET', '/add/form'); $this->client->submit($crawler->selectButton('Save')->form([ 'book[id]' => '1', 'book[title]' => 'Title', 'book[author]' => 'Author', 'book[isbn]' => '0-306-40615-2', ])); self::assertResponseRedirects('/book/1'); self::assertSame('9780306406157', $this->findBook(1)?->getIsbn()); } public function testMalformedIsbnCannotReachTheDatabase(): void { $book = new \App\Entity\Book()->setId(1)->setTitle('Title')->setAuthor('Author')->setIsbn('123'); $this->expectException(\DomainException::class); $this->entityManager()->persist($book); } public function testInvalidIsbnIsRejected(): void { $crawler = $this->client->request('GET', '/add/form'); $this->client->submit($crawler->selectButton('Save')->form([ 'book[id]' => '1', 'book[title]' => 'Title', 'book[author]' => 'Author', 'book[isbn]' => 'abc', ])); self::assertResponseStatusCodeSame(422); } public function testIdZeroIsAValidSticker(): void { $this->createBook(0, 'Zero'); $this->client->request('GET', '/book/0'); self::assertResponseIsSuccessful(); self::assertSelectorTextContains('h2', 'Zero'); } public function testIdMustBeFreeInBothCollections(): void { $this->createBook(1); $ousted = (new OustedBook('Lost'))->setId(2)->setTitle('Gone')->setAuthor('Someone'); $this->entityManager()->persist($ousted); $this->entityManager()->flush(); foreach ([1, 2] as $id) { $crawler = $this->client->request('GET', '/add/form'); $this->client->submit($crawler->selectButton('Save')->form([ 'book[id]' => (string)$id, 'book[title]' => 'Duplicate', 'book[author]' => 'Someone', ])); self::assertResponseStatusCodeSame(422); self::assertSelectorTextContains('body', 'already used by another book'); } } public function testEditKeepsTheId(): void { $this->createBook(3, 'Before'); $crawler = $this->client->request('GET', '/book/3/edit'); $form = $crawler->selectButton('Save')->form(); $form['book[title]'] = 'After'; $this->client->submit($form); self::assertResponseRedirects('/book/3'); self::assertSame('After', $this->findBook(3)?->getTitle()); } public function testUnknownBookIsNotFound(): void { $this->client->request('GET', '/book/999'); self::assertResponseStatusCodeSame(404); } public function testPolishIsServedFromAcceptLanguage(): void { $this->client->request('GET', '/list', server: ['HTTP_ACCEPT_LANGUAGE' => 'pl']); self::assertSelectorTextContains('.navbar-brand', 'Biblioteczka'); } }