]> BookStack Code Mirror - bookstack/blob - tests/TestResponse.php
Fix Crowdin name in the language_request issue template
[bookstack] / tests / TestResponse.php
1 <?php
2
3 namespace Tests;
4
5 use Illuminate\Testing\TestResponse as BaseTestResponse;
6 use PHPUnit\Framework\Assert as PHPUnit;
7 use Symfony\Component\DomCrawler\Crawler;
8
9 /**
10  * Class TestResponse
11  * Custom extension of the default Laravel TestResponse class.
12  */
13 class TestResponse extends BaseTestResponse
14 {
15     protected $crawlerInstance;
16
17     /**
18      * Get the DOM Crawler for the response content.
19      */
20     protected function crawler(): Crawler
21     {
22         if (!is_object($this->crawlerInstance)) {
23             $this->crawlerInstance = new Crawler($this->getContent());
24         }
25
26         return $this->crawlerInstance;
27     }
28
29     /**
30      * Get the HTML of the first element at the given selector.
31      */
32     public function getElementHtml(string $selector): string
33     {
34         return $this->crawler()->filter($selector)->first()->outerHtml();
35     }
36
37     /**
38      * Assert the response contains the specified element.
39      *
40      * @return $this
41      */
42     public function assertElementExists(string $selector)
43     {
44         $elements = $this->crawler()->filter($selector);
45         PHPUnit::assertTrue(
46             $elements->count() > 0,
47             'Unable to find element matching the selector: ' . PHP_EOL . PHP_EOL .
48             "[{$selector}]" . PHP_EOL . PHP_EOL .
49             'within' . PHP_EOL . PHP_EOL .
50             "[{$this->getContent()}]."
51         );
52
53         return $this;
54     }
55
56     /**
57      * Assert the response contains the given count of elements
58      * that match the given css selector.
59      *
60      * @return $this
61      */
62     public function assertElementCount(string $selector, int $count)
63     {
64         $elements = $this->crawler()->filter($selector);
65         PHPUnit::assertTrue(
66             $elements->count() === $count,
67             'Unable to ' . $count . ' element(s) matching the selector: ' . PHP_EOL . PHP_EOL .
68             "[{$selector}]" . PHP_EOL . PHP_EOL .
69             'found ' . $elements->count() . ' within' . PHP_EOL . PHP_EOL .
70             "[{$this->getContent()}]."
71         );
72
73         return $this;
74     }
75
76     /**
77      * Assert the response does not contain the specified element.
78      *
79      * @return $this
80      */
81     public function assertElementNotExists(string $selector)
82     {
83         $elements = $this->crawler()->filter($selector);
84         PHPUnit::assertTrue(
85             $elements->count() === 0,
86             'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
87             "[{$selector}]" . PHP_EOL . PHP_EOL .
88             'within' . PHP_EOL . PHP_EOL .
89             "[{$this->getContent()}]."
90         );
91
92         return $this;
93     }
94
95     /**
96      * Assert the response includes a specific element containing the given text.
97      * If an nth match is provided, only that will be checked otherwise all matching
98      * elements will be checked for the given text.
99      *
100      * @return $this
101      */
102     public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
103     {
104         $elements = $this->crawler()->filter($selector);
105         $matched = false;
106         $pattern = $this->getEscapedPattern($text);
107
108         if (!is_null($nthMatch)) {
109             $elements = $elements->eq($nthMatch - 1);
110         }
111
112         foreach ($elements as $element) {
113             $element = new Crawler($element);
114             if (preg_match("/$pattern/i", $element->text())) {
115                 $matched = true;
116                 break;
117             }
118         }
119
120         PHPUnit::assertTrue(
121             $matched,
122             'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
123             ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
124             "[{$selector}]" . PHP_EOL . PHP_EOL .
125             'containing text' . PHP_EOL . PHP_EOL .
126             "[{$text}]" . PHP_EOL . PHP_EOL .
127             'within' . PHP_EOL . PHP_EOL .
128             "[{$this->getContent()}]."
129         );
130
131         return $this;
132     }
133
134     /**
135      * Assert the response does not include a specific element containing the given text.
136      * If an nth match is provided, only that will be checked otherwise all matching
137      * elements will be checked for the given text.
138      *
139      * @return $this
140      */
141     public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
142     {
143         $elements = $this->crawler()->filter($selector);
144         $matched = false;
145         $pattern = $this->getEscapedPattern($text);
146
147         if (!is_null($nthMatch)) {
148             $elements = $elements->eq($nthMatch - 1);
149         }
150
151         foreach ($elements as $element) {
152             $element = new Crawler($element);
153             if (preg_match("/$pattern/i", $element->html())) {
154                 $matched = true;
155                 break;
156             }
157         }
158
159         PHPUnit::assertTrue(
160             !$matched,
161             'Found element of selector: ' . PHP_EOL . PHP_EOL .
162             ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
163             "[{$selector}]" . PHP_EOL . PHP_EOL .
164             'containing text' . PHP_EOL . PHP_EOL .
165             "[{$text}]" . PHP_EOL . PHP_EOL .
166             'within' . PHP_EOL . PHP_EOL .
167             "[{$this->getContent()}]."
168         );
169
170         return $this;
171     }
172
173     /**
174      * Assert there's a notification within the view containing the given text.
175      *
176      * @return $this
177      */
178     public function assertNotificationContains(string $text)
179     {
180         return $this->assertElementContains('[notification]', $text);
181     }
182
183     /**
184      * Get the escaped text pattern for the constraint.
185      *
186      * @return string
187      */
188     protected function getEscapedPattern(string $text)
189     {
190         $rawPattern = preg_quote($text, '/');
191         $escapedPattern = preg_quote(e($text), '/');
192
193         return $rawPattern == $escapedPattern
194             ? $rawPattern : "({$rawPattern}|{$escapedPattern})";
195     }
196 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.