Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
LibraryUpdateBookContext
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
9 / 9
13
100.00% covered (success)
100.00%
1 / 1
 whenIUpdateTheBook
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
5
 thenTheHtmlPageShouldRaiseAnException
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldBeRedirected
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldNotBeRedirected
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldSeeAnErrorMessage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 iTheBookFieldShoudBe
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 iShouldSee
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 iShouldSeeASubmitButton
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getRepository
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10namespace Tests\AppDemo\Acceptance;
11
12use AppDemo\Library\Application\Http\UpdateBookController as UpdateBookControllerHtml;
13use AppDemo\Library\Domain\BookRepository;
14use Assert\Assert;
15use Behat\Step\Then;
16use Behat\Step\When;
17use Exception;
18use Nyholm\Psr7\Response;
19use Nyholm\Psr7\ServerRequest as Request;
20use Phexium\Domain\Id\TimestampId;
21use Tests\AppDemo\Acceptance\Trait\BrowsePageTrait;
22
23final class LibraryUpdateBookContext extends BehatContext
24{
25    use BrowsePageTrait;
26
27    private Response $response;
28
29    private TimestampId $bookId;
30
31    private Exception $exception;
32
33    #[When('I update the book ID=:id with :field ":value"')]
34    public function whenIUpdateTheBook(int $id, string $field, string $value): void
35    {
36        $controller = self::$container->get(UpdateBookControllerHtml::class);
37
38        $this->bookId = TimestampId::from($id);
39        $book = $this->getRepository()->findById($this->bookId);
40
41        $request = new Request('POST', '/');
42        $request = $request->withParsedBody([
43            'title' => $field === 'title' ? $value : $book?->getTitle()->getValue(),
44            'author' => $field === 'author' ? $value : $book?->getAuthor()->getValue(),
45            'isbn' => $field === 'isbn' ? $value : $book?->getIsbn()->getValue(),
46            'status' => $book?->getStatus()->value,
47        ]);
48
49        try {
50            $this->response = $controller->updateBook($request, new Response(), ['id' => $id]);
51        } catch (Exception $exception) {
52            $this->exception = $exception;
53        }
54    }
55
56    #[Then('the HTML page should raise an exception ":message"')]
57    public function thenTheHtmlPageShouldRaiseAnException(string $message): void
58    {
59        Assert::that($this->exception)->isInstanceOf(Exception::class);
60        Assert::that($this->exception->getMessage())->same($message);
61    }
62
63    #[Then('I should be redirected')]
64    public function thenIShouldBeRedirected(): void
65    {
66        Assert::that($this->response->getStatusCode())->same(302);
67    }
68
69    #[Then('I should not be redirected')]
70    public function thenIShouldNotBeRedirected(): void
71    {
72        Assert::that($this->response->getStatusCode())->notSame(302);
73    }
74
75    #[Then('I should see an error message ":errorMessage"')]
76    public function thenIShouldSeeAnErrorMessage(string $errorMessage): void
77    {
78        $body = (string) $this->response->getBody();
79        Assert::that($body)->contains(htmlentities($errorMessage));
80    }
81
82    #[Then('/the book (title|author|isbn) should be "(.*)"/')]
83    public function iTheBookFieldShoudBe(string $fieldName, string $fieldValue): void
84    {
85        $book = $this->getRepository()->findById($this->bookId);
86
87        Assert::that((string) $book->{'get'.ucfirst($fieldName)}())->same($fieldValue);
88    }
89
90    #[Then('I should see :text')]
91    public function iShouldSee(string $text): void
92    {
93        $body = (string) $this->response->getBody();
94        Assert::that($body)->contains($text);
95    }
96
97    #[Then('I should see a submit button')]
98    public function iShouldSeeASubmitButton(): void
99    {
100        $body = (string) $this->response->getBody();
101        Assert::that($body)->contains('<button');
102        Assert::that($body)->contains('type="submit"');
103    }
104
105    private function getRepository(): BookRepository
106    {
107        return self::$container->get(BookRepository::class);
108    }
109}