Completed
Push — master ( 540c35...e2a6ad )
by Mark
21s
created

IntegrationTestTrait::setupServer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11
 * @since         3.7.0
12
 * @license       https://opensource.org/licenses/mit-license.php MIT License
13
 */
14
namespace Cake\TestSuite;
15
16
use Cake\Core\Configure;
17
use Cake\Database\Exception as DatabaseException;
18
use Cake\Http\ServerRequest;
19
use Cake\Http\Session;
20
use Cake\Routing\Router;
21
use Cake\TestSuite\Constraint\Response\BodyContains;
22
use Cake\TestSuite\Constraint\Response\BodyEmpty;
23
use Cake\TestSuite\Constraint\Response\BodyEquals;
24
use Cake\TestSuite\Constraint\Response\BodyNotContains;
25
use Cake\TestSuite\Constraint\Response\BodyNotEmpty;
26
use Cake\TestSuite\Constraint\Response\BodyNotEquals;
27
use Cake\TestSuite\Constraint\Response\BodyNotRegExp;
28
use Cake\TestSuite\Constraint\Response\BodyRegExp;
29
use Cake\TestSuite\Constraint\Response\ContentType;
30
use Cake\TestSuite\Constraint\Response\CookieEncryptedEquals;
31
use Cake\TestSuite\Constraint\Response\CookieEquals;
32
use Cake\TestSuite\Constraint\Response\CookieNotSet;
33
use Cake\TestSuite\Constraint\Response\CookieSet;
34
use Cake\TestSuite\Constraint\Response\FileSent;
35
use Cake\TestSuite\Constraint\Response\FileSentAs;
36
use Cake\TestSuite\Constraint\Response\HeaderContains;
37
use Cake\TestSuite\Constraint\Response\HeaderEquals;
38
use Cake\TestSuite\Constraint\Response\HeaderNotContains;
39
use Cake\TestSuite\Constraint\Response\HeaderNotSet;
40
use Cake\TestSuite\Constraint\Response\HeaderSet;
41
use Cake\TestSuite\Constraint\Response\StatusCode;
42
use Cake\TestSuite\Constraint\Response\StatusError;
43
use Cake\TestSuite\Constraint\Response\StatusFailure;
44
use Cake\TestSuite\Constraint\Response\StatusOk;
45
use Cake\TestSuite\Constraint\Response\StatusSuccess;
46
use Cake\TestSuite\Constraint\Session\FlashParamEquals;
47
use Cake\TestSuite\Constraint\Session\SessionEquals;
48
use Cake\TestSuite\Constraint\View\LayoutFileEquals;
49
use Cake\TestSuite\Constraint\View\TemplateFileEquals;
50
use Cake\TestSuite\Stub\TestExceptionRenderer;
51
use Cake\Utility\CookieCryptTrait;
52
use Cake\Utility\Hash;
53
use Cake\Utility\Security;
54
use Cake\Utility\Text;
55
use Cake\View\Helper\SecureFieldTokenTrait;
56
use Exception;
57
use LogicException;
58
use PHPUnit\Exception as PhpunitException;
59
60
/**
61
 * A trait intended to make integration tests of your controllers easier.
62
 *
63
 * This test class provides a number of helper methods and features
64
 * that make dispatching requests and checking their responses simpler.
65
 * It favours full integration tests over mock objects as you can test
66
 * more of your code easily and avoid some of the maintenance pitfalls
67
 * that mock objects create.
68
 */
