Passed
Push — master ( e12e8b...e5ca0d )
by Dmitriy
09:50 queued 09:12
created

FunctionalTester::fillDefaultMocks()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 3
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 20
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Testing;
6
7
use Exception;
8
use Psr\Container\ContainerInterface;
9
use RuntimeException;
10
11
final class FunctionalTester
12
{
13
    private ?TestApplicationRunner $application = null;
14
    private ?MockServiceProvider $mockServiceProvider = null;
15
16
    public function __construct(
17
        private array $defaultMocks = [
18
            'Yiisoft\Session\SessionInterface' => 'Yiisoft\Session\NullSession',
19
        ]
20
    ) {
21
    }
22
23
    public function mockService(string $id, mixed $definition): void
24
    {
25
        $this->getMockServiceProvider()->addDefinition($id, $definition);
26
    }
27
28
    public function bootstrapApplication(string $definitionEnvironment = 'web', ?string $projectRootPath = null): void
29
    {
30
        if ($this->application !== null) {
31
            return;
32
        }
33
34
        if ($projectRootPath === null) {
35
            $projectRootPath = dirname(__DIR__, 5);
36
        }
37
38
        $this->application = new TestApplicationRunner(
39
            new ResponseGrabber(),
40
            $projectRootPath,
41
            false,
42
            null,
43
            $definitionEnvironment
44
        );
45
        $this->application->addProviders([$this->getMockServiceProvider()]);
0 ignored issues
show
Bug introduced by
The method addProviders() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
        $this->application->/** @scrutinizer ignore-call */ 
46
                            addProviders([$this->getMockServiceProvider()]);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
46
    }
47
48
    public function doRequest(string $method, string $url): ResponseAccessor
49
    {
50
        $this->ensureApplicationLoaded();
51
52
        $this->application?->withRequest($method, $url);
53
        $this->application?->run();
54
55
        return $this->application?->responseGrabber?->getResponse() ?? throw new RuntimeException(
56
            'Either $application or $response is null'
57
        );
58
    }
59
60
    /**
61
     * @psalm-suppress NullableReturnStatement
62
     */
63
    public function getContainer(): ContainerInterface
64
    {
65
        $this->ensureApplicationLoaded();
66
67
        $this->application?->preloadContainer();
68
69
        return $this->application->container ?? throw new Exception('Container was not set.');
70
    }
71
72
    private function ensureApplicationLoaded(): void
73
    {
74
        if ($this->application === null) {
75
            throw new RuntimeException(
76
                'The application was not initialized. Initialize the application before the request: `$this->bootstrapApplication(\'web\')`.'
77
            );
78
        }
79
    }
80
81
    private function getMockServiceProvider(): MockServiceProvider
82
    {
83
        if ($this->mockServiceProvider === null) {
84
            $this->mockServiceProvider = new MockServiceProvider();
85
            $this->fillDefaultMocks($this->mockServiceProvider);
0 ignored issues
show
Bug introduced by
$this->mockServiceProvider of type null is incompatible with the type Yiisoft\Yii\Testing\MockServiceProvider expected by parameter $mockServiceProvider of Yiisoft\Yii\Testing\Func...ter::fillDefaultMocks(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

85
            $this->fillDefaultMocks(/** @scrutinizer ignore-type */ $this->mockServiceProvider);
Loading history...
86
        }
87
        return $this->mockServiceProvider;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->mockServiceProvider could return the type null which is incompatible with the type-hinted return Yiisoft\Yii\Testing\MockServiceProvider. Consider adding an additional type-check to rule them out.
Loading history...
88
    }
89
90
    private function fillDefaultMocks(MockServiceProvider $mockServiceProvider): void
91
    {
92
        foreach ($this->defaultMocks as $key => $value) {
93
            if (interface_exists($key) || class_exists($key)) {
94
                $mockServiceProvider->addDefinition($key, $value);
95
            }
96
        }
97
    }
98
}
99