ApiTestCase   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 253
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 28
eloc 87
c 5
b 0
f 0
dl 0
loc 253
ccs 0
cts 130
cp 0
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A getFixtureReference() 0 3 1
A tearDown() 0 5 1
A getFixtureGlobalId() 0 8 2
A encodeID() 0 17 4
A setUp() 0 9 1
A setUpBeforeClass() 0 3 1
A debugLastQuery() 0 37 5
A after() 0 2 1
A getClient() 0 3 1
A decodeID() 0 3 1
A runTest() 0 10 3
A loadFixtures() 0 8 2
A createClient() 0 3 1
A __construct() 0 5 1
A before() 0 2 1
A send() 0 14 2
1
<?php
2
3
/*******************************************************************************
4
 *  This file is part of the GraphQL Bundle package.
5
 *
6
 *  (c) YnloUltratech <[email protected]>
7
 *
8
 *  For the full copyright and license information, please view the LICENSE
9
 *  file that was distributed with this source code.
10
 ******************************************************************************/
11
12
namespace Ynlo\GraphQLBundle\Test;
13
14
use Doctrine\Common\DataFixtures\ReferenceRepository;
15
use PHPUnit\Util\Blacklist;
16
use Symfony\Bundle\FrameworkBundle\Client;
17
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
use Ynlo\GraphQLBundle\Definition\Registry\DefinitionRegistry;
21
use Ynlo\GraphQLBundle\Model\ID;
22
use Ynlo\GraphQLBundle\Model\NodeInterface;
23
use Ynlo\GraphQLBundle\Test\Assert\DoctrineAssertTrait;
24
use Ynlo\GraphQLBundle\Test\Assert\JsonAssertTrait;
25
use Ynlo\GraphQLBundle\Test\Assert\ResponseAssertTrait;
26
use Ynlo\GraphQLBundle\Test\FixtureLoader\FixtureLoader;
27
use Ynlo\GraphQLBundle\Test\Helper\DoctrineHelperTrait;
28
use Ynlo\GraphQLBundle\Test\Helper\JsonHelperTrait;
29
use Ynlo\GraphQLBundle\Test\Helper\ResponseHelperTrait;
30
use Ynlo\GraphQLBundle\Util\IDEncoder;
31
32
/**
33
 * @deprecated in favor of Behat tests
34
 */
