• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 15133993414

20 May 2025 09:30AM UTC coverage: 26.313% (-1.2%) from 27.493%
15133993414

Pull #7161

github

web-flow
Merge e2c03d45f into 5459ba375
Pull Request #7161: fix(metadata): infer parameter string type from schema

0 of 2 new or added lines in 1 file covered. (0.0%)

11019 existing lines in 363 files now uncovered.

12898 of 49018 relevant lines covered (26.31%)

34.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.18
/src/Symfony/Bundle/Test/ApiTestAssertionsTrait.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
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
declare(strict_types=1);
13

14
namespace ApiPlatform\Symfony\Bundle\Test;
15

16
use ApiPlatform\JsonSchema\BackwardCompatibleSchemaFactory;
17
use ApiPlatform\JsonSchema\Schema;
18
use ApiPlatform\JsonSchema\SchemaFactoryInterface;
19
use ApiPlatform\Metadata\Get;
20
use ApiPlatform\Metadata\GetCollection;
21
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
22
use ApiPlatform\Symfony\Bundle\Test\Constraint\ArraySubset;
23
use ApiPlatform\Symfony\Bundle\Test\Constraint\MatchesJsonSchema;
24
use PHPUnit\Framework\Constraint\JsonMatches;
25
use PHPUnit\Framework\ExpectationFailedException;
26
use Symfony\Bundle\FrameworkBundle\Test\BrowserKitAssertionsTrait;
27
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
28
use Symfony\Component\Mercure\Debug\TraceableHub;
29
use Symfony\Component\Mercure\HubRegistry;
30
use Symfony\Component\Mercure\Update;
31
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
32
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
33
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
34
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
35
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
36
use Symfony\Contracts\HttpClient\ResponseInterface;
37

38
/**
39
 * @see \Symfony\Bundle\FrameworkBundle\Test\WebTestAssertionsTrait
40
 */
