Passed
Push — master ( 150762...219199 )
by Sergei
28:42 queued 26:17
created

TestApplicationRunner::createDefaultContainer()   B

Complexity

Conditions 7
Paths 64

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
c 1
b 0
f 0
nc 64
nop 2
dl 0
loc 35
ccs 0
cts 19
cp 0
crap 56
rs 8.8333

1 Method

Rating   Name   Duplication   Size   Complexity  
A TestApplicationRunner::preloadContainer() 0 11 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Testing;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Throwable;
11
use Yiisoft\Di\Container;
12
use Yiisoft\Di\ServiceProviderInterface;
13
use Yiisoft\ErrorHandler\Middleware\ErrorCatcher;
14
use Yiisoft\Yii\Http\Application;
15
use Yiisoft\Yii\Http\Handler\ThrowableHandler;
16
use Yiisoft\Yii\Runner\ApplicationRunner;
17
use Yiisoft\Yii\Runner\Http\ServerRequestFactory;
18
19
final class TestApplicationRunner extends ApplicationRunner
20
{
21
    private array $requestParameters = [];
22
    public ?ContainerInterface $container = null;
23
    /**
24
     * @var ServiceProviderInterface[]
25
     */
26
    private array $providers = [];
27
28
    /**
29
     * @param string $rootPath The absolute path to the project root.
30
     * @param bool $debug Whether the debug mode is enabled.
31
     * @param bool $checkEvents Whether to check events' configuration.
32
     * @param string|null $environment The environment name.
33
     * @param string $bootstrapGroup The bootstrap configuration group name.
34
     * @param string $eventsGroup The events' configuration group name.
35
     * @param string $diGroup The container definitions' configuration group name.
36
     * @param string $diProvidersGroup The container providers' configuration group name.
37
     * @param string $diDelegatesGroup The container delegates' configuration group name.
38
     * @param string $diTagsGroup The container tags' configuration group name.
39
     * @param string $paramsGroup The configuration parameters group name.
40
     * @param array $nestedParamsGroups Configuration group names that included into configuration parameters group.
41
     * This is needed for recursive merging of parameters.
42
     * @param array $nestedEventsGroups Configuration group names that included into events' configuration group. This
43
     * is needed for reverse and recursive merge of events' configurations.
44
     *
45
     * @psalm-param list<string> $nestedParamsGroups
46
     * @psalm-param list<string> $nestedEventsGroups
47
     */
48
    public function __construct(
49
        public ResponseGrabber $responseGrabber,
50
        string $rootPath,
51
        bool $debug = false,
52
        bool $checkEvents = false,
53
        ?string $environment = null,
54
        string $bootstrapGroup = 'bootstrap-web',
55
        string $eventsGroup = 'events-web',
56
        string $diGroup = 'di-web',
57
        string $diProvidersGroup = 'di-providers-web',
58
        string $diDelegatesGroup = 'di-delegates-web',
59
        string $diTagsGroup = 'di-tags-web',
60
        string $paramsGroup = 'params-web',
61
        array $nestedParamsGroups = ['params'],
62
        array $nestedEventsGroups = ['events'],
63
    ) {
64
        parent::__construct(
65
            $rootPath,
66
            $debug,
67
            $checkEvents,
68
            $environment,
69
            $bootstrapGroup,
70
            $eventsGroup,
71
            $diGroup,
72
            $diProvidersGroup,
73
            $diDelegatesGroup,
74
            $diTagsGroup,
75
            $paramsGroup,
76
            $nestedParamsGroups,
77
            $nestedEventsGroups,
78
        );
79
    }
80
81
    /**
82
     * {@inheritDoc}
83
     */
84
    public function run(): void
85
    {
86
        $this->preloadContainer();
87
88
        /** @var ContainerInterface $container */
89
        $container = $this->container;
90
91
        /** @var Application $application */
92
        $application = $container->get(Application::class);
93
94
        /**
95
         * @var ServerRequestInterface
96
         * @psalm-suppress MixedMethodCall
97
         */
98
        $serverRequest = $container
99
            ->get(ServerRequestFactory::class)
100
            ->createFromParameters(
101
                ...$this->requestParameters,
102
            );
103
104
        /**
105
         * @var ResponseInterface|null $response
106
         */
107
        $response = null;
108
        try {
109
            $application->start();
110
            $response = $application->handle($serverRequest);
111
        } catch (Throwable $throwable) {
112
            $handler = new ThrowableHandler($throwable);
113
            /**
114
             * @psalm-suppress MixedMethodCall
115
             */
116
            $response = $container
117
                ->get(ErrorCatcher::class)
118
                ->process($serverRequest, $handler);
119
        } finally {
120
            $application->afterEmit($response ?? null);
121
            $application->shutdown();
122
            $this->responseGrabber->setResponse($response);
123
        }
124
    }
125
126
    public function withRequest(
127
        string $method,
128
        string $url,
129
        array $queryParams = [],
130
        array $postParams = [],
131
        mixed $body = null,
132
        array $headers = [],
133
        array $cookies = [],
134
        array $files = [],
135
    ): void {
136
        $this->requestParameters = [
137
            'server' => [
138
                'SCRIPT_NAME' => '/index.php',
139
                'REQUEST_METHOD' => $method,
140
                'SERVER_PROTOCOL' => '1.1',
141
                'REQUEST_URI' => $url,
142
            ],
143
            'headers' => $headers,
144
            'cookies' => $cookies,
145
            'get' => $queryParams,
146
            'post' => $postParams,
147
            'files' => $files,
148
            'body' => $body,
149
        ];
150
    }
151
152
    public function preloadContainer(): void
153
    {
154
        /**
155
         * @psalm-suppress UnresolvableInclude
156
         */
157
        require_once $this->rootPath . '/autoload.php';
158
159
        $this->container = $this->getContainer();
160
161
        $this->runBootstrap();
162
        $this->checkEvents();
163
    }
164
165
    /**
166
     * @param ServiceProviderInterface[] $providers
167
     */
168
    public function addProviders(array $providers): void
169
    {
170
        $this->providers = array_merge($this->providers, $providers);
171
    }
172
}
173