10
10
use Yii ;
11
11
use yii \base \ExitException ;
12
12
use yii \base \Security ;
13
+ use yii \web \Application ;
14
+ use yii \web \ErrorHandler ;
13
15
use yii \web \HttpException ;
14
16
use yii \web \Request ;
15
17
use yii \web \Response as YiiResponse ;
@@ -18,11 +20,50 @@ class Yii2 extends Client
18
20
{
19
21
use Shared \PhpSuperGlobalsConverter;
20
22
23
+ const CLEAN_METHODS = [
24
+ self ::CLEAN_RECREATE ,
25
+ self ::CLEAN_CLEAR ,
26
+ self ::CLEAN_FORCE_RECREATE ,
27
+ self ::CLEAN_MANUAL
28
+ ];
29
+ /**
30
+ * Clean the response object by recreating it.
31
+ * This might lose behaviors / event handlers / other changes that are done in the application bootstrap phase.
32
+ */
33
+ const CLEAN_RECREATE = 'recreate ' ;
34
+ /**
35
+ * Same as recreate but will not warn when behaviors / event handlers are lost.
36
+ */
37
+ const CLEAN_FORCE_RECREATE = 'force_recreate ' ;
38
+ /**
39
+ * Clean the response object by resetting specific properties via its' `clear()` method.
40
+ * This will keep behaviors / event handlers, but could inadvertently leave some changes intact.
41
+ * @see \Yii\web\Response::clear()
42
+ */
43
+ const CLEAN_CLEAR = 'clear ' ;
44
+
45
+ /**
46
+ * Do not clean the response, instead the test writer will be responsible for manually resetting the response in
47
+ * between requests during one test
48
+ */
49
+ const CLEAN_MANUAL = 'manual ' ;
50
+
51
+
21
52
/**
22
53
* @var string application config file
23
54
*/
24
55
public $ configFile ;
25
56
57
+ /**
58
+ * @var string method for cleaning the response object before each request
59
+ */
60
+ public $ responseCleanMethod ;
61
+
62
+ /**
63
+ * @var string method for cleaning the request object before each request
64
+ */
65
+ public $ requestCleanMethod ;
66
+
26
67
/**
27
68
* @return \yii\web\Application
28
69
*/
@@ -99,7 +140,9 @@ public function doRequest($request)
99
140
* @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
100
141
* those changes to be reflected in the reponse.
101
142
*/
102
- $ app ->set ('response ' , $ app ->getComponents ()['response ' ]);
143
+ $ this ->resetResponse ($ app );
144
+
145
+
103
146
104
147
// disabling logging. Logs are slowing test execution down
105
148
foreach ($ app ->log ->targets as $ target ) {
@@ -114,7 +157,7 @@ public function doRequest($request)
114
157
* @todo Implement some kind of check to see if someone tried to change the objects' properties and expects
115
158
* those changes to be reflected in the reponse.
116
159
*/
117
- $ app -> set ( ' request ' , $ app-> getComponents ()[ ' request ' ] );
160
+ $ this -> resetRequest ( $ app );
118
161
119
162
$ yiiRequest = $ app ->getRequest ();
120
163
if ($ request ->getContent () !== null ) {
@@ -134,7 +177,6 @@ public function doRequest($request)
134
177
$ app ->trigger ($ app ::EVENT_BEFORE_REQUEST );
135
178
$ response = $ app ->handleRequest ($ yiiRequest );
136
179
$ app ->trigger ($ app ::EVENT_AFTER_REQUEST );
137
- codecept_debug ($ response ->isSent );
138
180
$ response ->send ();
139
181
} catch (\Exception $ e ) {
140
182
if ($ e instanceof HttpException) {
@@ -259,4 +301,83 @@ public function restart()
259
301
parent ::restart ();
260
302
$ this ->resetApplication ();
261
303
}
304
+
305
+ /**
306
+ * Resets the applications' response object.
307
+ * The method used depends on the module configuration.
308
+ */
309
+ protected function resetResponse (Application $ app )
310
+ {
311
+ $ method = $ this ->responseCleanMethod ;
312
+ // First check the current response object.
313
+ if (($ app ->response ->hasEventHandlers (\yii \web \Response::EVENT_BEFORE_SEND )
314
+ || $ app ->response ->hasEventHandlers (\yii \web \Response::EVENT_AFTER_SEND )
315
+ || $ app ->response ->hasEventHandlers (\yii \web \Response::EVENT_AFTER_PREPARE )
316
+ || count ($ app ->response ->getBehaviors ()) > 0
317
+ ) && $ method === self ::CLEAN_RECREATE
318
+ ) {
319
+ Debug::debug (<<<TEXT
320
+ [WARNING] You are attaching event handlers or behaviors to the response object. But the Yii2 module is configured to recreate
321
+ the response object, this means any behaviors or events that are not attached in the component config will be lost.
322
+ We will fall back to clearing the response. If you are certain you want to recreate it, please configure
323
+ responseCleanMethod = 'force_recreate' in the module.
324
+ TEXT
325
+ );
326
+ $ method = self ::CLEAN_CLEAR ;
327
+ }
328
+
329
+ switch ($ method ) {
330
+ case self ::CLEAN_FORCE_RECREATE :
331
+ case self ::CLEAN_RECREATE :
332
+ $ app ->set ('response ' , $ app ->getComponents ()['response ' ]);
333
+ break ;
334
+ case self ::CLEAN_CLEAR :
335
+ $ app ->response ->clear ();
336
+ break ;
337
+ case self ::CLEAN_MANUAL :
338
+ break ;
339
+ }
340
+ }
341
+
342
+ protected function resetRequest (Application $ app )
343
+ {
344
+ $ method = $ this ->requestCleanMethod ;
345
+ $ request = $ app ->request ;
346
+
347
+ // First check the current request object.
348
+ if (count ($ request ->getBehaviors ()) > 0 && $ method === self ::CLEAN_RECREATE ) {
349
+ Debug::debug (<<<TEXT
350
+ [WARNING] You are attaching event handlers or behaviors to the request object. But the Yii2 module is configured to recreate
351
+ the request object, this means any behaviors or events that are not attached in the component config will be lost.
352
+ We will fall back to clearing the request. If you are certain you want to recreate it, please configure
353
+ requestCleanMethod = 'force_recreate' in the module.
354
+ TEXT
355
+ );
356
+ $ method = self ::CLEAN_CLEAR ;
357
+ }
358
+
359
+ switch ($ method ) {
360
+ case self ::CLEAN_FORCE_RECREATE :
361
+ case self ::CLEAN_RECREATE :
362
+ $ app ->set ('request ' , $ app ->getComponents ()['request ' ]);
363
+ break ;
364
+ case self ::CLEAN_CLEAR :
365
+ $ request ->getHeaders ()->removeAll ();
366
+ $ request ->getCookies ()->removeAll ();
367
+ $ request ->setBaseUrl (null );
368
+ $ request ->setHostInfo (null );
369
+ $ request ->setPathInfo (null );
370
+ $ request ->setScriptFile (null );
371
+ $ request ->setScriptUrl (null );
372
+ $ request ->setUrl (null );
373
+ $ request ->setPort (null );
374
+ $ request ->setSecurePort (null );
375
+ $ request ->setAcceptableContentTypes (null );
376
+ $ request ->setAcceptableLanguages (null );
377
+
378
+ break ;
379
+ case self ::CLEAN_MANUAL :
380
+ break ;
381
+ }
382
+ }
262
383
}
0 commit comments