Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
13 / 13
CRAP
100.00% covered (success)
100.00%
1 / 1
LibraryDetailBookContext
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
13 / 13
15
100.00% covered (success)
100.00%
1 / 1
 whenICallTheDetailBookApiForBookId
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 thenIShouldGetTheBookTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldGetTheBookAuthor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldGetTheBookIsbn
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldGetTheBookStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldSeeTheEditButton
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 thenIShouldSeeTheBookTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldSeeTheBookAuthor
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldSeeTheBookIsbn
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldSeeTheBookStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 thenAnExceptionShouldBeRaised
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldGetTheBookInfo
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 thenIShouldSeeTheBookInfo
100.00% covered (success)
100.00%
2 / 2
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\Api\DetailBookController;
13use Assert\Assert;
14use Behat\Step\Then;
15use Behat\Step\When;
16use Exception;
17use Nyholm\Psr7\Response;
18use Nyholm\Psr7\ServerRequest as Request;
19use Tests\AppDemo\Acceptance\Trait\BrowsePageTrait;
20
21final class LibraryDetailBookContext extends BehatContext
22{
23    use BrowsePageTrait;
24
25    private Response $response;
26
27    private Exception $exception;
28
29    #[When('I call the Detail Book API for book ID :id')]
30    public function whenICallTheDetailBookApiForBookId(int $id): void
31    {
32        $controller = self::$container->get(DetailBookController::class);
33
34        try {
35            $this->response = $controller->index(new Request('get', '/'), new Response(), ['id' => $id]);
36        } catch (Exception $exception) {
37            $this->exception = $exception;
38        }
39    }
40
41    #[Then('I should get the book title ":title"')]
42    public function thenIShouldGetTheBookTitle(string $title): void
43    {
44        $this->thenIShouldGetTheBookInfo('title', $title);
45    }
46
47    #[Then('I should get the book author ":author"')]
48    public function thenIShouldGetTheBookAuthor(string $author): void
49    {
50        $this->thenIShouldGetTheBookInfo('author', $author);
51    }
52
53    #[Then('I should get the book ISBN ":isbn"')]
54    public function thenIShouldGetTheBookIsbn(string $isbn): void
55    {
56        $this->thenIShouldGetTheBookInfo('isbn', $isbn);
57    }
58
59    #[Then('I should get the book status ":status"')]
60    public function thenIShouldGetTheBookStatus(string $status): void
61    {
62        $this->thenIShouldGetTheBookInfo('status', $status);
63    }
64
65    #[Then('/I should (not )?see the edit button/')]
66    public function thenIShouldSeeTheEditButton(bool $not = false): void
67    {
68        $body = (string) $this->response->getBody();
69
70        if ($not === false) {
71            Assert::that($body)->contains('Edit book');
72        } else {
73            Assert::that($body)->notContains('Edit book');
74        }
75    }
76
77    #[Then('I should see the book title ":title"')]
78    public function thenIShouldSeeTheBookTitle(string $title): void
79    {
80        $this->thenIShouldSeeTheBookInfo($title);
81    }
82
83    #[Then('I should see the book author ":title"')]
84    public function thenIShouldSeeTheBookAuthor(string $author): void
85    {
86        $this->thenIShouldSeeTheBookInfo($author);
87    }
88
89    #[Then('I should see the book ISBN ":isbn"')]
90    public function thenIShouldSeeTheBookIsbn(string $isbn): void
91    {
92        $this->thenIShouldSeeTheBookInfo($isbn);
93    }
94
95    #[Then('I should see the book status ":status"')]
96    public function thenIShouldSeeTheBookStatus(string $status): void
97    {
98        $this->thenIShouldSeeTheBookInfo($status);
99    }
100
101    #[Then('an exception ":message" should be raised')]
102    public function thenAnExceptionShouldBeRaised(string $message): void
103    {
104        Assert::that($this->exception)->isInstanceOf(Exception::class);
105        Assert::that($this->exception->getMessage())->same($message);
106    }
107
108    private function thenIShouldGetTheBookInfo(string $name, string $value): void
109    {
110        $body = (string) $this->response->getBody();
111        $data = json_decode($body, true);
112        Assert::that($data)->keyExists('book');
113        $book = $data['book'];
114
115        Assert::that($book)->keyExists($name);
116        Assert::that($book[$name])->same($value);
117    }
118
119    private function thenIShouldSeeTheBookInfo(string $value): void
120    {
121        $body = (string) $this->response->getBody();
122
123        Assert::that($body)->contains(htmlentities($value));
124    }
125}