AbstractServer::testSchemaIsValid()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 6
ccs 0
cts 4
cp 0
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ecodev\Felix\Testing\Api;
6
7
use Ecodev\Felix\Api\Server;
8
use Ecodev\Felix\Testing\Traits\TestWithTransaction;
9
use Exception;
10
use GraphQL\Executor\ExecutionResult;
11
use GraphQL\Type\Schema;
12
use Laminas\Diactoros\ServerRequest;
13
use Mezzio\Session\Session;
14
use Mezzio\Session\SessionMiddleware;
15
use PHPUnit\Framework\TestCase;
16
use Throwable;
17
18
abstract class AbstractServer extends TestCase
19
{
20
    use TestWithTransaction;
21
22
    /**
23
     * Should get user and call User::setCurrent().
24
     */
25
    abstract protected function setCurrentUser(?string $user): void;
26
27
    abstract protected function createSchema(): Schema;
28
29
    protected function createServer(): Server
30
    {
31
        return new Server($this->createSchema(), true);
32
    }
33
34
    public function testSchemaIsValid(): void
35
    {
36
        $schema = $this->createSchema();
37
        $schema->assertValid();
38
39
        self::assertTrue(true, 'schema passes validation');
40
    }
41
42
    /**
43
     * @dataProvider providerQuery
44
     */
45
    public function testQuery(?string $user, ServerRequest $request, array $expected, ?callable $dataPreparator = null, ?callable $additionalAsserts = null): void
46
    {
47
        $this->setCurrentUser($user);
48
49
        if ($dataPreparator) {
50
            $dataPreparator(_em()->getConnection());
51
        }
52
53
        // Configure server
54
        $server = $this->createServer();
55
56
        // Execute query
57
        $result = $server->execute($request);
58
59
        $actual = $this->resultToArray($result);
60
        $actualWithoutTrace = $this->removeTrace($actual);
61
62
        try {
63
            self::assertEquals($expected, $actualWithoutTrace);
64
        } catch (Throwable $e) {
65
            // If assertion fails, print the version of the result with trace for easier debugging
66
            ve($actual);
67
68
            throw $e;
69
        }
70
71
        if ($additionalAsserts) {
72
            $additionalAsserts(_em()->getConnection());
73
        }
74
    }
75
76
    public function providerQuery(): array
77
    {
78
        $data = [];
79
        $files = glob('tests/data/query/*.php');
80
        if ($files === false) {
81
            throw new Exception('Could not find any queries to test server');
82
        }
83
84
        foreach ($files as $file) {
85
            $name = str_replace('-', ' ', basename($file, '.php'));
86
            $user = preg_replace('/\d/', '', explode(' ', $name)[0]);
87
            if ($user === 'anonymous') {
88
                $user = null;
89
            }
90
91
            $args = require $file;
92
93
            // Convert arg into request
94
            $request = new ServerRequest();
95
            $args[0] = $request
96
                ->withParsedBody($args[0])
97
                ->withAttribute(SessionMiddleware::SESSION_ATTRIBUTE, new Session([]))
98
                ->withMethod('POST')
99
                ->withHeader('content-type', ['application/json']);
100
101
            array_unshift($args, $user);
102
            $data[$name] = $args;
103
        }
104
105
        return $data;
106
    }
107
108
    /**
109
     * @param ExecutionResult|ExecutionResult[] $result
110
     */
111
    private function resultToArray(array|ExecutionResult $result): array
112
    {
113
        if (is_array($result)) {
0 ignored issues
show
introduced by
The condition is_array($result) is always true.
Loading history...
114
            foreach ($result as &$one) {
115
                $one = $one->toArray();
116
            }
117
        } else {
118
            $result = $result->toArray();
119
        }
120
121
        return $result;
122
    }
123
124
    private function removeTrace(array $result): array
125
    {
126
        if (array_key_exists('errors', $result)) {
127
            $result = $this->removeTraceOneResult($result);
128
        } else {
129
            foreach ($result as &$r) {
130
                $r = $this->removeTraceOneResult($r);
131
            }
132
        }
133
134
        return $result;
135
    }
136
137
    private function removeTraceOneResult(array $result): array
138
    {
139
        if (array_key_exists('errors', $result)) {
140
            foreach ($result['errors'] as &$error) {
141
                unset($error['extensions']['file'], $error['extensions']['line'], $error['extensions']['trace']);
142
143
                if (array_key_exists('extensions', $error) && !$error['extensions']) {
144
                    unset($error['extensions']);
145
                }
146
            }
147
        }
148
149
        return $result;
150
    }
151
}
152