44
55namespace Codeception \Lib \Connector ;
66
7- use Closure ;
87use Codeception \Lib \Connector \Laravel \ExceptionHandlerDecorator as LaravelExceptionHandlerDecorator ;
98use Codeception \Lib \Connector \Laravel6 \ExceptionHandlerDecorator as Laravel6ExceptionHandlerDecorator ;
9+ use Codeception \Module \Laravel \ServicesTrait ;
1010use Codeception \Stub ;
1111use Exception ;
1212use Illuminate \Contracts \Debug \ExceptionHandler ;
1313use Illuminate \Contracts \Events \Dispatcher ;
14- use Illuminate \Contracts \Http \ Kernel ;
14+ use Illuminate \Contracts \Foundation \ Application as AppContract ;
1515use Illuminate \Database \Eloquent \Model ;
1616use Illuminate \Foundation \Application ;
1717use Illuminate \Foundation \Bootstrap \RegisterProviders ;
2020use Symfony \Component \HttpFoundation \Request as SymfonyRequest ;
2121use Symfony \Component \HttpFoundation \Response ;
2222use Symfony \Component \HttpKernel \HttpKernelBrowser as Client ;
23- use Symfony \Component \HttpKernel \Kernel as SymfonyKernel ;
24- use function class_alias ;
25-
26- if (SymfonyKernel::VERSION_ID < 40300 ) {
27- class_alias ('Symfony\Component\HttpKernel\Client ' , 'Symfony\Component\HttpKernel\HttpKernelBrowser ' );
28- }
2923
3024class Laravel extends Client
3125{
26+ use ServicesTrait;
27+
3228 /**
3329 * @var array
3430 */
@@ -40,12 +36,12 @@ class Laravel extends Client
4036 private $ contextualBindings = [];
4137
4238 /**
43- * @var array
39+ * @var object[]
4440 */
4541 private $ instances = [];
4642
4743 /**
48- * @var array
44+ * @var callable[]
4945 */
5046 private $ applicationHandlers = [];
5147
@@ -111,11 +107,11 @@ public function __construct($module)
111107
112108 $ this ->initialize ();
113109
114- $ components = parse_url ($ this ->app [ ' config ' ] ->get ('app.url ' , 'http://localhost ' ));
110+ $ components = parse_url ($ this ->getConfig () ->get ('app.url ' , 'http://localhost ' ));
115111 if (array_key_exists ('url ' , $ this ->module ->config )) {
116112 $ components = parse_url ($ this ->module ->config ['url ' ]);
117113 }
118- $ host = isset ( $ components ['host ' ]) ? $ components [ ' host ' ] : 'localhost ' ;
114+ $ host = $ components ['host ' ] ?? 'localhost ' ;
119115
120116 parent ::__construct ($ this ->app , ['HTTP_HOST ' => $ host ]);
121117
@@ -127,7 +123,6 @@ public function __construct($module)
127123 * Execute a request.
128124 *
129125 * @param SymfonyRequest $request
130- * @return Response
131126 * @throws Exception
132127 */
133128 protected function doRequest ($ request ): Response
@@ -144,22 +139,20 @@ protected function doRequest($request): Response
144139
145140 $ request = Request::createFromBase ($ request );
146141 $ response = $ this ->kernel ->handle ($ request );
147- $ this ->app -> make (Kernel::class )->terminate ($ request , $ response );
142+ $ this ->getHttpKernel ( )->terminate ($ request , $ response );
148143
149144 return $ response ;
150145 }
151146
152- /**
153- * @param SymfonyRequest|null $request
154- * @throws Exception
155- */
156147 private function initialize (SymfonyRequest $ request = null ): void
157148 {
158149 // Store a reference to the database object
159150 // so the database connection can be reused during tests
160151 $ this ->oldDb = null ;
161- if (isset ($ this ->app ['db ' ]) && $ this ->app ['db ' ]->connection ()) {
162- $ this ->oldDb = $ this ->app ['db ' ];
152+
153+ $ db = $ this ->getDb ();
154+ if ($ db && $ db ->connection ()) {
155+ $ this ->oldDb = $ db ;
163156 }
164157
165158 $ this ->app = $ this ->kernel = $ this ->loadApplication ();
@@ -173,36 +166,27 @@ private function initialize(SymfonyRequest $request = null): void
173166
174167 // Reset the old database after all the service providers are registered.
175168 if ($ this ->oldDb ) {
176- $ this ->app [ ' events ' ] ->listen ('bootstrapped: ' . RegisterProviders::class, function () {
169+ $ this ->getEvents () ->listen ('bootstrapped: ' . RegisterProviders::class, function () {
177170 $ this ->app ->singleton ('db ' , function () {
178171 return $ this ->oldDb ;
179172 });
180173 });
181174 }
182175
183- $ this ->app -> make (Kernel::class )->bootstrap ();
176+ $ this ->getHttpKernel ( )->bootstrap ();
184177
185- // Record all triggered events by adding a wildcard event listener
186- // Since Laravel 5.4 wildcard event handlers receive the event name as the first argument,
187- // but for earlier Laravel versions the firing() method of the event dispatcher should be used
188- // to determine the event name.
189- if (method_exists ($ this ->app ['events ' ], 'firing ' )) {
190- $ listener = function () {
191- $ this ->triggeredEvents [] = $ this ->normalizeEvent ($ this ->app ['events ' ]->firing ());
192- };
193- } else {
194- $ listener = function ($ event ) {
195- $ this ->triggeredEvents [] = $ this ->normalizeEvent ($ event );
196- };
197- }
198- $ this ->app ['events ' ]->listen ('* ' , $ listener );
178+ $ listener = function ($ event ) {
179+ $ this ->triggeredEvents [] = $ this ->normalizeEvent ($ event );
180+ };
181+
182+ $ this ->getEvents ()->listen ('* ' , $ listener );
199183
200184 // Replace the Laravel exception handler with our decorated exception handler,
201185 // so exceptions can be intercepted for the disable_exception_handling functionality.
202186 if (version_compare (Application::VERSION , '7.0.0 ' , '< ' )) {
203- $ decorator = new Laravel6ExceptionHandlerDecorator ($ this ->app [ExceptionHandler::class] );
187+ $ decorator = new Laravel6ExceptionHandlerDecorator ($ this ->getExceptionHandler () );
204188 } else {
205- $ decorator = new LaravelExceptionHandlerDecorator ($ this ->app [ExceptionHandler::class] );
189+ $ decorator = new LaravelExceptionHandlerDecorator ($ this ->getExceptionHandler () );
206190 }
207191
208192 $ decorator ->exceptionHandlingDisabled ($ this ->exceptionHandlingDisabled );
@@ -225,11 +209,10 @@ private function initialize(SymfonyRequest $request = null): void
225209
226210 /**
227211 * Boot the Laravel application object.
228- *
229- * @return Application
230212 */
231- private function loadApplication (): Application
213+ private function loadApplication (): AppContract
232214 {
215+ /** @var AppContract $app */
233216 $ app = require $ this ->module ->config ['bootstrap_file ' ];
234217 $ app ->loadEnvironmentFrom ($ this ->module ->config ['environment_file ' ]);
235218 $ app ->instance ('request ' , new Request ());
@@ -239,8 +222,6 @@ private function loadApplication(): Application
239222
240223 /**
241224 * Replace the Laravel event dispatcher with a mock.
242- *
243- * @throws Exception
244225 */
245226 private function mockEventDispatcher (): void
246227 {
@@ -253,13 +234,7 @@ private function mockEventDispatcher(): void
253234 return [];
254235 };
255236
256- // In Laravel 5.4 the Illuminate\Contracts\Events\Dispatcher interface was changed,
257- // the 'fire' method was renamed to 'dispatch'. This code determines the correct method to mock.
258- $ method = method_exists ($ this ->app ['events ' ], 'dispatch ' ) ? 'dispatch ' : 'fire ' ;
259-
260- $ mock = Stub::makeEmpty (Dispatcher::class, [
261- $ method => $ callback
262- ]);
237+ $ mock = Stub::makeEmpty (Dispatcher::class, ['dispatch ' => $ callback ]);
263238
264239 $ this ->app ->instance ('events ' , $ mock );
265240 }
@@ -372,7 +347,7 @@ private function applyApplicationHandlers(): void
372347 private function applyBindings (): void
373348 {
374349 foreach ($ this ->bindings as $ abstract => $ binding ) {
375- list ( $ concrete , $ shared) = $ binding ;
350+ [ $ concrete , $ shared] = $ binding ;
376351
377352 $ this ->app ->bind ($ abstract , $ concrete , $ shared );
378353 }
@@ -400,93 +375,29 @@ private function applyInstances(): void
400375 }
401376 }
402377
403- //======================================================================
404- // Public methods called by module
405- //======================================================================
406-
407- /**
408- * Register a Laravel service container binding that should be applied
409- * after initializing the Laravel Application object.
410- *
411- * @param string $abstract
412- * @param Closure|string|null $concrete
413- * @param bool $shared
414- */
415- public function haveBinding (string $ abstract , $ concrete , bool $ shared = false ): void
416- {
417- $ this ->bindings [$ abstract ] = [$ concrete , $ shared ];
418- }
419-
420- /**
421- * Register a Laravel service container contextual binding that should be applied
422- * after initializing the Laravel Application object.
423- *
424- * @param string $concrete
425- * @param string $abstract
426- * @param Closure|string $implementation
427- */
428- public function haveContextualBinding (string $ concrete , string $ abstract , $ implementation ): void
429- {
430- if (! isset ($ this ->contextualBindings [$ concrete ])) {
431- $ this ->contextualBindings [$ concrete ] = [];
432- }
433-
434- $ this ->contextualBindings [$ concrete ][$ abstract ] = $ implementation ;
435- }
436-
437- /**
438- * Register a Laravel service container instance binding that should be applied
439- * after initializing the Laravel Application object.
440- *
441- * @param string $abstract
442- * @param mixed $instance
443- */
444- public function haveInstance (string $ abstract , $ instance ): void
445- {
446- $ this ->instances [$ abstract ] = $ instance ;
447- }
448-
449- /**
450- * Register a handler than can be used to modify the Laravel application object after it is initialized.
451- * The Laravel application object will be passed as an argument to the handler.
452- *
453- * @param callable $handler
454- */
455- public function haveApplicationHandler (callable $ handler ): void
456- {
457- $ this ->applicationHandlers [] = $ handler ;
458- }
459-
460- /**
461- * Clear the registered application handlers.
462- */
463- public function clearApplicationHandlers (): void
464- {
465- $ this ->applicationHandlers = [];
466- }
467-
468378 /**
469379 * Make sure files are \Illuminate\Http\UploadedFile instances with the private $test property set to true.
470380 * Fixes issue https://github.com/Codeception/Codeception/pull/3417.
471- *
472- * @param array $files
473- * @return array
474381 */
475382 protected function filterFiles (array $ files ): array
476383 {
477384 $ files = parent ::filterFiles ($ files );
478385 return $ this ->convertToTestFiles ($ files );
479386 }
480387
481- private function convertToTestFiles (array $ files ): array
388+ private function convertToTestFiles (array & $ files ): array
482389 {
483390 $ filtered = [];
484391
485392 foreach ($ files as $ key => $ value ) {
486393 if (is_array ($ value )) {
487394 $ filtered [$ key ] = $ this ->convertToTestFiles ($ value );
395+
396+ $ files [$ key ] = $ value ;
488397 } else {
489398 $ filtered [$ key ] = UploadedFile::createFromBase ($ value , true );
399+
400+ unset($ files [$ key ]);
490401 }
491402 }
492403
0 commit comments