41
trait ApiTestAssertionsTrait
42
{
43
    use BrowserKitAssertionsTrait;
44

45
    /**
46
     * Asserts that the retrieved JSON contains the specified subset.
47
     *
48
     * This method delegates to static::assertArraySubset().
49
     *
50
     * @throws ClientExceptionInterface
51
     * @throws DecodingExceptionInterface
52
     * @throws RedirectionExceptionInterface
53
     * @throws ServerExceptionInterface
54
     * @throws TransportExceptionInterface
55
     */
56
    public static function assertJsonContains(array|string $subset, bool $checkForObjectIdentity = true, string $message = ''): void
57
    {
UNCOV
58
        if (\is_string($subset)) {
11✔
UNCOV
59
            $subset = json_decode($subset, true, 512, \JSON_THROW_ON_ERROR);
2✔
60
        }
UNCOV
61
        if (!\is_array($subset)) {
11✔
UNCOV
62
            throw new \InvalidArgumentException('$subset must be array or string (JSON array or JSON object)');
1✔
63
        }
64

UNCOV
65
        static::assertArraySubset($subset, self::getHttpResponse()->toArray(false), $checkForObjectIdentity, $message);
10✔
66
    }
67

68
    /**
69
     * Asserts that the retrieved JSON is equal to $json.
70
     *
71
     * Both values are canonicalized before the comparison.
72
     */
73
    public static function assertJsonEquals(array|string $json, string $message = ''): void
74
    {
UNCOV
75
        if (\is_array($json)) {
44✔
UNCOV
76
            $json = json_encode(
43✔
UNCOV
77
                $json,
43✔
UNCOV
78
                \JSON_UNESCAPED_UNICODE
43✔
UNCOV
79
                | \JSON_UNESCAPED_SLASHES
43✔
UNCOV
80
                | \JSON_PRESERVE_ZERO_FRACTION
43✔
UNCOV
81
                | \JSON_THROW_ON_ERROR);
43✔
82
        }
83

UNCOV
84
        $constraint = new JsonMatches($json);
44✔
85

UNCOV
86
        static::assertThat(self::getHttpResponse()->getContent(false), $constraint, $message);
44✔
87
    }
88

89
    /**
90
     * Asserts that an array has a specified subset.
91
     *
92
     * Imported from dms/phpunit-arraysubset, because the original constraint has been deprecated.
93
     *
94
     * @copyright Sebastian Bergmann <sebastian@phpunit.de>
95
     * @copyright Rafael Dohms <rdohms@gmail.com>
96
     *
97
     * @see https://github.com/sebastianbergmann/phpunit/issues/3494
98
     *
99
     * @throws ExpectationFailedException
100
     * @throws \Exception
101
     */
102
    public static function assertArraySubset(iterable $subset, iterable $array, bool $checkForObjectIdentity = false, string $message = ''): void
103
    {
UNCOV
104
        $constraint = new ArraySubset($subset, $checkForObjectIdentity);
53✔
105

UNCOV
106
        static::assertThat($array, $constraint, $message);
53✔
107
    }
108

109
    public static function assertMatchesJsonSchema(object|array|string $jsonSchema, ?int $checkMode = null, string $message = ''): void
110
    {
UNCOV
111
        $constraint = new MatchesJsonSchema($jsonSchema, $checkMode);
21✔
112

UNCOV
113
        static::assertThat(self::getHttpResponse()->toArray(false), $constraint, $message);
21✔
114
    }
115

116
    public static function assertMatchesResourceCollectionJsonSchema(string $resourceClass, ?string $operationName = null, string $format = 'jsonld', ?array $serializationContext = null, ?int $checkMode = null): void
117
    {
UNCOV
118
        $schemaFactory = self::getSchemaFactory();
10✔
119

UNCOV
120
        if ($resourceMetadataFactoryCollection = self::getResourceMetadataCollectionFactory()) {
10✔
UNCOV
121
            $operation = $resourceMetadataFactoryCollection->create($resourceClass)->getOperation($operationName, true);
10✔
122
        } else {
123
            $operation = $operationName ? (new GetCollection())->withName($operationName) : new GetCollection();
×
124
        }
125

UNCOV
126
        $serializationContext = $serializationContext ?? $operation->getNormalizationContext();
10✔
127

UNCOV
128
        $schema = $schemaFactory->buildSchema($resourceClass, $format, Schema::TYPE_OUTPUT, $operation, null, ($serializationContext ?? []) + [BackwardCompatibleSchemaFactory::SCHEMA_DRAFT4_VERSION => true]);
10✔
129

UNCOV
130
        static::assertMatchesJsonSchema($schema->getArrayCopy(), $checkMode);
10✔
131
    }
132

133
    public static function assertMatchesResourceItemJsonSchema(string $resourceClass, ?string $operationName = null, string $format = 'jsonld', ?array $serializationContext = null, ?int $checkMode = null): void
134
    {
UNCOV
135
        $schemaFactory = self::getSchemaFactory();
16✔
136

UNCOV
137
        if ($resourceMetadataFactoryCollection = self::getResourceMetadataCollectionFactory()) {
16✔
UNCOV
138
            $operation = $resourceMetadataFactoryCollection->create($resourceClass)->getOperation($operationName);
16✔
139
        } else {
140
            $operation = $operationName ? (new Get())->withName($operationName) : new Get();
×
141
        }
142

UNCOV
143
        $serializationContext = $serializationContext ?? $operation->getNormalizationContext();
16✔
144

UNCOV
145
        $schema = $schemaFactory->buildSchema($resourceClass, $format, Schema::TYPE_OUTPUT, $operation, null, ($serializationContext ?? []) + [BackwardCompatibleSchemaFactory::SCHEMA_DRAFT4_VERSION => true]);
16✔
146

UNCOV
147
        static::assertMatchesJsonSchema($schema->getArrayCopy(), $checkMode);
16✔
148
    }
149

150
    /**
151
     * @return Update[]
152
     */
153
    public static function getMercureMessages(?string $hubName = null): array
154
    {
155
        return array_map(fn (array $update) => $update['object'], self::getMercureHub($hubName)->getMessages());
×
156
    }
157

158
    public static function getMercureMessage(int $index = 0, ?string $hubName = null): ?Update
159
    {
160
        return static::getMercureMessages($hubName)[$index] ?? null;
×
161
    }
162

163
    /**
164
     * @throws \JsonException
165
     */
166
    public static function assertMercureUpdateMatchesJsonSchema(Update $update, array $topics, array|object|string $jsonSchema = '', bool $private = false, ?string $id = null, ?string $type = null, ?int $retry = null, string $message = ''): void
167
    {
168
        static::assertSame($topics, $update->getTopics(), $message);
×
169
        static::assertThat(json_decode($update->getData(), true, \JSON_THROW_ON_ERROR), new MatchesJsonSchema($jsonSchema), $message);
×
170
        static::assertSame($private, $update->isPrivate(), $message);
×
171
        static::assertSame($id, $update->getId(), $message);
×
172
        static::assertSame($type, $update->getType(), $message);
×
173
        static::assertSame($retry, $update->getRetry(), $message);
×
174
    }
175

176
    public static function getMercureRegistry(): HubRegistry
177
    {
178
        $container = static::getContainer();
×
179
        if ($container->has(HubRegistry::class)) {
×
180
            return $container->get(HubRegistry::class);
×
181
        }
182

183
        static::fail('A client must have Mercure enabled to make update assertions. Did you forget to require symfony/mercure?');
×
184
    }
185

186
    public static function getMercureHub(?string $name = null): TraceableHub
187
    {
188
        $hub = self::getMercureRegistry()->getHub($name);
×
189
        if (!$hub instanceof TraceableHub) {
×
190
            static::fail('You must enable "framework.test" to make Mercure update assertions.');
×
191
        }
192

193
        return $hub;
×
194
    }
195

196
    private static function getHttpClient(?Client $newClient = null): ?Client
197
    {
UNCOV
198
        static $client;
237✔
199

UNCOV
200
        if (0 < \func_num_args()) {
237✔
UNCOV
201
            return $client = $newClient;
237✔
202
        }
203

UNCOV
204
        if (!$client instanceof Client) {
73✔
205
            static::fail(\sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', self::class));
×
206
        }
207

UNCOV
208
        return $client;
73✔
209
    }
210

211
    private static function getHttpResponse(): ResponseInterface
212
    {
UNCOV
213
        if (!$response = self::getHttpClient()->getResponse()) {
73✔
214
            static::fail('A client must have an HTTP Response to make assertions. Did you forget to make an HTTP request?');
×
215
        }
216

UNCOV
217
        return $response;
73✔
218
    }
219

220
    private static function getSchemaFactory(): SchemaFactoryInterface
221
    {
UNCOV
222
        $container = static::getContainer();
19✔
223

224
        try {
225
            /** @var SchemaFactoryInterface $schemaFactory */
UNCOV
226
            $schemaFactory = $container->get('api_platform.json_schema.schema_factory');
19✔
227
        } catch (ServiceNotFoundException) {
×
228
            throw new \LogicException('You cannot use the resource JSON Schema assertions if the "api_platform.swagger.versions" config is null or empty.');
×
229
        }
230

UNCOV
231
        return $schemaFactory;
19✔
232
    }
233

234
    private static function getResourceMetadataCollectionFactory(): ?ResourceMetadataCollectionFactoryInterface
235
    {
UNCOV
236
        $container = static::getContainer();
19✔
237

238
        try {
UNCOV
239
            $resourceMetadataFactoryCollection = $container->get('api_platform.metadata.resource.metadata_collection_factory');
19✔
240
        } catch (ServiceNotFoundException) {
×
241
            return null;
×
242
        }
243

UNCOV
244
        return $resourceMetadataFactoryCollection;
19✔
245
    }
246
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc