]> BookStack Code Mirror - bookstack/blob - tests/TestResponse.php
Apply fixes from StyleCI
[bookstack] / tests / TestResponse.php
1 <?php
2
3 namespace Tests;
4
5 use Illuminate\Foundation\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      * Assert the response contains the specified element.
31      *
32      * @return $this
33      */
34     public function assertElementExists(string $selector)
35     {
36         $elements = $this->crawler()->filter($selector);
37         PHPUnit::assertTrue(
38             $elements->count() > 0,
39             'Unable to find element matching the selector: ' . PHP_EOL . PHP_EOL .
40             "[{$selector}]" . PHP_EOL . PHP_EOL .
41             'within' . PHP_EOL . PHP_EOL .
42             "[{$this->getContent()}]."
43         );
44
45         return $this;
46     }
47
48     /**
49      * Assert the response does not contain the specified element.
50      *
51      * @return $this
52      */
53     public function assertElementNotExists(string $selector)
54     {
55         $elements = $this->crawler()->filter($selector);
56         PHPUnit::assertTrue(
57             $elements->count() === 0,
58             'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
59             "[{$selector}]" . PHP_EOL . PHP_EOL .
60             'within' . PHP_EOL . PHP_EOL .
61             "[{$this->getContent()}]."
62         );
63
64         return $this;
65     }
66
67     /**
68      * Assert the response includes a specific element containing the given text.
69      * If an nth match is provided, only that will be checked otherwise all matching
70      * elements will be checked for the given text.
71      *
72      * @return $this
73      */
74     public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
75     {
76         $elements = $this->crawler()->filter($selector);
77         $matched = false;
78         $pattern = $this->getEscapedPattern($text);
79
80         if (!is_null($nthMatch)) {
81             $elements = $elements->eq($nthMatch - 1);
82         }
83
84         foreach ($elements as $element) {
85             $element = new Crawler($element);
86             if (preg_match("/$pattern/i", $element->html())) {
87                 $matched = true;
88                 break;
89             }
90         }
91
92         PHPUnit::assertTrue(
93             $matched,
94             'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
95             ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
96             "[{$selector}]" . PHP_EOL . PHP_EOL .
97             'containing text' . PHP_EOL . PHP_EOL .
98             "[{$text}]" . PHP_EOL . PHP_EOL .
99             'within' . PHP_EOL . PHP_EOL .
100             "[{$this->getContent()}]."
101         );
102
103         return $this;
104     }
105
106     /**
107      * Assert the response does not include a specific element containing the given text.
108      * If an nth match is provided, only that will be checked otherwise all matching
109      * elements will be checked for the given text.
110      *
111      * @return $this
112      */
113     public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
114     {
115         $elements = $this->crawler()->filter($selector);
116         $matched = false;
117         $pattern = $this->getEscapedPattern($text);
118
119         if (!is_null($nthMatch)) {
120             $elements = $elements->eq($nthMatch - 1);
121         }
122
123         foreach ($elements as $element) {
124             $element = new Crawler($element);
125             if (preg_match("/$pattern/i", $element->html())) {
126                 $matched = true;
127                 break;
128             }
129         }
130
131         PHPUnit::assertTrue(
132             !$matched,
133             'Found element of selector: ' . PHP_EOL . PHP_EOL .
134             ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
135             "[{$selector}]" . PHP_EOL . PHP_EOL .
136             'containing text' . PHP_EOL . PHP_EOL .
137             "[{$text}]" . PHP_EOL . PHP_EOL .
138             'within' . PHP_EOL . PHP_EOL .
139             "[{$this->getContent()}]."
140         );
141
142         return $this;
143     }
144
145     /**
146      * Assert there's a notification within the view containing the given text.
147      *
148      * @return $this
149      */
150     public function assertNotificationContains(string $text)
151     {
152         return $this->assertElementContains('[notification]', $text);
153     }
154
155     /**
156      * Get the escaped text pattern for the constraint.
157      *
158      * @return string
159      */
160     protected function getEscapedPattern(string $text)
161     {
162         $rawPattern = preg_quote($text, '/');
163         $escapedPattern = preg_quote(e($text), '/');
164
165         return $rawPattern == $escapedPattern
166             ? $rawPattern : "({$rawPattern}|{$escapedPattern})";
167     }
168 }