]> BookStack Code Mirror - bookstack/blobdiff - tests/TestResponse.php
Fixed failing webhook test cases
[bookstack] / tests / TestResponse.php
index a68a5783fa044c881bfbf8fa39b66355128ae8be..4e53aa020ba3ca5054e8d75e14a2ed57dc277276 100644 (file)
@@ -1,33 +1,42 @@
-<?php namespace Tests;
+<?php
 
-use \Illuminate\Foundation\Testing\TestResponse as BaseTestResponse;
-use Symfony\Component\DomCrawler\Crawler;
+namespace Tests;
+
+use Illuminate\Testing\TestResponse as BaseTestResponse;
 use PHPUnit\Framework\Assert as PHPUnit;
+use Symfony\Component\DomCrawler\Crawler;
 
 /**
  * Class TestResponse
  * Custom extension of the default Laravel TestResponse class.
- * @package Tests
  */
-class TestResponse extends BaseTestResponse {
-
+class TestResponse extends BaseTestResponse
+{
     protected $crawlerInstance;
 
     /**
      * Get the DOM Crawler for the response content.
-     * @return Crawler
      */
-    protected function crawler()
+    protected function crawler(): Crawler
     {
         if (!is_object($this->crawlerInstance)) {
             $this->crawlerInstance = new Crawler($this->getContent());
         }
+
         return $this->crawlerInstance;
     }
 
+    /**
+     * Get the HTML of the first element at the given selector.
+     */
+    public function getElementHtml(string $selector): string
+    {
+        return $this->crawler()->filter($selector)->first()->outerHtml();
+    }
+
     /**
      * Assert the response contains the specified element.
-     * @param string $selector
+     *
      * @return $this
      */
     public function assertElementExists(string $selector)
@@ -35,17 +44,38 @@ class TestResponse extends BaseTestResponse {
         $elements = $this->crawler()->filter($selector);
         PHPUnit::assertTrue(
             $elements->count() > 0,
-            'Unable to find element matching the selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Unable to find element matching the selector: ' . PHP_EOL . PHP_EOL .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
+            "[{$this->getContent()}]."
+        );
+
+        return $this;
+    }
+
+    /**
+     * Assert the response contains the given count of elements
+     * that match the given css selector.
+     *
+     * @return $this
+     */
+    public function assertElementCount(string $selector, int $count)
+    {
+        $elements = $this->crawler()->filter($selector);
+        PHPUnit::assertTrue(
+            $elements->count() === $count,
+            'Unable to ' . $count . ' element(s) matching the selector: ' . PHP_EOL . PHP_EOL .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'found ' . $elements->count() . ' within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
+
         return $this;
     }
 
     /**
      * Assert the response does not contain the specified element.
-     * @param string $selector
+     *
      * @return $this
      */
     public function assertElementNotExists(string $selector)
@@ -53,25 +83,32 @@ class TestResponse extends BaseTestResponse {
         $elements = $this->crawler()->filter($selector);
         PHPUnit::assertTrue(
             $elements->count() === 0,
-            'Found elements matching the selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Found elements matching the selector: ' . PHP_EOL . PHP_EOL .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
+
         return $this;
     }
 
     /**
      * Assert the response includes a specific element containing the given text.
-     * @param string $selector
-     * @param string $text
+     * If an nth match is provided, only that will be checked otherwise all matching
+     * elements will be checked for the given text.
+     *
      * @return $this
      */
-    public function assertElementContains(string $selector, string $text)
+    public function assertElementContains(string $selector, string $text, ?int $nthMatch = null)
     {
         $elements = $this->crawler()->filter($selector);
         $matched = false;
         $pattern = $this->getEscapedPattern($text);
+
+        if (!is_null($nthMatch)) {
+            $elements = $elements->eq($nthMatch - 1);
+        }
+
         foreach ($elements as $element) {
             $element = new Crawler($element);
             if (preg_match("/$pattern/i", $element->html())) {
@@ -82,11 +119,12 @@ class TestResponse extends BaseTestResponse {
 
         PHPUnit::assertTrue(
             $matched,
-            'Unable to find element of selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'containing text'.PHP_EOL.PHP_EOL.
-            "[{$text}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Unable to find element of selector: ' . PHP_EOL . PHP_EOL .
+            ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'containing text' . PHP_EOL . PHP_EOL .
+            "[{$text}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
 
@@ -95,15 +133,21 @@ class TestResponse extends BaseTestResponse {
 
     /**
      * Assert the response does not include a specific element containing the given text.
-     * @param string $selector
-     * @param string $text
+     * If an nth match is provided, only that will be checked otherwise all matching
+     * elements will be checked for the given text.
+     *
      * @return $this
      */
-    public function assertElementNotContains(string $selector, string $text)
+    public function assertElementNotContains(string $selector, string $text, ?int $nthMatch = null)
     {
         $elements = $this->crawler()->filter($selector);
         $matched = false;
         $pattern = $this->getEscapedPattern($text);
+
+        if (!is_null($nthMatch)) {
+            $elements = $elements->eq($nthMatch - 1);
+        }
+
         foreach ($elements as $element) {
             $element = new Crawler($element);
             if (preg_match("/$pattern/i", $element->html())) {
@@ -114,28 +158,39 @@ class TestResponse extends BaseTestResponse {
 
         PHPUnit::assertTrue(
             !$matched,
-            'Found element of selector: '.PHP_EOL.PHP_EOL.
-            "[{$selector}]".PHP_EOL.PHP_EOL.
-            'containing text'.PHP_EOL.PHP_EOL.
-            "[{$text}]".PHP_EOL.PHP_EOL.
-            'within'.PHP_EOL.PHP_EOL.
+            'Found element of selector: ' . PHP_EOL . PHP_EOL .
+            ($nthMatch ? ("at position {$nthMatch}" . PHP_EOL . PHP_EOL) : '') .
+            "[{$selector}]" . PHP_EOL . PHP_EOL .
+            'containing text' . PHP_EOL . PHP_EOL .
+            "[{$text}]" . PHP_EOL . PHP_EOL .
+            'within' . PHP_EOL . PHP_EOL .
             "[{$this->getContent()}]."
         );
 
         return $this;
     }
 
+    /**
+     * Assert there's a notification within the view containing the given text.
+     *
+     * @return $this
+     */
+    public function assertNotificationContains(string $text)
+    {
+        return $this->assertElementContains('[notification]', $text);
+    }
+
     /**
      * Get the escaped text pattern for the constraint.
-     * @param  string  $text
+     *
      * @return string
      */
-    protected function getEscapedPattern($text)
+    protected function getEscapedPattern(string $text)
     {
         $rawPattern = preg_quote($text, '/');
         $escapedPattern = preg_quote(e($text), '/');
+
         return $rawPattern == $escapedPattern
             ? $rawPattern : "({$rawPattern}|{$escapedPattern})";
     }
-
 }