<?php
|
declare(strict_types=1);
|
|
namespace App\Tests\Functional;
|
|
use App\Entity\OustedBook;
|
use App\Enum\LabelType;
|
use App\Tests\DatabaseTestCase;
|
|
final class BookTest extends DatabaseTestCase {
|
public function testEmptyListInvitesToAddABook(): void {
|
$this->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');
|
}
|
}
|