"Fossies" - the Fresh Open Source Software Archive

Member "framework-8.65.0/src/Illuminate/Testing/AssertableJsonString.php" (19 Oct 2021, 10052 Bytes) of package /linux/www/laravel-framework-8.65.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "AssertableJsonString.php": 8.58.0_vs_8.59.0.

    1 <?php
    2 
    3 namespace Illuminate\Testing;
    4 
    5 use ArrayAccess;
    6 use Countable;
    7 use Illuminate\Contracts\Support\Jsonable;
    8 use Illuminate\Support\Arr;
    9 use Illuminate\Support\Str;
   10 use Illuminate\Testing\Assert as PHPUnit;
   11 use JsonSerializable;
   12 
   13 class AssertableJsonString implements ArrayAccess, Countable
   14 {
   15     /**
   16      * The original encoded json.
   17      *
   18      * @var \Illuminate\Contracts\Support\Jsonable|\JsonSerializable|array
   19      */
   20     public $json;
   21 
   22     /**
   23      * The decoded json contents.
   24      *
   25      * @var array|null
   26      */
   27     protected $decoded;
   28 
   29     /**
   30      * Create a new assertable JSON string instance.
   31      *
   32      * @param  \Illuminate\Contracts\Support\Jsonable|\JsonSerializable|array|string  $jsonable
   33      * @return void
   34      */
   35     public function __construct($jsonable)
   36     {
   37         $this->json = $jsonable;
   38 
   39         if ($jsonable instanceof JsonSerializable) {
   40             $this->decoded = $jsonable->jsonSerialize();
   41         } elseif ($jsonable instanceof Jsonable) {
   42             $this->decoded = json_decode($jsonable->toJson(), true);
   43         } elseif (is_array($jsonable)) {
   44             $this->decoded = $jsonable;
   45         } else {
   46             $this->decoded = json_decode($jsonable, true);
   47         }
   48     }
   49 
   50     /**
   51      * Validate and return the decoded response JSON.
   52      *
   53      * @param  string|null  $key
   54      * @return mixed
   55      */
   56     public function json($key = null)
   57     {
   58         return data_get($this->decoded, $key);
   59     }
   60 
   61     /**
   62      * Assert that the response JSON has the expected count of items at the given key.
   63      *
   64      * @param  int  $count
   65      * @param  string|null  $key
   66      * @return $this
   67      */
   68     public function assertCount(int $count, $key = null)
   69     {
   70         if (! is_null($key)) {
   71             PHPUnit::assertCount(
   72                 $count, data_get($this->decoded, $key),
   73                 "Failed to assert that the response count matched the expected {$count}"
   74             );
   75 
   76             return $this;
   77         }
   78 
   79         PHPUnit::assertCount($count,
   80             $this->decoded,
   81             "Failed to assert that the response count matched the expected {$count}"
   82         );
   83 
   84         return $this;
   85     }
   86 
   87     /**
   88      * Assert that the response has the exact given JSON.
   89      *
   90      * @param  array  $data
   91      * @return $this
   92      */
   93     public function assertExact(array $data)
   94     {
   95         $actual = $this->reorderAssocKeys((array) $this->decoded);
   96 
   97         $expected = $this->reorderAssocKeys($data);
   98 
   99         PHPUnit::assertEquals(
  100             json_encode($expected, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES),
  101             json_encode($actual, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
  102         );
  103 
  104         return $this;
  105     }
  106 
  107     /**
  108      * Assert that the response has the similar JSON as given.
  109      *
  110      * @param  array  $data
  111      * @return $this
  112      */
  113     public function assertSimilar(array $data)
  114     {
  115         $actual = json_encode(Arr::sortRecursive(
  116             (array) $this->decoded
  117         ));
  118 
  119         PHPUnit::assertEquals(json_encode(Arr::sortRecursive($data)), $actual);
  120 
  121         return $this;
  122     }
  123 
  124     /**
  125      * Assert that the response contains the given JSON fragment.
  126      *
  127      * @param  array  $data
  128      * @return $this
  129      */
  130     public function assertFragment(array $data)
  131     {
  132         $actual = json_encode(Arr::sortRecursive(
  133             (array) $this->decoded
  134         ));
  135 
  136         foreach (Arr::sortRecursive($data) as $key => $value) {
  137             $expected = $this->jsonSearchStrings($key, $value);
  138 
  139             PHPUnit::assertTrue(
  140                 Str::contains($actual, $expected),
  141                 'Unable to find JSON fragment: '.PHP_EOL.PHP_EOL.
  142                 '['.json_encode([$key => $value]).']'.PHP_EOL.PHP_EOL.
  143                 'within'.PHP_EOL.PHP_EOL.
  144                 "[{$actual}]."
  145             );
  146         }
  147 
  148         return $this;
  149     }
  150 
  151     /**
  152      * Assert that the response does not contain the given JSON fragment.
  153      *
  154      * @param  array  $data
  155      * @param  bool  $exact
  156      * @return $this
  157      */
  158     public function assertMissing(array $data, $exact = false)
  159     {
  160         if ($exact) {
  161             return $this->assertMissingExact($data);
  162         }
  163 
  164         $actual = json_encode(Arr::sortRecursive(
  165             (array) $this->decoded
  166         ));
  167 
  168         foreach (Arr::sortRecursive($data) as $key => $value) {
  169             $unexpected = $this->jsonSearchStrings($key, $value);
  170 
  171             PHPUnit::assertFalse(
  172                 Str::contains($actual, $unexpected),
  173                 'Found unexpected JSON fragment: '.PHP_EOL.PHP_EOL.
  174                 '['.json_encode([$key => $value]).']'.PHP_EOL.PHP_EOL.
  175                 'within'.PHP_EOL.PHP_EOL.
  176                 "[{$actual}]."
  177             );
  178         }
  179 
  180         return $this;
  181     }
  182 
  183     /**
  184      * Assert that the response does not contain the exact JSON fragment.
  185      *
  186      * @param  array  $data
  187      * @return $this
  188      */
  189     public function assertMissingExact(array $data)
  190     {
  191         $actual = json_encode(Arr::sortRecursive(
  192             (array) $this->decoded
  193         ));
  194 
  195         foreach (Arr::sortRecursive($data) as $key => $value) {
  196             $unexpected = $this->jsonSearchStrings($key, $value);
  197 
  198             if (! Str::contains($actual, $unexpected)) {
  199                 return $this;
  200             }
  201         }
  202 
  203         PHPUnit::fail(
  204             'Found unexpected JSON fragment: '.PHP_EOL.PHP_EOL.
  205             '['.json_encode($data).']'.PHP_EOL.PHP_EOL.
  206             'within'.PHP_EOL.PHP_EOL.
  207             "[{$actual}]."
  208         );
  209 
  210         return $this;
  211     }
  212 
  213     /**
  214      * Assert that the expected value and type exists at the given path in the response.
  215      *
  216      * @param  string  $path
  217      * @param  mixed  $expect
  218      * @return $this
  219      */
  220     public function assertPath($path, $expect)
  221     {
  222         PHPUnit::assertSame($expect, $this->json($path));
  223 
  224         return $this;
  225     }
  226 
  227     /**
  228      * Assert that the response has a given JSON structure.
  229      *
  230      * @param  array|null  $structure
  231      * @param  array|null  $responseData
  232      * @return $this
  233      */
  234     public function assertStructure(array $structure = null, $responseData = null)
  235     {
  236         if (is_null($structure)) {
  237             return $this->assertSimilar($this->decoded);
  238         }
  239 
  240         if (! is_null($responseData)) {
  241             return (new static($responseData))->assertStructure($structure);
  242         }
  243 
  244         foreach ($structure as $key => $value) {
  245             if (is_array($value) && $key === '*') {
  246                 PHPUnit::assertIsArray($this->decoded);
  247 
  248                 foreach ($this->decoded as $responseDataItem) {
  249                     $this->assertStructure($structure['*'], $responseDataItem);
  250                 }
  251             } elseif (is_array($value)) {
  252                 PHPUnit::assertArrayHasKey($key, $this->decoded);
  253 
  254                 $this->assertStructure($structure[$key], $this->decoded[$key]);
  255             } else {
  256                 PHPUnit::assertArrayHasKey($value, $this->decoded);
  257             }
  258         }
  259 
  260         return $this;
  261     }
  262 
  263     /**
  264      * Assert that the response is a superset of the given JSON.
  265      *
  266      * @param  array  $data
  267      * @param  bool  $strict
  268      * @return $this
  269      */
  270     public function assertSubset(array $data, $strict = false)
  271     {
  272         PHPUnit::assertArraySubset(
  273             $data, $this->decoded, $strict, $this->assertJsonMessage($data)
  274         );
  275 
  276         return $this;
  277     }
  278 
  279     /**
  280      * Reorder associative array keys to make it easy to compare arrays.
  281      *
  282      * @param  array  $data
  283      * @return array
  284      */
  285     protected function reorderAssocKeys(array $data)
  286     {
  287         $data = Arr::dot($data);
  288         ksort($data);
  289 
  290         $result = [];
  291 
  292         foreach ($data as $key => $value) {
  293             Arr::set($result, $key, $value);
  294         }
  295 
  296         return $result;
  297     }
  298 
  299     /**
  300      * Get the assertion message for assertJson.
  301      *
  302      * @param  array  $data
  303      * @return string
  304      */
  305     protected function assertJsonMessage(array $data)
  306     {
  307         $expected = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  308 
  309         $actual = json_encode($this->decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
  310 
  311         return 'Unable to find JSON: '.PHP_EOL.PHP_EOL.
  312             "[{$expected}]".PHP_EOL.PHP_EOL.
  313             'within response JSON:'.PHP_EOL.PHP_EOL.
  314             "[{$actual}].".PHP_EOL.PHP_EOL;
  315     }
  316 
  317     /**
  318      * Get the strings we need to search for when examining the JSON.
  319      *
  320      * @param  string  $key
  321      * @param  string  $value
  322      * @return array
  323      */
  324     protected function jsonSearchStrings($key, $value)
  325     {
  326         $needle = substr(json_encode([$key => $value]), 1, -1);
  327 
  328         return [
  329             $needle.']',
  330             $needle.'}',
  331             $needle.',',
  332         ];
  333     }
  334 
  335     /**
  336      * Get the total number of items in the underlying JSON array.
  337      *
  338      * @return int
  339      */
  340     #[\ReturnTypeWillChange]
  341     public function count()
  342     {
  343         return count($this->decoded);
  344     }
  345 
  346     /**
  347      * Determine whether an offset exists.
  348      *
  349      * @param  mixed  $offset
  350      * @return bool
  351      */
  352     #[\ReturnTypeWillChange]
  353     public function offsetExists($offset)
  354     {
  355         return isset($this->decoded[$offset]);
  356     }
  357 
  358     /**
  359      * Get the value at the given offset.
  360      *
  361      * @param  string  $offset
  362      * @return mixed
  363      */
  364     #[\ReturnTypeWillChange]
  365     public function offsetGet($offset)
  366     {
  367         return $this->decoded[$offset];
  368     }
  369 
  370     /**
  371      * Set the value at the given offset.
  372      *
  373      * @param  string  $offset
  374      * @param  mixed  $value
  375      * @return void
  376      */
  377     #[\ReturnTypeWillChange]
  378     public function offsetSet($offset, $value)
  379     {
  380         $this->decoded[$offset] = $value;
  381     }
  382 
  383     /**
  384      * Unset the value at the given offset.
  385      *
  386      * @param  string  $offset
  387      * @return void
  388      */
  389     #[\ReturnTypeWillChange]
  390     public function offsetUnset($offset)
  391     {
  392         unset($this->decoded[$offset]);
  393     }
  394 }