35
class ApiTestCase extends WebTestCase
36
{
37
    // helpers
38
    use DoctrineHelperTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait Ynlo\GraphQLBundle\Test\Helper\DoctrineHelperTrait has been deprecated: in favor of Behat tests ( Ignorable by Annotation )

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

38
    use /** @scrutinizer ignore-deprecated */ DoctrineHelperTrait;

This trait has been deprecated. The supplier of the trait has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.

Loading history...
39
    use JsonHelperTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait Ynlo\GraphQLBundle\Test\Helper\JsonHelperTrait has been deprecated: in favor of Behat tests ( Ignorable by Annotation )

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

39
    use /** @scrutinizer ignore-deprecated */ JsonHelperTrait;

This trait has been deprecated. The supplier of the trait has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.

Loading history...
40
    use ResponseHelperTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait Ynlo\GraphQLBundle\Test\Helper\ResponseHelperTrait has been deprecated: in favor of Behat tests ( Ignorable by Annotation )

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

40
    use /** @scrutinizer ignore-deprecated */ ResponseHelperTrait;

This trait has been deprecated. The supplier of the trait has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.

Loading history...
41
42
    // asserts
43
    use DoctrineAssertTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait Ynlo\GraphQLBundle\Test\Assert\DoctrineAssertTrait has been deprecated: in favor of Behat tests ( Ignorable by Annotation )

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

43
    use /** @scrutinizer ignore-deprecated */ DoctrineAssertTrait;

This trait has been deprecated. The supplier of the trait has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.

Loading history...
44
    use JsonAssertTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait Ynlo\GraphQLBundle\Test\Assert\JsonAssertTrait has been deprecated: in favor of Behat tests ( Ignorable by Annotation )

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

44
    use /** @scrutinizer ignore-deprecated */ JsonAssertTrait;

This trait has been deprecated. The supplier of the trait has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.

Loading history...
45
    use ResponseAssertTrait;
0 ignored issues
show
Deprecated Code introduced by
The trait Ynlo\GraphQLBundle\Test\Assert\ResponseAssertTrait has been deprecated: in favor of Behat tests ( Ignorable by Annotation )

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

45
    use /** @scrutinizer ignore-deprecated */ ResponseAssertTrait;

This trait has been deprecated. The supplier of the trait has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the trait will be removed and what other trait to use instead.

Loading history...
Bug introduced by
The trait Ynlo\GraphQLBundle\Test\Assert\ResponseAssertTrait requires the property $headers which is not provided by Ynlo\GraphQLBundle\Test\ApiTestCase.
Loading history...
46
47
    /**
48
     * @var ReferenceRepository
49
     */
50
    protected static $referenceRepository;
51
52
    /**
53
     * @var Client
54
     */
55
    protected static $client;
56
57
    /**
58
     * Whether to insulate each request or not.
59
     * The request ran into a separate process to avoid
60
     * any conflict (cache, container, doctrine etc..) with previous requests.
61
     *
62
     * NOTE: should be disabled for debugging
63
     *
64
     * @var bool
65
     */
66
    protected static $insulateRequests = false;
67
68
    /**
69
     * Endpoint where the API is available, e.g. /api
70
     *
71
     * @var string
72
     */
73
    protected static $endpoint = '';
74
75
    private static $lastQuery;
76
77
    private static $lastQueryExecutionTime = 0;
78
79
    public function __construct(string $name = null, array $data = [], string $dataName = '')
80
    {
81
        parent::__construct($name, $data, $dataName);
82
83
        Blacklist::$blacklistedClassNames['Ynlo\GraphQLBundle\Test\ApiTestCase'] = 1;
84
    }
85
86
    final public static function setUpBeforeClass()
87
    {
88
        static::$client = null;
89
    }
90
91
    final public function setUp()
92
    {
93
        parent::setUp();
94
95
        self::$lastQuery = null;
96
        self::$lastQueryExecutionTime = 0;
97
98
        static::loadFixtures();
99
        $this->before();
100
    }
101
102
    /**
103
     * This method is called before a test is executed.
104
     */
105
    public function before()
106
    {
107
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    final protected function tearDown()
114
    {
115
        parent::tearDown();
116
        static::$client = null;
117
        $this->after();
118
    }
119
120
    /**
121
     * This method is called after a test is executed.
122
     */
123
    public function after()
124
    {
125
126
    }
127
128
    protected static function createClient(array $options = [], array $server = [])
129
    {
130
        return static::$client = parent::createClient($options, $server);
131
    }
132
133
    protected static function getClient(): Client
134
    {
135
        return static::$client ?? static::createClient();
136
    }
137
138
    protected static function loadFixtures($classNames = [])
139
    {
140
        /** @var Client $client */
141
        $client = static::getClient();
142
        $container = $client->getContainer();
143
        if ($container) {
144
            $fixtureLoader = new FixtureLoader($container, $container->get('doctrine'));
0 ignored issues
show
Bug introduced by
It seems like $container->get('doctrine') can also be of type null; however, parameter $registry of Ynlo\GraphQLBundle\Test\...reLoader::__construct() does only seem to accept Doctrine\Bundle\DoctrineBundle\Registry, maybe add an additional type check? ( Ignorable by Annotation )

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

144
            $fixtureLoader = new FixtureLoader($container, /** @scrutinizer ignore-type */ $container->get('doctrine'));
Loading history...
145
            static::$referenceRepository = $fixtureLoader->loadFixtures($classNames);
146
        }
147
    }
148
149
    protected static function getFixtureReference(string $name)
150
    {
151
        return self::$referenceRepository->getReference($name);
152
    }
153
154
    /**
155
     * @param string    $query     query or mutation in GraphQL format
156
     * @param array     $variables array of variables
157
     * @param bool|null $insulate  Whether to insulate the requests or not. Leave null to use default value.
158
     *                             The request ran into a separate process to avoid
159
     *                             any conflict (cache, container, doctrine etc..) with previous requests.
160
     *                             NOTE: should be disabled for debugging
161
     *
162
     * @return Response
163
     */
164
    protected static function send($query, array $variables = [], $insulate = null): Response
165
    {
166
        self::$lastQuery = ['query' => $query, 'variables' => $variables];
167
168
        if (null === $insulate) {
169
            $insulate = static::$insulateRequests;
170
        }
171
172
        $client = static::getClient();
173
        $client->insulate($insulate);
174
175
        $client->request(Request::METHOD_POST, self::$endpoint, [], [], [], json_encode(self::$lastQuery));
176
177
        return $client->getResponse();
178
    }
179
180
    /**
181
     * Use this method to get the global ID of a existent fixture
182
     *
183
     * getFixtureGlobalId('user1') => VXNlcjox
184
     */
185
    protected static function getFixtureGlobalId(string $name): string
186
    {
187
        $fixture = static::getFixtureReference($name);
188
        if ($fixture instanceof NodeInterface) {
189
            return static::encodeID($fixture);
190
        }
191
192
        throw new \RuntimeException(sprintf('The fixture must implements %s', NodeInterface::class));
193
    }
194
195
    /**
196
     * Encode given id or node interface to global ID
197
     *
198
     * encodeID($user) => VXNlcjox
199
     * encodeID(1, 'User') => VXNlcjox
200
     *
201
     * @param string|NodeInterface $node     id of the node or instance
202
     * @param string               $nodeType required in case the first argument is scalar
203
     *
204
     * @return string
205
     */
206
    protected static function encodeID($node, $nodeType = null)
207
    {
208
        if (!is_object($node) && !$nodeType) {
209
            throw new \RuntimeException('Node type is required when use scalar ID as node');
210
        }
211
212
        if (!$node instanceof NodeInterface) {
213
            $nodeClass = static::getClient()
214
                               ->getContainer()
215
                               ->get(DefinitionRegistry::class)
216
                               ->getEndpoint()
217
                               ->getClassForType($nodeType);
218
219
            $node = self::getDoctrine()->getEntityManager()->getReference($nodeClass, $node);
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Bundle\Doctrine...try::getEntityManager() has been deprecated. ( Ignorable by Annotation )

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

219
            $node = /** @scrutinizer ignore-deprecated */ self::getDoctrine()->getEntityManager()->getReference($nodeClass, $node);
Loading history...
220
        }
221
222
        return IDEncoder::encode($node);
223
    }
224
225
    /**
226
     * Decode globalId to get type and real database id
227
     *
228
     * @deprecated since v1.1 use IDEncoder utility instead
229
     */
230
    protected static function decodeID(string $globalID): ID
231
    {
232
        return ID::createFromString($globalID);
0 ignored issues
show
Deprecated Code introduced by
The function Ynlo\GraphQLBundle\Model\ID::createFromString() has been deprecated: since v1.1 IDEncoder::decode() instead ( Ignorable by Annotation )

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

232
        return /** @scrutinizer ignore-deprecated */ ID::createFromString($globalID);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
233
    }
234
235
    /**
236
     * Print helpful debug information for latest executed query
237
     */
238
    protected static function debugLastQuery()
239
    {
240
        if (self::$lastQuery) {
241
            $query = self::$lastQuery['query'] ?? null;
242
243
            $type = 'QUERY';
244
            if (preg_match('/^\s*mutation/', $query)) {
245
                $type = 'MUTATION';
246
            }
247
248
            $variables = self::$lastQuery['variables'] ?? null;
249
250
            print_r("\033[43m\n\n----------------------- $type ---------------------\n\n\033[0m");
251
            print_r($query ?? null);
252
            print_r("\n\n");
253
            print_r("\033[46m------------------- VARIABLES-----------------------\n\n\033[0m");
254
            print_r(json_encode($variables, JSON_PRETTY_PRINT));
255
            print_r("\n\n");
256
257
            /** @var Response $response */
258
            $response = static::getClient()->getResponse();
259
            $bg = $response->getStatusCode() >= 400 ? 41: 42;
260
            print_r("\033[{$bg}m-------------------- RESPONSE ----------------------\n\n\033[0m");
261
            print_r(sprintf("STATUS: [%s] %s \n", $response->getStatusCode(), Response::$statusTexts[$response->getStatusCode()] ?? 'Unknown Status'));
262
            print_r(sprintf("TIME: %s ms \n\n", self::$lastQueryExecutionTime));
263
264
            $content = $response->getContent();
265
            $json = @json_decode($content, true);
266
            if ($json) {
267
                print_r(json_encode($json, JSON_PRETTY_PRINT));
268
            } else {
269
                print_r($content);
270
            }
271
            print_r("\n\n");
272
            print_r("-----------------------------------------------------\n\n");
273
        } else {
274
            throw new \RuntimeException('Does not exist any executed query on current test, try use this method after "send" the query.');
275
        }
276
    }
277
278
    protected function runTest()
279
    {
280
        try {
281
            parent::runTest();
282
        } catch (\Exception $exception) {
283
            if (self::$lastQuery) {
284
                self::debugLastQuery();
285
            }
286
287
            throw $exception;
288
        }
289
    }
290
}
291
292