Jacek Kowalski
4 hours ago 6b9278a5d57091fce636dbb640b380cfb990db6c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
declare(strict_types=1);
 
namespace App\Tests\Functional;
 
use App\Entity\OustedBook;
use App\Tests\DatabaseTestCase;
use Symfony\Component\DomCrawler\Crawler;
 
final class BulkOustTest extends DatabaseTestCase {
    protected function setUp(): void {
        parent::setUp();
 
        $this->createBook(1, 'Never seen');
        $this->createBook(2, 'Seen long ago')->setLastSeen(new \DateTimeImmutable('2026-01-10 12:00'));
        $this->createBook(3, 'Seen on the day')->setLastSeen(new \DateTimeImmutable('2026-11-01 00:00'));
        $this->createBook(4, 'Seen later')->setLastSeen(new \DateTimeImmutable('2026-11-05 18:00'));
        $this->createBook(5, 'Lent out')->lendTo('A Reader', new \DateTimeImmutable('2026-01-01'));
        $this->entityManager()->flush();
    }
 
    public function testPreviewListsBooksNotSeenSinceTheDate(): void {
        $crawler = $this->preview('2026-11-01');
 
        self::assertResponseIsSuccessful();
        self::assertSame([1, 2], $crawler->filter('.results .tile .label-primary')->each(static fn($node): int => (int)$node->text()));
        self::assertSelectorTextContains('.bulk-oust-confirm', '2 books were not seen on or after 2026-11-01');
        self::assertSelectorTextContains('.bulk-oust-borrowed', '1 borrowed books');
        self::assertNotNull($this->findBook(1));
    }
 
    public function testConfirmingOustsTheListedBooks(): void {
        $crawler = $this->preview('2026-11-01');
        $this->client->submit($crawler->selectButton('Take them all out')->form());
 
        self::assertResponseRedirects('/ousted');
        $this->client->followRedirect();
        self::assertSelectorTextContains('.flash', '2 books have been taken out');
 
        self::assertNull($this->findBook(1));
        self::assertNull($this->findBook(2));
        self::assertNotNull($this->findBook(3));
        self::assertNotNull($this->findBook(4));
        self::assertNotNull($this->findBook(5));
        self::assertSame('Inventory 2026', $this->entityManager()->find(OustedBook::class, 2)?->getReason());
    }
 
    public function testNothingIsOustedIfTheSelectionChanged(): void {
        $crawler = $this->preview('2026-11-01');
        $form = $crawler->selectButton('Take them all out')->form();
 
        // One book found and another added: the count stays the same, the books do not.
        $this->findBook(2)?->setLastSeen(new \DateTimeImmutable('2026-11-02'));
        $this->entityManager()->flush();
        $this->createBook(6, 'Added meanwhile');
        $this->client->submit($form);
 
        self::assertResponseRedirects();
        $this->client->followRedirect();
        self::assertSelectorTextContains('.flash', 'has changed');
        self::assertNotNull($this->findBook(1));
        self::assertNotNull($this->findBook(6));
    }
 
    public function testConfirmationRequiresAValidCsrfToken(): void {
        $this->client->request('POST', '/ousted/bulk', ['bulk_oust' => [
            'notSeenSince' => '2026-11-01',
            'reason' => 'Forged',
            'selection' => 'anything',
            '_token' => 'forged',
        ]]);
 
        self::assertResponseRedirects('/ousted/bulk');
        self::assertNotNull($this->findBook(1));
    }
 
    public function testPreviewWithNothingToOust(): void {
        $this->findBook(1)?->setLastSeen(new \DateTimeImmutable('2026-03-01'));
        $this->entityManager()->flush();
 
        $this->preview('2026-01-01');
 
        self::assertSelectorTextContains('.toast-success', 'Every book on the shelves was seen');
        self::assertSelectorNotExists('.bulk-oust-confirm');
    }
 
    private function preview(string $date): Crawler {
        $crawler = $this->client->request('GET', '/ousted/bulk');
 
        return $this->client->submit($crawler->selectButton('Show the books')->form([
            'bulk_oust[notSeenSince]' => $date,
            'bulk_oust[reason]' => 'Inventory 2026',
        ]));
    }
}