69
trait IntegrationTestTrait
70
{
71
    use CookieCryptTrait;
72
    use SecureFieldTokenTrait;
73
74
    /**
75
     * Track whether or not tests are run against
76
     * the PSR7 HTTP stack.
77
     *
78
     * @var bool
79
     */
80
    protected $_useHttpServer = false;
81
82
    /**
83
     * The customized application class name.
84
     *
85
     * @var string|null
86
     */
87
    protected $_appClass;
88
89
    /**
90
     * The customized application constructor arguments.
91
     *
92
     * @var array|null
93
     */
94
    protected $_appArgs;
95
96
    /**
97
     * The data used to build the next request.
98
     *
99
     * @var array
100
     */
101
    protected $_request = [];
102
103
    /**
104
     * The response for the most recent request.
105
     *
106
     * @var \Cake\Http\Response|null
107
     */
108
    protected $_response;
109
110
    /**
111
     * The exception being thrown if the case.
112
     *
113
     * @var \Exception|null
114
     */
115
    protected $_exception;
116
117
    /**
118
     * Session data to use in the next request.
119
     *
120
     * @var array
121
     */
122
    protected $_session = [];
123
124
    /**
125
     * Cookie data to use in the next request.
126
     *
127
     * @var array
128
     */
129
    protected $_cookie = [];
130
131
    /**
132
     * The controller used in the last request.
133
     *
134
     * @var \Cake\Controller\Controller|null
135
     */
136
    protected $_controller;
137
138
    /**
139
     * The last rendered view
140
     *
141
     * @var string|null
142
     */
143
    protected $_viewName;
144
145
    /**
146
     * The last rendered layout
147
     *
148
     * @var string|null
149
     */
150
    protected $_layoutName;
151
152
    /**
153
     * The session instance from the last request
154
     *
155
     * @var \Cake\Http\Session|null
156
     */
157
    protected $_requestSession;
158
159
    /**
160
     * Boolean flag for whether or not the request should have
161
     * a SecurityComponent token added.
162
     *
163
     * @var bool
164
     */
165
    protected $_securityToken = false;
166
167
    /**
168
     * Boolean flag for whether or not the request should have
169
     * a CSRF token added.
170
     *
171
     * @var bool
172
     */
173
    protected $_csrfToken = false;
174
175
    /**
176
     * Boolean flag for whether or not the request should re-store
177
     * flash messages
178
     *
179
     * @var bool
180
     */
181
    protected $_retainFlashMessages = false;
182
183
    /**
184
     * Stored flash messages before render
185
     *
186
     * @var null|array
187
     */
188
    protected $_flashMessages;
189
190
    /**
191
     *
192
     * @var null|string
193
     */
194
    protected $_cookieEncryptionKey;
195
196
    /**
197
     * Auto-detect if the HTTP middleware stack should be used.
198
     *
199
     * @before
200
     * @return void
201
     */
202
    public function setupServer()
203
    {
204
        $namespace = Configure::read('App.namespace');
205
        $this->_useHttpServer = class_exists($namespace . '\Application');
206
    }
207
208
    /**
209
     * Clears the state used for requests.
210
     *
211
     * @after
212
     * @return void
213
     */
214
    public function cleanup()
215
    {
216
        $this->_request = [];
217
        $this->_session = [];
218
        $this->_cookie = [];
219
        $this->_response = null;
220
        $this->_exception = null;
221
        $this->_controller = null;
222
        $this->_viewName = null;
223
        $this->_layoutName = null;
224
        $this->_requestSession = null;
225
        $this->_appClass = null;
226
        $this->_appArgs = null;
227
        $this->_securityToken = false;
228
        $this->_csrfToken = false;
229
        $this->_retainFlashMessages = false;
230
        $this->_useHttpServer = false;
231
    }
232
233
    /**
234
     * Toggle whether or not you want to use the HTTP Server stack.
235
     *
236
     * @param bool $enable Enable/disable the usage of the HTTP Stack.
237
     * @return void
238
     */
239
    public function useHttpServer($enable)
240
    {
241
        $this->_useHttpServer = (bool)$enable;
242
    }
243
244
    /**
245
     * Configure the application class to use in integration tests.
246
     *
247
     * Combined with `useHttpServer()` to customize the class name and constructor arguments
248
     * of your application class.
249
     *
250
     * @param string $class The application class name.
251
     * @param array|null $constructorArgs The constructor arguments for your application class.
252
     * @return void
253
     */
254
    public function configApplication($class, $constructorArgs)
255
    {
256
        $this->_appClass = $class;
257
        $this->_appArgs = $constructorArgs;
258
    }
259
260
    /**
261
     * Calling this method will enable a SecurityComponent
262
     * compatible token to be added to request data. This
263
     * lets you easily test actions protected by SecurityComponent.
264
     *
265
     * @return void
266
     */
267
    public function enableSecurityToken()
268
    {
269
        $this->_securityToken = true;
270
    }
271
272
    /**
273
     * Calling this method will add a CSRF token to the request.
274
     *
275
     * Both the POST data and cookie will be populated when this option
276
     * is enabled. The default parameter names will be used.
277
     *
278
     * @return void
279
     */
280
    public function enableCsrfToken()
281
    {
282
        $this->_csrfToken = true;
283
    }
284
285
    /**
286
     * Calling this method will re-store flash messages into the test session
287
     * after being removed by the FlashHelper
288
     *
289
     * @return void
290
     */
291
    public function enableRetainFlashMessages()
292
    {
293
        $this->_retainFlashMessages = true;
294
    }
295
296
    /**
297
     * Configures the data for the *next* request.
298
     *
299
     * This data is cleared in the tearDown() method.
300
     *
301
     * You can call this method multiple times to append into
302
     * the current state.
303
     *
304
     * @param array $data The request data to use.
305
     * @return void
306
     */
307
    public function configRequest(array $data)
308
    {
309
        $this->_request = $data + $this->_request;
310
    }
311
312
    /**
313
     * Sets session data.
314
     *
315
     * This method lets you configure the session data
316
     * you want to be used for requests that follow. The session
317
     * state is reset in each tearDown().
318
     *
319
     * You can call this method multiple times to append into
320
     * the current state.
321
     *
322
     * @param array $data The session data to use.
323
     * @return void
324
     */
325
    public function session(array $data)
326
    {
327
        $this->_session = $data + $this->_session;
328
    }
329
330
    /**
331
     * Sets a request cookie for future requests.
332
     *
333
     * This method lets you configure the session data
334
     * you want to be used for requests that follow. The session
335
     * state is reset in each tearDown().
336
     *
337
     * You can call this method multiple times to append into
338
     * the current state.
339
     *
340
     * @param string $name The cookie name to use.
341
     * @param mixed $value The value of the cookie.
342
     * @return void
343
     */
344
    public function cookie($name, $value)
345
    {
346
        $this->_cookie[$name] = $value;
347
    }
348
349
    /**
350
     * Returns the encryption key to be used.
351
     *
352
     * @return string
353
     */
354
    protected function _getCookieEncryptionKey()
355
    {
356
        if (isset($this->_cookieEncryptionKey)) {
357
            return $this->_cookieEncryptionKey;
358
        }
359
360
        return Security::getSalt();
361
    }
362
363
    /**
364
     * Sets a encrypted request cookie for future requests.
365
     *
366
     * The difference from cookie() is this encrypts the cookie
367
     * value like the CookieComponent.
368
     *
369
     * @param string $name The cookie name to use.
370
     * @param mixed $value The value of the cookie.
371
     * @param string|bool $encrypt Encryption mode to use.
372
     * @param string|null $key Encryption key used. Defaults
373
     *   to Security.salt.
374
     * @return void
375
     * @see \Cake\Utility\CookieCryptTrait::_encrypt()
376
     */
377
    public function cookieEncrypted($name, $value, $encrypt = 'aes', $key = null)
378
    {
379
        $this->_cookieEncryptionKey = $key;
380
        $this->_cookie[$name] = $this->_encrypt($value, $encrypt);
381
    }
382
383
    /**
384
     * Performs a GET request using the current request data.
385
     *
386
     * The response of the dispatched request will be stored as
387
     * a property. You can use various assert methods to check the
388
     * response.
389
     *
390
     * @param string|array $url The URL to request.
391
     * @return void
392
     * @throws \PHPUnit\Exception
393
     */
394
    public function get($url)
395
    {
396
        $this->_sendRequest($url, 'GET');
397
    }
398
399
    /**
400
     * Performs a POST request using the current request data.
401
     *
402
     * The response of the dispatched request will be stored as
403
     * a property. You can use various assert methods to check the
404
     * response.
405
     *
406
     * @param string|array $url The URL to request.
407
     * @param array $data The data for the request.
408
     * @return void
409
     * @throws \PHPUnit\Exception
410
     */
411
    public function post($url, $data = [])
412
    {
413
        $this->_sendRequest($url, 'POST', $data);
414
    }
415
416
    /**
417
     * Performs a PATCH request using the current request data.
418
     *
419
     * The response of the dispatched request will be stored as
420
     * a property. You can use various assert methods to check the
421
     * response.
422
     *
423
     * @param string|array $url The URL to request.
424
     * @param array $data The data for the request.
425
     * @return void
426
     * @throws \PHPUnit\Exception
427
     */
428
    public function patch($url, $data = [])
429
    {
430
        $this->_sendRequest($url, 'PATCH', $data);
431
    }
432
433
    /**
434
     * Performs a PUT request using the current request data.
435
     *
436
     * The response of the dispatched request will be stored as
437
     * a property. You can use various assert methods to check the
438
     * response.
439
     *
440
     * @param string|array $url The URL to request.
441
     * @param array $data The data for the request.
442
     * @return void
443
     * @throws \PHPUnit\Exception
444
     */
445
    public function put($url, $data = [])
446
    {
447
        $this->_sendRequest($url, 'PUT', $data);
448
    }
449
450
    /**
451
     * Performs a DELETE request using the current request data.
452
     *
453
     * The response of the dispatched request will be stored as
454
     * a property. You can use various assert methods to check the
455
     * response.
456
     *
457
     * @param string|array $url The URL to request.
458
     * @return void
459
     * @throws \PHPUnit\Exception
460
     */
461
    public function delete($url)
462
    {
463
        $this->_sendRequest($url, 'DELETE');
464
    }
465
466
    /**
467
     * Performs a HEAD request using the current request data.
468
     *
469
     * The response of the dispatched request will be stored as
470
     * a property. You can use various assert methods to check the
471
     * response.
472
     *
473
     * @param string|array $url The URL to request.
474
     * @return void
475
     * @throws \PHPUnit\Exception
476
     */
477
    public function head($url)
478
    {
479
        $this->_sendRequest($url, 'HEAD');
480
    }
481
482
    /**
483
     * Performs an OPTIONS request using the current request data.
484
     *
485
     * The response of the dispatched request will be stored as
486
     * a property. You can use various assert methods to check the
487
     * response.
488
     *
489
     * @param string|array $url The URL to request.
490
     * @return void
491
     * @throws \PHPUnit\Exception
492
     */
493
    public function options($url)
494
    {
495
        $this->_sendRequest($url, 'OPTIONS');
496
    }
497
498
    /**
499
     * Creates and send the request into a Dispatcher instance.
500
     *
501
     * Receives and stores the response for future inspection.
502
     *
503
     * @param string|array $url The URL
504
     * @param string $method The HTTP method
505
     * @param array|null $data The request data.
506
     * @return void
507
     * @throws \PHPUnit\Exception
508
     */
509
    protected function _sendRequest($url, $method, $data = [])
510
    {
511
        $dispatcher = $this->_makeDispatcher();
512
        $url = $dispatcher->resolveUrl($url);
513
514
        try {
515
            $request = $this->_buildRequest($url, $method, $data);
516
            $response = $dispatcher->execute($request);
517
            $this->_requestSession = $request['session'];
518
            if ($this->_retainFlashMessages && $this->_flashMessages) {
519
                $this->_requestSession->write('Flash', $this->_flashMessages);
520
            }
521
            $this->_response = $response;
522
        } catch (PhpUnitException $e) {
523
            throw $e;
524
        } catch (DatabaseException $e) {
525
            throw $e;
526
        } catch (LogicException $e) {
527
            throw $e;
528
        } catch (Exception $e) {
529
            $this->_exception = $e;
530
            // Simulate the global exception handler being invoked.
531
            $this->_handleError($e);
532
        }
533
    }
534
535
    /**
536
     * Get the correct dispatcher instance.
537
     *
538
     * @return \Cake\TestSuite\MiddlewareDispatcher|\Cake\TestSuite\LegacyRequestDispatcher A dispatcher instance
539
     */
540
    protected function _makeDispatcher()
541
    {
542
        if ($this->_useHttpServer) {
543
            return new MiddlewareDispatcher($this, $this->_appClass, $this->_appArgs);
544
        }
545
546
        return new LegacyRequestDispatcher($this);
547
    }
548
549
    /**
550
     * Adds additional event spies to the controller/view event manager.
551
     *
552
     * @param \Cake\Event\Event $event A dispatcher event.
553
     * @param \Cake\Controller\Controller|null $controller Controller instance.
554
     * @return void
555
     */
556
    public function controllerSpy($event, $controller = null)
557
    {
558
        if (!$controller) {
559
            /** @var \Cake\Controller\Controller $controller */
560
            $controller = $event->getSubject();
561
        }
562
        $this->_controller = $controller;
563
        $events = $controller->getEventManager();
564
        $events->on('View.beforeRender', function ($event, $viewFile) use ($controller) {
0 ignored issues
show
Documentation introduced by
function ($event, $viewF...>read('Flash'); } } is of type object<Closure>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
565
            if (!$this->_viewName) {
566
                $this->_viewName = $viewFile;
567
            }
568
            if ($this->_retainFlashMessages) {
569
                $this->_flashMessages = $controller->getRequest()->getSession()->read('Flash');
570
            }
571
        });
572
        $events->on('View.beforeLayout', function ($event, $viewFile) {
0 ignored issues
show
Documentation introduced by
function ($event, $viewF...youtName = $viewFile; } is of type object<Closure>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
573
            $this->_layoutName = $viewFile;
574
        });
575
    }
576
577
    /**
578
     * Attempts to render an error response for a given exception.
579
     *
580
     * This method will attempt to use the configured exception renderer.
581
     * If that class does not exist, the built-in renderer will be used.
582
     *
583
     * @param \Exception $exception Exception to handle.
584
     * @return void
585
     * @throws \Exception
586
     */
587
    protected function _handleError($exception)
588
    {
589
        $class = Configure::read('Error.exceptionRenderer');
590
        if (empty($class) || !class_exists($class)) {
591
            $class = 'Cake\Error\ExceptionRenderer';
592
        }
593
        /** @var \Cake\Error\ExceptionRenderer $instance */
594
        $instance = new $class($exception);
595
        $this->_response = $instance->render();
596
    }
597
598
    /**
599
     * Creates a request object with the configured options and parameters.
600
     *
601
     * @param string|array $url The URL
602
     * @param string $method The HTTP method
603
     * @param array|null $data The request data.
604
     * @return array The request context
605
     */
606
    protected function _buildRequest($url, $method, $data)
607
    {
608
        $sessionConfig = (array)Configure::read('Session') + [
609
            'defaults' => 'php',
610
        ];
611
        $session = Session::create($sessionConfig);
612
        $session->write($this->_session);
613
        list($url, $query) = $this->_url($url);
614
        $tokenUrl = $url;
615
616
        if ($query) {
617
            $tokenUrl .= '?' . $query;
618
        }
619
620
        parse_str($query, $queryData);
621
        $props = [
622
            'url' => $url,
623
            'session' => $session,
624
            'query' => $queryData
625
        ];
626
        if (is_string($data)) {
627
            $props['input'] = $data;
628
        }
629
        if (!isset($props['input'])) {
630
            $data = $this->_addTokens($tokenUrl, $data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null or string; however, Cake\TestSuite\IntegrationTestTrait::_addTokens() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
631
            $props['post'] = $this->_castToString($data);
632
        }
633
        $props['cookies'] = $this->_cookie;
634
635
        $env = [
636
            'REQUEST_METHOD' => $method,
637
            'QUERY_STRING' => $query,
638
            'REQUEST_URI' => $url,
639
        ];
640
        if (isset($this->_request['headers'])) {
641
            foreach ($this->_request['headers'] as $k => $v) {
642
                $name = strtoupper(str_replace('-', '_', $k));
643
                if (!in_array($name, ['CONTENT_LENGTH', 'CONTENT_TYPE'])) {
644
                    $name = 'HTTP_' . $name;
645
                }
646
                $env[$name] = $v;
647
            }
648
            unset($this->_request['headers']);
649
        }
650
        $props['environment'] = $env;
651
        $props = Hash::merge($props, $this->_request);
652
653
        return $props;
654
    }
655
656
    /**
657
     * Add the CSRF and Security Component tokens if necessary.
658
     *
659
     * @param string $url The URL the form is being submitted on.
660
     * @param array $data The request body data.
661
     * @return array The request body with tokens added.
662
     */
663
    protected function _addTokens($url, $data)
664
    {
665
        if ($this->_securityToken === true) {
666
            $keys = array_map(function ($field) {
667
                return preg_replace('/(\.\d+)+$/', '', $field);
668
            }, array_keys(Hash::flatten($data)));
669
            $tokenData = $this->_buildFieldToken($url, array_unique($keys));
670
            $data['_Token'] = $tokenData;
671
            $data['_Token']['debug'] = 'SecurityComponent debug data would be added here';
672
        }
673
674
        if ($this->_csrfToken === true) {
675
            if (!isset($this->_cookie['csrfToken'])) {
676
                $this->_cookie['csrfToken'] = Text::uuid();
677
            }
678
            if (!isset($data['_csrfToken'])) {
679
                $data['_csrfToken'] = $this->_cookie['csrfToken'];
680
            }
681
        }
682
683
        return $data;
684
    }
685
686
    /**
687
     * Recursively casts all data to string as that is how data would be POSTed in
688
     * the real world
689
     *
690
     * @param array $data POST data
691
     * @return array
692
     */
693
    protected function _castToString($data)
694
    {
695
        foreach ($data as $key => $value) {
696
            if (is_scalar($value)) {
697
                $data[$key] = $value === false ? '0' : (string)$value;
698
699
                continue;
700
            }
701
702 View Code Duplication
            if (is_array($value)) {
703
                $looksLikeFile = isset($value['error'], $value['tmp_name'], $value['size']);
704
                if ($looksLikeFile) {
705
                    continue;
706
                }
707
708
                $data[$key] = $this->_castToString($value);
709
            }
710
        }
711
712
        return $data;
713
    }
714
715
    /**
716
     * Creates a valid request url and parameter array more like Request::_url()
717
     *
718
     * @param string|array $url The URL
719
     * @return array Qualified URL and the query parameters
720
     */
721
    protected function _url($url)
722
    {
723
        // re-create URL in ServerRequest's context so
724
        // query strings are encoded as expected
725
        $request = new ServerRequest(['url' => $url]);
726
        $url = $request->getRequestTarget();
727
728
        $query = '';
729
730
        $path = parse_url($url, PHP_URL_PATH);
731
        if (strpos($url, '?') !== false) {
732
            $query = parse_url($url, PHP_URL_QUERY);
733
        }
734
735
        return [$path, $query];
736
    }
737
738
    /**
739
     * Get the response body as string
740
     *
741
     * @return string The response body.
742
     */
743
    protected function _getBodyAsString()
744
    {
745
        if (!$this->_response) {
746
            $this->fail('No response set, cannot assert content.');
0 ignored issues
show
Bug introduced by
It seems like fail() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
747
        }
748
749
        return (string)$this->_response->getBody();
750
    }
751
752
    /**
753
     * Fetches a view variable by name.
754
     *
755
     * If the view variable does not exist, null will be returned.
756
     *
757
     * @param string $name The view variable to get.
758
     * @return mixed The view variable if set.
759
     */
760
    public function viewVariable($name)
761
    {
762
        if (empty($this->_controller->viewVars)) {
763
            $this->fail('There are no view variables, perhaps you need to run a request?');
0 ignored issues
show
Bug introduced by
It seems like fail() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
764
        }
765
        if (isset($this->_controller->viewVars[$name])) {
766
            return $this->_controller->viewVars[$name];
767
        }
768
769
        return null;
770
    }
771
772
    /**
773
     * Asserts that the response status code is in the 2xx range.
774
     *
775
     * @param string $message Custom message for failure.
776
     * @return void
777
     */
778
    public function assertResponseOk($message = null)
779
    {
780
        $verboseMessage = $this->extractVerboseMessage($message);
781
        $this->assertThat(null, new StatusOk($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
782
    }
783
784
    /**
785
     * Asserts that the response status code is in the 2xx/3xx range.
786
     *
787
     * @param string $message Custom message for failure.
788
     * @return void
789
     */
790
    public function assertResponseSuccess($message = null)
791
    {
792
        $verboseMessage = $this->extractVerboseMessage($message);
793
        $this->assertThat(null, new StatusSuccess($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
794
    }
795
796
    /**
797
     * Asserts that the response status code is in the 4xx range.
798
     *
799
     * @param string $message Custom message for failure.
800
     * @return void
801
     */
802
    public function assertResponseError($message = null)
803
    {
804
        $this->assertThat(null, new StatusError($this->_response), $message);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
805
    }
806
807
    /**
808
     * Asserts that the response status code is in the 5xx range.
809
     *
810
     * @param string $message Custom message for failure.
811
     * @return void
812
     */
813
    public function assertResponseFailure($message = null)
814
    {
815
        $this->assertThat(null, new StatusFailure($this->_response), $message);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
816
    }
817
818
    /**
819
     * Asserts a specific response status code.
820
     *
821
     * @param int $code Status code to assert.
822
     * @param string $message Custom message for failure.
823
     * @return void
824
     */
825
    public function assertResponseCode($code, $message = null)
826
    {
827
        $this->assertThat($code, new StatusCode($this->_response), $message);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
828
    }
829
830
    /**
831
     * Asserts that the Location header is correct.
832
     *
833
     * @param string|array|null $url The URL you expected the client to go to. This
834
     *   can either be a string URL or an array compatible with Router::url(). Use null to
835
     *   simply check for the existence of this header.
836
     * @param string $message The failure message that will be appended to the generated message.
837
     * @return void
838
     */
839
    public function assertRedirect($url = null, $message = '')
840
    {
841
        $verboseMessage = $this->extractVerboseMessage($message);
842
        $this->assertThat(null, new HeaderSet($this->_response, 'Location'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
843
844
        if ($url) {
845
            $this->assertThat(Router::url($url, ['_full' => true]), new HeaderEquals($this->_response, 'Location'), $verboseMessage);
0 ignored issues
show
Documentation introduced by
array('_full' => true) is of type array<string,boolean,{"_full":"boolean"}>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
846
        }
847
    }
848
849
    /**
850
     * Asserts that the Location header contains a substring
851
     *
852
     * @param string $url The URL you expected the client to go to.
853
     * @param string $message The failure message that will be appended to the generated message.
854
     * @return void
855
     */
856
    public function assertRedirectContains($url, $message = '')
857
    {
858
        $verboseMessage = $this->extractVerboseMessage($message);
859
        $this->assertThat(null, new HeaderSet($this->_response, 'Location'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
860
        $this->assertThat($url, new HeaderContains($this->_response, 'Location'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
861
    }
862
863
    /**
864
     * Asserts that the Location header does not contain a substring
865
     *
866
     * @param string $url The URL you expected the client to go to.
867
     * @param string $message The failure message that will be appended to the generated message.
868
     * @return void
869
     */
870
    public function assertRedirectNotContains($url, $message = '')
871
    {
872
        $verboseMessage = $this->extractVerboseMessage($message);
873
        $this->assertThat(null, new HeaderSet($this->_response, 'Location'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
874
        $this->assertThat($url, new HeaderNotContains($this->_response, 'Location'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
875
    }
876
877
    /**
878
     * Asserts that the Location header is not set.
879
     *
880
     * @param string $message The failure message that will be appended to the generated message.
881
     * @return void
882
     */
883
    public function assertNoRedirect($message = '')
884
    {
885
        $verboseMessage = $this->extractVerboseMessage($message);
886
        $this->assertThat(null, new HeaderNotSet($this->_response, 'Location'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
887
    }
888
889
    /**
890
     * Asserts response headers
891
     *
892
     * @param string $header The header to check
893
     * @param string $content The content to check for.
894
     * @param string $message The failure message that will be appended to the generated message.
895
     * @return void
896
     */
897
    public function assertHeader($header, $content, $message = '')
898
    {
899
        $verboseMessage = $this->extractVerboseMessage($message);
900
        $this->assertThat(null, new HeaderSet($this->_response, $header), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
901
        $this->assertThat($content, new HeaderEquals($this->_response, $header), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
902
    }
903
904
    /**
905
     * Asserts response header contains a string
906
     *
907
     * @param string $header The header to check
908
     * @param string $content The content to check for.
909
     * @param string $message The failure message that will be appended to the generated message.
910
     * @return void
911
     */
912
    public function assertHeaderContains($header, $content, $message = '')
913
    {
914
        $verboseMessage = $this->extractVerboseMessage($message);
915
        $this->assertThat(null, new HeaderSet($this->_response, $header), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
916
        $this->assertThat($content, new HeaderContains($this->_response, $header), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
917
    }
918
919
    /**
920
     * Asserts response header does not contain a string
921
     *
922
     * @param string $header The header to check
923
     * @param string $content The content to check for.
924
     * @param string $message The failure message that will be appended to the generated message.
925
     * @return void
926
     */
927
    public function assertHeaderNotContains($header, $content, $message = '')
928
    {
929
        $verboseMessage = $this->extractVerboseMessage($message);
930
        $this->assertThat(null, new HeaderSet($this->_response, $header), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
931
        $this->assertThat($content, new HeaderNotContains($this->_response, $header), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
932
    }
933
934
    /**
935
     * Asserts content type
936
     *
937
     * @param string $type The content-type to check for.
938
     * @param string $message The failure message that will be appended to the generated message.
939
     * @return void
940
     */
941
    public function assertContentType($type, $message = '')
942
    {
943
        $verboseMessage = $this->extractVerboseMessage($message);
944
        $this->assertThat($type, new ContentType($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
945
    }
946
947
    /**
948
     * Asserts content in the response body equals.
949
     *
950
     * @param mixed $content The content to check for.
951
     * @param string $message The failure message that will be appended to the generated message.
952
     * @return void
953
     */
954
    public function assertResponseEquals($content, $message = '')
955
    {
956
        $verboseMessage = $this->extractVerboseMessage($message);
957
        $this->assertThat($content, new BodyEquals($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
958
    }
959
960
    /**
961
     * Asserts content in the response body not equals.
962
     *
963
     * @param mixed $content The content to check for.
964
     * @param string $message The failure message that will be appended to the generated message.
965
     * @return void
966
     */
967
    public function assertResponseNotEquals($content, $message = '')
968
    {
969
        $verboseMessage = $this->extractVerboseMessage($message);
970
        $this->assertThat($content, new BodyNotEquals($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
971
    }
972
973
    /**
974
     * Asserts content exists in the response body.
975
     *
976
     * @param string $content The content to check for.
977
     * @param string $message The failure message that will be appended to the generated message.
978
     * @param bool $ignoreCase A flag to check whether we should ignore case or not.
979
     * @return void
980
     */
981
    public function assertResponseContains($content, $message = '', $ignoreCase = false)
982
    {
983
        $verboseMessage = $this->extractVerboseMessage($message);
984
        $this->assertThat($content, new BodyContains($this->_response, $ignoreCase), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
985
    }
986
987
    /**
988
     * Asserts content does not exist in the response body.
989
     *
990
     * @param string $content The content to check for.
991
     * @param string $message The failure message that will be appended to the generated message.
992
     * @param bool $ignoreCase A flag to check whether we should ignore case or not.
993
     * @return void
994
     */
995
    public function assertResponseNotContains($content, $message = '', $ignoreCase = false)
996
    {
997
        $verboseMessage = $this->extractVerboseMessage($message);
998
        $this->assertThat($content, new BodyNotContains($this->_response, $ignoreCase), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
999
    }
1000
1001
    /**
1002
     * Asserts that the response body matches a given regular expression.
1003
     *
1004
     * @param string $pattern The pattern to compare against.
1005
     * @param string $message The failure message that will be appended to the generated message.
1006
     * @return void
1007
     */
1008
    public function assertResponseRegExp($pattern, $message = '')
1009
    {
1010
        $verboseMessage = $this->extractVerboseMessage($message);
1011
        $this->assertThat($pattern, new BodyRegExp($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1012
    }
1013
1014
    /**
1015
     * Asserts that the response body does not match a given regular expression.
1016
     *
1017
     * @param string $pattern The pattern to compare against.
1018
     * @param string $message The failure message that will be appended to the generated message.
1019
     * @return void
1020
     */
1021
    public function assertResponseNotRegExp($pattern, $message = '')
1022
    {
1023
        $verboseMessage = $this->extractVerboseMessage($message);
1024
        $this->assertThat($pattern, new BodyNotRegExp($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1025
    }
1026
1027
    /**
1028
     * Assert response content is not empty.
1029
     *
1030
     * @param string $message The failure message that will be appended to the generated message.
1031
     * @return void
1032
     */
1033
    public function assertResponseNotEmpty($message = '')
1034
    {
1035
        $this->assertThat(null, new BodyNotEmpty($this->_response), $message);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1036
    }
1037
1038
    /**
1039
     * Assert response content is empty.
1040
     *
1041
     * @param string $message The failure message that will be appended to the generated message.
1042
     * @return void
1043
     */
1044
    public function assertResponseEmpty($message = '')
1045
    {
1046
        $this->assertThat(null, new BodyEmpty($this->_response), $message);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1047
    }
1048
1049
    /**
1050
     * Asserts that the search string was in the template name.
1051
     *
1052
     * @param string $content The content to check for.
1053
     * @param string $message The failure message that will be appended to the generated message.
1054
     * @return void
1055
     */
1056
    public function assertTemplate($content, $message = '')
1057
    {
1058
        $verboseMessage = $this->extractVerboseMessage($message);
1059
        $this->assertThat($content, new TemplateFileEquals($this->_viewName), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1060
    }
1061
1062
    /**
1063
     * Asserts that the search string was in the layout name.
1064
     *
1065
     * @param string $content The content to check for.
1066
     * @param string $message The failure message that will be appended to the generated message.
1067
     * @return void
1068
     */
1069
    public function assertLayout($content, $message = '')
1070
    {
1071
        $verboseMessage = $this->extractVerboseMessage($message);
1072
        $this->assertThat($content, new LayoutFileEquals($this->_layoutName), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1073
    }
1074
1075
    /**
1076
     * Asserts session contents
1077
     *
1078
     * @param string $expected The expected contents.
1079
     * @param string $path The session data path. Uses Hash::get() compatible notation
1080
     * @param string $message The failure message that will be appended to the generated message.
1081
     * @return void
1082
     */
1083
    public function assertSession($expected, $path, $message = '')
1084
    {
1085
        $verboseMessage = $this->extractVerboseMessage($message);
1086
        $this->assertThat($expected, new SessionEquals($this->_requestSession, $path), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1087
    }
1088
1089
    /**
1090
     * Asserts a flash message was set
1091
     *
1092
     * @param string $expected Expected message
1093
     * @param string $key Flash key
1094
     * @param string $message Assertion failure message
1095
     * @return void
1096
     */
1097
    public function assertFlashMessage($expected, $key = 'flash', $message = '')
1098
    {
1099
        $verboseMessage = $this->extractVerboseMessage($message);
1100
        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'message'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1101
    }
1102
1103
    /**
1104
     * Asserts a flash message was set at a certain index
1105
     *
1106
     * @param int $at Flash index
1107
     * @param string $expected Expected message
1108
     * @param string $key Flash key
1109
     * @param string $message Assertion failure message
1110
     * @return void
1111
     */
1112
    public function assertFlashMessageAt($at, $expected, $key = 'flash', $message = '')
1113
    {
1114
        $verboseMessage = $this->extractVerboseMessage($message);
1115
        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'message', $at), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1116
    }
1117
1118
    /**
1119
     * Asserts a flash element was set
1120
     *
1121
     * @param string $expected Expected element name
1122
     * @param string $key Flash key
1123
     * @param string $message Assertion failure message
1124
     * @return void
1125
     */
1126
    public function assertFlashElement($expected, $key = 'flash', $message = '')
1127
    {
1128
        $verboseMessage = $this->extractVerboseMessage($message);
1129
        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'element'), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1130
    }
1131
1132
    /**
1133
     * Asserts a flash element was set at a certain index
1134
     *
1135
     * @param int $at Flash index
1136
     * @param string $expected Expected element name
1137
     * @param string $key Flash key
1138
     * @param string $message Assertion failure message
1139
     * @return void
1140
     */
1141
    public function assertFlashElementAt($at, $expected, $key = 'flash', $message = '')
1142
    {
1143
        $verboseMessage = $this->extractVerboseMessage($message);
1144
        $this->assertThat($expected, new FlashParamEquals($this->_requestSession, $key, 'element', $at), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1145
    }
1146
1147
    /**
1148
     * Asserts cookie values
1149
     *
1150
     * @param string $expected The expected contents.
1151
     * @param string $name The cookie name.
1152
     * @param string $message The failure message that will be appended to the generated message.
1153
     * @return void
1154
     */
1155
    public function assertCookie($expected, $name, $message = '')
1156
    {
1157
        $verboseMessage = $this->extractVerboseMessage($message);
1158
        $this->assertThat($name, new CookieSet($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1159
        $this->assertThat($expected, new CookieEquals($this->_response, $name), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1160
    }
1161
1162
    /**
1163
     * Asserts a cookie has not been set in the response
1164
     *
1165
     * @param string $cookie The cookie name to check
1166
     * @param string $message The failure message that will be appended to the generated message.
1167
     * @return void
1168
     */
1169
    public function assertCookieNotSet($cookie, $message = '')
1170
    {
1171
        $verboseMessage = $this->extractVerboseMessage($message);
1172
        $this->assertThat($cookie, new CookieNotSet($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1173
    }
1174
1175
    /**
1176
     * Disable the error handler middleware.
1177
     *
1178
     * By using this function, exceptions are no longer caught by the ErrorHandlerMiddleware
1179
     * and are instead re-thrown by the TestExceptionRenderer. This can be helpful
1180
     * when trying to diagnose/debug unexpected failures in test cases.
1181
     *
1182
     * @return void
1183
     */
1184
    public function disableErrorHandlerMiddleware()
1185
    {
1186
        Configure::write('Error.exceptionRenderer', TestExceptionRenderer::class);
1187
    }
1188
1189
    /**
1190
     * Asserts cookie values which are encrypted by the
1191
     * CookieComponent.
1192
     *
1193
     * The difference from assertCookie() is this decrypts the cookie
1194
     * value like the CookieComponent for this assertion.
1195
     *
1196
     * @param string $expected The expected contents.
1197
     * @param string $name The cookie name.
1198
     * @param string|bool $encrypt Encryption mode to use.
1199
     * @param string|null $key Encryption key used. Defaults
1200
     *   to Security.salt.
1201
     * @param string $message The failure message that will be appended to the generated message.
1202
     * @return void
1203
     * @see \Cake\Utility\CookieCryptTrait::_encrypt()
1204
     */
1205
    public function assertCookieEncrypted($expected, $name, $encrypt = 'aes', $key = null, $message = '')
1206
    {
1207
        $verboseMessage = $this->extractVerboseMessage($message);
1208
        $this->assertThat($name, new CookieSet($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1209
1210
        $this->_cookieEncryptionKey = $key;
1211
        $this->assertThat($expected, new CookieEncryptedEquals($this->_response, $name, $encrypt, $this->_getCookieEncryptionKey()));
0 ignored issues
show
Bug introduced by
It seems like $encrypt defined by parameter $encrypt on line 1205 can also be of type boolean; however, Cake\TestSuite\Constrain...edEquals::__construct() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1212
    }
1213
1214
    /**
1215
     * Asserts that a file with the given name was sent in the response
1216
     *
1217
     * @param string $expected The file name that should be sent in the response
1218
     * @param string $message The failure message that will be appended to the generated message.
1219
     * @return void
1220
     */
1221
    public function assertFileResponse($expected, $message = '')
1222
    {
1223
        $verboseMessage = $this->extractVerboseMessage($message);
1224
        $this->assertThat(null, new FileSent($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1225
        $this->assertThat($expected, new FileSentAs($this->_response), $verboseMessage);
0 ignored issues
show
Bug introduced by
It seems like assertThat() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
1226
    }
1227
1228
    /**
1229
     * Inspect controller to extract possible causes of the failed assertion
1230
     *
1231
     * @param string $message Original message to use as a base
1232
     * @return null|string
1233
     */
1234
    protected function extractVerboseMessage($message = null)
1235
    {
1236
        if ($this->_exception instanceof \Exception) {
1237
            $message .= $this->extractExceptionMessage($this->_exception);
1238
        }
1239
        if ($this->_controller === null) {
1240
            return $message;
1241
        }
1242
        $error = Hash::get($this->_controller->viewVars, 'error');
1243
        if ($error instanceof \Exception) {
1244
            $message .= $this->extractExceptionMessage($this->viewVariable('error'));
1245
        }
1246
1247
        return $message;
1248
    }
1249
1250
    /**
1251
     * Extract verbose message for existing exception
1252
     *
1253
     * @param \Exception $exception Exception to extract
1254
     * @return string
1255
     */
1256
    protected function extractExceptionMessage(\Exception $exception)
1257
    {
1258
        return PHP_EOL .
1259
            sprintf('Possibly related to %s: "%s" ', get_class($exception), $exception->getMessage()) .
1260
            PHP_EOL .
1261
            $exception->getTraceAsString();
1262
    }
1263
}
1264