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

api-platform / core / 18089937549

29 Sep 2025 07:56AM UTC coverage: 21.764% (-0.3%) from 22.093%
18089937549

Pull #7416

github

web-flow
Merge 061bcc790 into abe0438be
Pull Request #7416: fix(laravel): serializer attributes on Eloquent methods

0 of 151 new or added lines in 11 files covered. (0.0%)

5028 existing lines in 173 files now uncovered.

11889 of 54626 relevant lines covered (21.76%)

25.32 hits per line

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

0.0
/src/JsonSchema/Tests/SchemaFactoryTest.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\JsonSchema\Tests;
15

16
use ApiPlatform\JsonSchema\DefinitionNameFactory;
17
use ApiPlatform\JsonSchema\Schema;
18
use ApiPlatform\JsonSchema\SchemaFactory;
19
use ApiPlatform\JsonSchema\Tests\Fixtures\ApiResource\OverriddenOperationDummy;
20
use ApiPlatform\JsonSchema\Tests\Fixtures\DummyResourceInterface;
21
use ApiPlatform\JsonSchema\Tests\Fixtures\Enum\GenderTypeEnum;
22
use ApiPlatform\JsonSchema\Tests\Fixtures\GenericChild;
23
use ApiPlatform\JsonSchema\Tests\Fixtures\NotAResource;
24
use ApiPlatform\JsonSchema\Tests\Fixtures\NotAResourceWithUnionIntersectTypes;
25
use ApiPlatform\JsonSchema\Tests\Fixtures\Serializable;
26
use ApiPlatform\Metadata\ApiProperty;
27
use ApiPlatform\Metadata\ApiResource;
28
use ApiPlatform\Metadata\Operations;
29
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
30
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
31
use ApiPlatform\Metadata\Property\PropertyNameCollection;
32
use ApiPlatform\Metadata\Put;
33
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
34
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
35
use ApiPlatform\Metadata\ResourceClassResolverInterface;
36
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
37
use PHPUnit\Framework\TestCase;
38
use Prophecy\Argument;
39
use Prophecy\PhpUnit\ProphecyTrait;
40
use Symfony\Component\PropertyInfo\Type as LegacyType;
41
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
42
use Symfony\Component\TypeInfo\Type;
43

44
class SchemaFactoryTest extends TestCase
45
{
46
    use ProphecyTrait;
47

48
    #[IgnoreDeprecations]
49
    public function testBuildSchemaForNonResourceClassLegacy(): void
50
    {
UNCOV
51
        $this->expectUserDeprecationMessage('Since api-platform/metadata 4.2: The "ApiPlatform\Metadata\ApiProperty::withBuiltinTypes()" method is deprecated, use "ApiPlatform\Metadata\ApiProperty::withNativeType()" instead.');
×
52
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
53

54
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
55
        $propertyNameCollectionFactoryProphecy->create(NotAResource::class, Argument::cetera())->willReturn(new PropertyNameCollection(['foo', 'bar', 'genderType']));
×
56

57
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
58
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'foo', Argument::cetera())->willReturn(
×
59
            (new ApiProperty())
×
60
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_STRING)])
×
61
                ->withReadable(true)
×
62
                ->withSchema(['type' => 'string'])
×
63
        );
×
64
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'bar', Argument::cetera())->willReturn(
×
65
            (new ApiProperty())
×
66
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_INT)])
×
67
                ->withReadable(true)
×
68
                ->withDefault('default_bar')
×
69
                ->withExample('example_bar')
×
70
                ->withSchema(['type' => 'integer', 'default' => 'default_bar', 'example' => 'example_bar'])
×
71
        );
×
72
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'genderType', Argument::cetera())->willReturn(
×
73
            (new ApiProperty())
×
UNCOV
74
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_OBJECT)])
×
75
                ->withReadable(true)
×
76
                ->withDefault('male')
×
UNCOV
77
                ->withSchema(['type' => 'object', 'default' => 'male', 'example' => 'male'])
×
78
        );
×
79

80
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
81
        $resourceClassResolverProphecy->isResourceClass(NotAResource::class)->willReturn(false);
×
82

83
        $definitionNameFactory = new DefinitionNameFactory();
×
84

85
        $schemaFactory = new SchemaFactory(
×
86
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
87
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
UNCOV
88
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
89
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
90
            definitionNameFactory: $definitionNameFactory,
×
UNCOV
91
        );
×
92
        $resultSchema = $schemaFactory->buildSchema(NotAResource::class);
×
93

94
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
95
        $definitions = $resultSchema->getDefinitions();
×
96

97
        $this->assertSame((new \ReflectionClass(NotAResource::class))->getShortName(), $rootDefinitionKey);
×
98
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
99
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]);
×
100
        $this->assertSame('object', $definitions[$rootDefinitionKey]['type']);
×
101
        $this->assertArrayNotHasKey('additionalProperties', $definitions[$rootDefinitionKey]);
×
102
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
103
        $this->assertArrayHasKey('foo', $definitions[$rootDefinitionKey]['properties']);
×
104
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['foo']);
×
105
        $this->assertArrayNotHasKey('default', $definitions[$rootDefinitionKey]['properties']['foo']);
×
106
        $this->assertArrayNotHasKey('example', $definitions[$rootDefinitionKey]['properties']['foo']);
×
107
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['foo']['type']);
×
108
        $this->assertArrayHasKey('bar', $definitions[$rootDefinitionKey]['properties']);
×
109
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['bar']);
×
UNCOV
110
        $this->assertArrayHasKey('default', $definitions[$rootDefinitionKey]['properties']['bar']);
×
111
        $this->assertArrayHasKey('example', $definitions[$rootDefinitionKey]['properties']['bar']);
×
112
        $this->assertSame('integer', $definitions[$rootDefinitionKey]['properties']['bar']['type']);
×
113
        $this->assertSame('default_bar', $definitions[$rootDefinitionKey]['properties']['bar']['default']);
×
114
        $this->assertSame('example_bar', $definitions[$rootDefinitionKey]['properties']['bar']['example']);
×
115

116
        $this->assertArrayHasKey('genderType', $definitions[$rootDefinitionKey]['properties']);
×
117
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
118
        $this->assertArrayHasKey('default', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
119
        $this->assertArrayHasKey('example', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
120
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['genderType']['type']);
×
UNCOV
121
        $this->assertSame('male', $definitions[$rootDefinitionKey]['properties']['genderType']['default']);
×
122
        $this->assertSame('male', $definitions[$rootDefinitionKey]['properties']['genderType']['example']);
×
123
    }
124

125
    public function testBuildSchemaForNonResourceClass(): void
126
    {
127
        if (!method_exists(PropertyInfoExtractor::class, 'getType')) { // @phpstan-ignore-line symfony/property-info 6.4 is still allowed and this may be true
×
128
            $this->markTestSkipped('This test only supports type-info component');
×
129
        }
130

131
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
132

133
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
134
        $propertyNameCollectionFactoryProphecy->create(NotAResource::class, Argument::cetera())->willReturn(new PropertyNameCollection(['foo', 'bar', 'genderType', 'items']));
×
135

136
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
137
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'foo', Argument::cetera())->willReturn(
×
138
            (new ApiProperty())
×
139
                ->withNativeType(Type::string())
×
140
                ->withReadable(true)
×
141
                ->withSchema(['type' => 'string'])
×
142
        );
×
143
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'bar', Argument::cetera())->willReturn(
×
144
            (new ApiProperty())
×
145
                ->withNativeType(Type::int())
×
146
                ->withReadable(true)
×
147
                ->withDefault('default_bar')
×
148
                ->withExample('example_bar')
×
UNCOV
149
                ->withSchema(['type' => 'integer', 'default' => 'default_bar', 'example' => 'example_bar'])
×
150
        );
×
151
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'genderType', Argument::cetera())->willReturn(
×
UNCOV
152
            (new ApiProperty())
×
153
                ->withNativeType(Type::object())
×
UNCOV
154
                ->withReadable(true)
×
155
                ->withDefault('male')
×
156
                ->withSchema(['type' => 'object', 'default' => 'male', 'example' => 'male'])
×
157
        );
×
158
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'items', Argument::cetera())->willReturn(
×
159
            (new ApiProperty())
×
160
                ->withNativeType(
×
161
                    Type::generic(Type::object(GenericChild::class), Type::int()),
×
162
                )
×
UNCOV
163
                ->withReadable(true)
×
164
                ->withSchema(['type' => Schema::UNKNOWN_TYPE])
×
165
        );
×
166

167
        $propertyNameCollectionFactoryProphecy->create(GenericChild::class, Argument::cetera())
×
168
            ->willReturn(new PropertyNameCollection(['property']));
×
169
        $propertyMetadataFactoryProphecy->create(GenericChild::class, 'property', Argument::cetera())
×
170
            ->willReturn(
×
171
                (new ApiProperty())
×
172
                    ->withNativeType(Type::string())
×
UNCOV
173
                    ->withReadable(true)
×
174
                    ->withSchema(['type' => 'string'])
×
175
            );
×
176

UNCOV
177
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
178
        $resourceClassResolverProphecy->isResourceClass(NotAResource::class)->willReturn(false);
×
179
        $resourceClassResolverProphecy->isResourceClass(GenericChild::class)->willReturn(false);
×
180

181
        $definitionNameFactory = new DefinitionNameFactory();
×
182

183
        $schemaFactory = new SchemaFactory(
×
UNCOV
184
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
185
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
186
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
187
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
UNCOV
188
            definitionNameFactory: $definitionNameFactory,
×
UNCOV
189
        );
×
UNCOV
190
        $resultSchema = $schemaFactory->buildSchema(NotAResource::class);
×
191

192
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
193
        $definitions = $resultSchema->getDefinitions();
×
194

195
        $this->assertSame((new \ReflectionClass(NotAResource::class))->getShortName(), $rootDefinitionKey);
×
196
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
197
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]);
×
198
        $this->assertSame('object', $definitions[$rootDefinitionKey]['type']);
×
199
        $this->assertArrayNotHasKey('additionalProperties', $definitions[$rootDefinitionKey]);
×
200
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
201
        $this->assertArrayHasKey('foo', $definitions[$rootDefinitionKey]['properties']);
×
202
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['foo']);
×
203
        $this->assertArrayNotHasKey('default', $definitions[$rootDefinitionKey]['properties']['foo']);
×
UNCOV
204
        $this->assertArrayNotHasKey('example', $definitions[$rootDefinitionKey]['properties']['foo']);
×
205
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['foo']['type']);
×
UNCOV
206
        $this->assertArrayHasKey('bar', $definitions[$rootDefinitionKey]['properties']);
×
207
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['bar']);
×
208
        $this->assertArrayHasKey('default', $definitions[$rootDefinitionKey]['properties']['bar']);
×
UNCOV
209
        $this->assertArrayHasKey('example', $definitions[$rootDefinitionKey]['properties']['bar']);
×
210
        $this->assertSame('integer', $definitions[$rootDefinitionKey]['properties']['bar']['type']);
×
211
        $this->assertSame('default_bar', $definitions[$rootDefinitionKey]['properties']['bar']['default']);
×
212
        $this->assertSame('example_bar', $definitions[$rootDefinitionKey]['properties']['bar']['example']);
×
213

214
        $this->assertArrayHasKey('genderType', $definitions[$rootDefinitionKey]['properties']);
×
215
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
216
        $this->assertArrayHasKey('default', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
217
        $this->assertArrayHasKey('example', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
218
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['genderType']['type']);
×
219
        $this->assertSame('male', $definitions[$rootDefinitionKey]['properties']['genderType']['default']);
×
220
        $this->assertSame('male', $definitions[$rootDefinitionKey]['properties']['genderType']['example']);
×
221

222
        $this->assertArrayHasKey('items', $definitions[$rootDefinitionKey]['properties']);
×
223
        $this->assertArrayHasKey('$ref', $definitions[$rootDefinitionKey]['properties']['items']);
×
224
        $this->assertSame('#/definitions/GenericChild', $definitions[$rootDefinitionKey]['properties']['items']['$ref']);
×
225
    }
226

227
    #[IgnoreDeprecations]
228
    public function testBuildSchemaForNonResourceClassWithUnionIntersectTypesLegacy(): void
229
    {
UNCOV
230
        $this->expectUserDeprecationMessage('Since api-platform/metadata 4.2: The "ApiPlatform\Metadata\ApiProperty::withBuiltinTypes()" method is deprecated, use "ApiPlatform\Metadata\ApiProperty::withNativeType()" instead.');
×
231
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
232

233
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
UNCOV
234
        $propertyNameCollectionFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, Argument::cetera())->willReturn(new PropertyNameCollection(['ignoredProperty', 'unionType', 'intersectType']));
×
235

UNCOV
236
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
237
        $propertyMetadataFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, 'ignoredProperty', Argument::cetera())->willReturn(
×
238
            (new ApiProperty())
×
239
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_STRING, nullable: true)])
×
240
                ->withReadable(true)
×
241
                ->withSchema(['type' => ['string', 'null']])
×
242
        );
×
243
        $propertyMetadataFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, 'unionType', Argument::cetera())->willReturn(
×
244
            (new ApiProperty())
×
UNCOV
245
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_STRING, nullable: true), new LegacyType(LegacyType::BUILTIN_TYPE_INT, nullable: true), new LegacyType(LegacyType::BUILTIN_TYPE_FLOAT, nullable: true)])
×
246
                ->withReadable(true)
×
247
                ->withSchema(['oneOf' => [
×
UNCOV
248
                    ['type' => ['string', 'null']],
×
249
                    ['type' => ['integer', 'null']],
×
250
                ]])
×
251
        );
×
252
        $propertyMetadataFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, 'intersectType', Argument::cetera())->willReturn(
×
253
            (new ApiProperty())
×
254
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_OBJECT, class: Serializable::class), new LegacyType(LegacyType::BUILTIN_TYPE_OBJECT, class: DummyResourceInterface::class)])
×
255
                ->withReadable(true)
×
256
                ->withSchema(['type' => 'object'])
×
257
        );
×
258

259
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
260
        $resourceClassResolverProphecy->isResourceClass(NotAResourceWithUnionIntersectTypes::class)->willReturn(false);
×
261

262
        $definitionNameFactory = new DefinitionNameFactory();
×
263

264
        $schemaFactory = new SchemaFactory(
×
265
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
UNCOV
266
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
UNCOV
267
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
UNCOV
268
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
UNCOV
269
            definitionNameFactory: $definitionNameFactory,
×
270
        );
×
UNCOV
271
        $resultSchema = $schemaFactory->buildSchema(NotAResourceWithUnionIntersectTypes::class);
×
272

273
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
UNCOV
274
        $definitions = $resultSchema->getDefinitions();
×
275

276
        $this->assertSame((new \ReflectionClass(NotAResourceWithUnionIntersectTypes::class))->getShortName(), $rootDefinitionKey);
×
277
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
278
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]);
×
279
        $this->assertSame('object', $definitions[$rootDefinitionKey]['type']);
×
280
        $this->assertArrayNotHasKey('additionalProperties', $definitions[$rootDefinitionKey]);
×
281
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
282

283
        $this->assertArrayHasKey('ignoredProperty', $definitions[$rootDefinitionKey]['properties']);
×
284
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['ignoredProperty']);
×
285
        $this->assertSame(['string', 'null'], $definitions[$rootDefinitionKey]['properties']['ignoredProperty']['type']);
×
286
        $this->assertArrayHasKey('unionType', $definitions[$rootDefinitionKey]['properties']);
×
287
        $this->assertArrayHasKey('oneOf', $definitions[$rootDefinitionKey]['properties']['unionType']);
×
UNCOV
288
        $this->assertCount(2, $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf']);
×
289
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf'][0]);
×
290
        $this->assertSame(['string', 'null'], $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf'][0]['type']);
×
UNCOV
291
        $this->assertSame(['integer', 'null'], $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf'][1]['type']);
×
292

UNCOV
293
        $this->assertArrayHasKey('intersectType', $definitions[$rootDefinitionKey]['properties']);
×
294
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['intersectType']);
×
295
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['intersectType']['type']);
×
296
    }
297

298
    public function testBuildSchemaForNonResourceClassWithUnionIntersectTypes(): void
299
    {
300
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
301

UNCOV
302
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
303
        $propertyNameCollectionFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, Argument::cetera())->willReturn(new PropertyNameCollection(['ignoredProperty', 'unionType', 'intersectType']));
×
304

UNCOV
305
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
306
        $propertyMetadataFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, 'ignoredProperty', Argument::cetera())->willReturn(
×
307
            (new ApiProperty())
×
308
                ->withNativeType(Type::nullable(Type::string()))
×
309
                ->withReadable(true)
×
310
                ->withSchema(['type' => ['string', 'null']])
×
311
        );
×
312
        $propertyMetadataFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, 'unionType', Argument::cetera())->willReturn(
×
313
            (new ApiProperty())
×
314
                ->withNativeType(Type::union(Type::string(), Type::int(), Type::float(), Type::null()))
×
315
                ->withReadable(true)
×
316
                ->withSchema(['oneOf' => [
×
317
                    ['type' => ['string', 'null']],
×
UNCOV
318
                    ['type' => ['integer', 'null']],
×
UNCOV
319
                ]])
×
UNCOV
320
        );
×
UNCOV
321
        $propertyMetadataFactoryProphecy->create(NotAResourceWithUnionIntersectTypes::class, 'intersectType', Argument::cetera())->willReturn(
×
UNCOV
322
            (new ApiProperty())
×
UNCOV
323
                ->withNativeType(Type::intersection(Type::object(Serializable::class), Type::object(DummyResourceInterface::class)))
×
UNCOV
324
                ->withReadable(true)
×
UNCOV
325
                ->withSchema(['type' => 'object'])
×
UNCOV
326
        );
×
327

UNCOV
328
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
UNCOV
329
        $resourceClassResolverProphecy->isResourceClass(NotAResourceWithUnionIntersectTypes::class)->willReturn(false);
×
330

UNCOV
331
        $definitionNameFactory = new DefinitionNameFactory();
×
332

UNCOV
333
        $schemaFactory = new SchemaFactory(
×
UNCOV
334
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
UNCOV
335
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
UNCOV
336
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
UNCOV
337
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
UNCOV
338
            definitionNameFactory: $definitionNameFactory,
×
UNCOV
339
        );
×
UNCOV
340
        $resultSchema = $schemaFactory->buildSchema(NotAResourceWithUnionIntersectTypes::class);
×
341

UNCOV
342
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
UNCOV
343
        $definitions = $resultSchema->getDefinitions();
×
344

UNCOV
345
        $this->assertSame((new \ReflectionClass(NotAResourceWithUnionIntersectTypes::class))->getShortName(), $rootDefinitionKey);
×
UNCOV
346
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
UNCOV
347
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]);
×
UNCOV
348
        $this->assertSame('object', $definitions[$rootDefinitionKey]['type']);
×
UNCOV
349
        $this->assertArrayNotHasKey('additionalProperties', $definitions[$rootDefinitionKey]);
×
UNCOV
350
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
351

UNCOV
352
        $this->assertArrayHasKey('ignoredProperty', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
353
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['ignoredProperty']);
×
UNCOV
354
        $this->assertSame(['string', 'null'], $definitions[$rootDefinitionKey]['properties']['ignoredProperty']['type']);
×
355

UNCOV
356
        $this->assertArrayHasKey('unionType', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
357
        $this->assertArrayHasKey('oneOf', $definitions[$rootDefinitionKey]['properties']['unionType']);
×
UNCOV
358
        $this->assertCount(2, $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf']);
×
UNCOV
359
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf'][0]);
×
UNCOV
360
        $this->assertSame(['string', 'null'], $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf'][0]['type']);
×
UNCOV
361
        $this->assertSame(['integer', 'null'], $definitions[$rootDefinitionKey]['properties']['unionType']['oneOf'][1]['type']);
×
362

UNCOV
363
        $this->assertArrayHasKey('intersectType', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
364
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['intersectType']);
×
UNCOV
365
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['intersectType']['type']);
×
366
    }
367

368
    #[IgnoreDeprecations]
369
    public function testBuildSchemaWithSerializerGroupsLegacy(): void
370
    {
UNCOV
371
        $this->expectUserDeprecationMessage('Since api-platform/metadata 4.2: The "ApiPlatform\Metadata\ApiProperty::withBuiltinTypes()" method is deprecated, use "ApiPlatform\Metadata\ApiProperty::withNativeType()" instead.');
×
UNCOV
372
        $shortName = (new \ReflectionClass(OverriddenOperationDummy::class))->getShortName();
×
UNCOV
373
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
UNCOV
374
        $operation = (new Put())->withName('put')->withNormalizationContext([
×
UNCOV
375
            'groups' => 'overridden_operation_dummy_put',
×
UNCOV
376
            AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
×
UNCOV
377
        ])->withShortName($shortName)->withValidationContext(['groups' => ['validation_groups_dummy_put']]);
×
UNCOV
378
        $resourceMetadataFactoryProphecy->create(OverriddenOperationDummy::class)
×
UNCOV
379
            ->willReturn(
×
UNCOV
380
                new ResourceMetadataCollection(OverriddenOperationDummy::class, [
×
UNCOV
381
                    (new ApiResource())->withOperations(new Operations(['put' => $operation])),
×
UNCOV
382
                ])
×
UNCOV
383
            );
×
384

UNCOV
385
        $serializerGroup = 'custom_operation_dummy';
×
386

UNCOV
387
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
UNCOV
388
        $propertyNameCollectionFactoryProphecy->create(OverriddenOperationDummy::class, Argument::type('array'))->willReturn(new PropertyNameCollection(['alias', 'description', 'genderType']));
×
389

UNCOV
390
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
UNCOV
391
        $propertyMetadataFactoryProphecy->create(OverriddenOperationDummy::class, 'alias', Argument::type('array'))->willReturn(
×
UNCOV
392
            (new ApiProperty())
×
UNCOV
393
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_STRING)])
×
UNCOV
394
                ->withReadable(true)
×
UNCOV
395
                ->withSchema(['type' => 'string'])
×
UNCOV
396
        );
×
UNCOV
397
        $propertyMetadataFactoryProphecy->create(OverriddenOperationDummy::class, 'description', Argument::type('array'))->willReturn(
×
UNCOV
398
            (new ApiProperty())
×
UNCOV
399
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_STRING)])
×
UNCOV
400
                ->withReadable(true)
×
UNCOV
401
                ->withSchema(['type' => 'string'])
×
UNCOV
402
        );
×
UNCOV
403
        $propertyMetadataFactoryProphecy->create(OverriddenOperationDummy::class, 'genderType', Argument::type('array'))->willReturn(
×
UNCOV
404
            (new ApiProperty())
×
UNCOV
405
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_OBJECT, false, GenderTypeEnum::class)])
×
UNCOV
406
                ->withReadable(true)
×
UNCOV
407
                ->withDefault(GenderTypeEnum::MALE)
×
UNCOV
408
                ->withSchema(['type' => 'object'])
×
UNCOV
409
        );
×
410

UNCOV
411
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
UNCOV
412
        $resourceClassResolverProphecy->isResourceClass(OverriddenOperationDummy::class)->willReturn(true);
×
UNCOV
413
        $resourceClassResolverProphecy->isResourceClass(GenderTypeEnum::class)->willReturn(true);
×
414

UNCOV
415
        $definitionNameFactory = new DefinitionNameFactory();
×
416

UNCOV
417
        $schemaFactory = new SchemaFactory(
×
UNCOV
418
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
UNCOV
419
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
UNCOV
420
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
UNCOV
421
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
UNCOV
422
            definitionNameFactory: $definitionNameFactory,
×
UNCOV
423
        );
×
UNCOV
424
        $resultSchema = $schemaFactory->buildSchema(OverriddenOperationDummy::class, 'json', Schema::TYPE_OUTPUT, null, null, ['groups' => $serializerGroup, AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false]);
×
425

UNCOV
426
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
UNCOV
427
        $definitions = $resultSchema->getDefinitions();
×
428

UNCOV
429
        $this->assertSame((new \ReflectionClass(OverriddenOperationDummy::class))->getShortName().'-'.$serializerGroup, $rootDefinitionKey);
×
UNCOV
430
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
UNCOV
431
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]);
×
UNCOV
432
        $this->assertSame('object', $definitions[$rootDefinitionKey]['type']);
×
UNCOV
433
        $this->assertFalse($definitions[$rootDefinitionKey]['additionalProperties']);
×
UNCOV
434
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
UNCOV
435
        $this->assertArrayHasKey('alias', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
436
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['alias']);
×
UNCOV
437
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['alias']['type']);
×
UNCOV
438
        $this->assertArrayHasKey('description', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
439
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['description']);
×
UNCOV
440
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['description']['type']);
×
UNCOV
441
        $this->assertArrayHasKey('genderType', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
442
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
443
        $this->assertArrayNotHasKey('default', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
444
        $this->assertArrayNotHasKey('example', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
445
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['genderType']['type']);
×
446
    }
447

448
    public function testBuildSchemaWithSerializerGroups(): void
449
    {
UNCOV
450
        $shortName = (new \ReflectionClass(OverriddenOperationDummy::class))->getShortName();
×
UNCOV
451
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
UNCOV
452
        $operation = (new Put())->withName('put')->withNormalizationContext([
×
UNCOV
453
            'groups' => 'overridden_operation_dummy_put',
×
UNCOV
454
            AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
×
UNCOV
455
        ])->withShortName($shortName)->withValidationContext(['groups' => ['validation_groups_dummy_put']]);
×
UNCOV
456
        $resourceMetadataFactoryProphecy->create(OverriddenOperationDummy::class)
×
UNCOV
457
            ->willReturn(
×
UNCOV
458
                new ResourceMetadataCollection(OverriddenOperationDummy::class, [
×
UNCOV
459
                    (new ApiResource())->withOperations(new Operations(['put' => $operation])),
×
UNCOV
460
                ])
×
UNCOV
461
            );
×
462

UNCOV
463
        $serializerGroup = 'custom_operation_dummy';
×
464

UNCOV
465
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
UNCOV
466
        $propertyNameCollectionFactoryProphecy->create(OverriddenOperationDummy::class, Argument::type('array'))->willReturn(new PropertyNameCollection(['alias', 'description', 'genderType']));
×
467

UNCOV
468
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
UNCOV
469
        $propertyMetadataFactoryProphecy->create(OverriddenOperationDummy::class, 'alias', Argument::type('array'))->willReturn(
×
UNCOV
470
            (new ApiProperty())
×
UNCOV
471
                ->withNativeType(Type::string())
×
UNCOV
472
                ->withReadable(true)
×
UNCOV
473
                ->withSchema(['type' => 'string'])
×
UNCOV
474
        );
×
UNCOV
475
        $propertyMetadataFactoryProphecy->create(OverriddenOperationDummy::class, 'description', Argument::type('array'))->willReturn(
×
UNCOV
476
            (new ApiProperty())
×
UNCOV
477
                ->withNativeType(Type::string())
×
UNCOV
478
                ->withReadable(true)
×
UNCOV
479
                ->withSchema(['type' => 'string'])
×
UNCOV
480
        );
×
UNCOV
481
        $propertyMetadataFactoryProphecy->create(OverriddenOperationDummy::class, 'genderType', Argument::type('array'))->willReturn(
×
UNCOV
482
            (new ApiProperty())
×
UNCOV
483
                ->withNativeType(Type::enum(GenderTypeEnum::class))
×
UNCOV
484
                ->withReadable(true)
×
UNCOV
485
                ->withDefault(GenderTypeEnum::MALE)
×
UNCOV
486
                ->withSchema(['type' => 'object'])
×
UNCOV
487
        );
×
UNCOV
488
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
UNCOV
489
        $resourceClassResolverProphecy->isResourceClass(OverriddenOperationDummy::class)->willReturn(true);
×
UNCOV
490
        $resourceClassResolverProphecy->isResourceClass(GenderTypeEnum::class)->willReturn(true);
×
491

UNCOV
492
        $definitionNameFactory = new DefinitionNameFactory();
×
493

UNCOV
494
        $schemaFactory = new SchemaFactory(
×
UNCOV
495
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
UNCOV
496
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
UNCOV
497
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
UNCOV
498
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
UNCOV
499
            definitionNameFactory: $definitionNameFactory,
×
UNCOV
500
        );
×
UNCOV
501
        $resultSchema = $schemaFactory->buildSchema(OverriddenOperationDummy::class, 'json', Schema::TYPE_OUTPUT, null, null, ['groups' => $serializerGroup, AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false]);
×
502

UNCOV
503
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
UNCOV
504
        $definitions = $resultSchema->getDefinitions();
×
505

UNCOV
506
        $this->assertSame((new \ReflectionClass(OverriddenOperationDummy::class))->getShortName().'-'.$serializerGroup, $rootDefinitionKey);
×
UNCOV
507
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
UNCOV
508
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]);
×
UNCOV
509
        $this->assertSame('object', $definitions[$rootDefinitionKey]['type']);
×
UNCOV
510
        $this->assertFalse($definitions[$rootDefinitionKey]['additionalProperties']);
×
UNCOV
511
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
UNCOV
512
        $this->assertArrayHasKey('alias', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
513
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['alias']);
×
UNCOV
514
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['alias']['type']);
×
UNCOV
515
        $this->assertArrayHasKey('description', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
516
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['description']);
×
UNCOV
517
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['description']['type']);
×
UNCOV
518
        $this->assertArrayHasKey('genderType', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
519
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
520
        $this->assertArrayNotHasKey('default', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
521
        $this->assertArrayNotHasKey('example', $definitions[$rootDefinitionKey]['properties']['genderType']);
×
UNCOV
522
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['genderType']['type']);
×
523
    }
524

525
    #[IgnoreDeprecations]
526
    public function testBuildSchemaForAssociativeArrayLegacy(): void
527
    {
UNCOV
528
        $this->expectUserDeprecationMessage('Since api-platform/metadata 4.2: The "ApiPlatform\Metadata\ApiProperty::withBuiltinTypes()" method is deprecated, use "ApiPlatform\Metadata\ApiProperty::withNativeType()" instead.');
×
UNCOV
529
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
530

UNCOV
531
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
UNCOV
532
        $propertyNameCollectionFactoryProphecy->create(NotAResource::class, Argument::cetera())->willReturn(new PropertyNameCollection(['foo', 'bar']));
×
533

UNCOV
534
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
UNCOV
535
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'foo', Argument::cetera())->willReturn(
×
UNCOV
536
            (new ApiProperty())
×
UNCOV
537
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_ARRAY, false, null, true, new LegacyType(LegacyType::BUILTIN_TYPE_INT), new LegacyType(LegacyType::BUILTIN_TYPE_STRING))])
×
UNCOV
538
                ->withReadable(true)
×
UNCOV
539
                ->withSchema(['type' => 'array', 'items' => ['string', 'int']])
×
UNCOV
540
        );
×
UNCOV
541
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'bar', Argument::cetera())->willReturn(
×
UNCOV
542
            (new ApiProperty())
×
UNCOV
543
                ->withBuiltinTypes([new LegacyType(LegacyType::BUILTIN_TYPE_ARRAY, false, null, true, new LegacyType(LegacyType::BUILTIN_TYPE_STRING), new LegacyType(LegacyType::BUILTIN_TYPE_STRING))])
×
UNCOV
544
                ->withReadable(true)
×
UNCOV
545
                ->withSchema(['type' => 'object', 'additionalProperties' => 'string'])
×
UNCOV
546
        );
×
547

UNCOV
548
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
UNCOV
549
        $resourceClassResolverProphecy->isResourceClass(NotAResource::class)->willReturn(false);
×
550

UNCOV
551
        $definitionNameFactory = new DefinitionNameFactory();
×
552

UNCOV
553
        $schemaFactory = new SchemaFactory(
×
UNCOV
554
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
UNCOV
555
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
UNCOV
556
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
UNCOV
557
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
UNCOV
558
            definitionNameFactory: $definitionNameFactory,
×
UNCOV
559
        );
×
UNCOV
560
        $resultSchema = $schemaFactory->buildSchema(NotAResource::class);
×
561

UNCOV
562
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
UNCOV
563
        $definitions = $resultSchema->getDefinitions();
×
564

UNCOV
565
        $this->assertSame((new \ReflectionClass(NotAResource::class))->getShortName(), $rootDefinitionKey);
×
UNCOV
566
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
UNCOV
567
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
UNCOV
568
        $this->assertArrayHasKey('foo', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
569
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['foo']);
×
UNCOV
570
        $this->assertArrayNotHasKey('additionalProperties', $definitions[$rootDefinitionKey]['properties']['foo']);
×
UNCOV
571
        $this->assertSame('array', $definitions[$rootDefinitionKey]['properties']['foo']['type']);
×
UNCOV
572
        $this->assertArrayHasKey('bar', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
573
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['bar']);
×
UNCOV
574
        $this->assertArrayHasKey('additionalProperties', $definitions[$rootDefinitionKey]['properties']['bar']);
×
UNCOV
575
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['bar']['type']);
×
UNCOV
576
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['bar']['additionalProperties']);
×
577
    }
578

579
    public function testBuildSchemaForAssociativeArray(): void
580
    {
UNCOV
581
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
582

UNCOV
583
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
UNCOV
584
        $propertyNameCollectionFactoryProphecy->create(NotAResource::class, Argument::cetera())->willReturn(new PropertyNameCollection(['foo', 'bar']));
×
585

UNCOV
586
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
UNCOV
587
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'foo', Argument::cetera())->willReturn(
×
UNCOV
588
            (new ApiProperty())
×
UNCOV
589
                ->withNativeType(Type::list(Type::string()))
×
UNCOV
590
                ->withReadable(true)
×
UNCOV
591
                ->withSchema(['type' => 'array', 'items' => ['string', 'int']])
×
UNCOV
592
        );
×
UNCOV
593
        $propertyMetadataFactoryProphecy->create(NotAResource::class, 'bar', Argument::cetera())->willReturn(
×
UNCOV
594
            (new ApiProperty())
×
UNCOV
595
                ->withNativeType(Type::dict(Type::string()))
×
UNCOV
596
                ->withReadable(true)
×
UNCOV
597
                ->withSchema(['type' => 'object', 'additionalProperties' => 'string'])
×
UNCOV
598
        );
×
599

UNCOV
600
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
UNCOV
601
        $resourceClassResolverProphecy->isResourceClass(NotAResource::class)->willReturn(false);
×
602

UNCOV
603
        $definitionNameFactory = new DefinitionNameFactory();
×
604

UNCOV
605
        $schemaFactory = new SchemaFactory(
×
UNCOV
606
            resourceMetadataFactory: $resourceMetadataFactoryProphecy->reveal(),
×
UNCOV
607
            propertyNameCollectionFactory: $propertyNameCollectionFactoryProphecy->reveal(),
×
UNCOV
608
            propertyMetadataFactory: $propertyMetadataFactoryProphecy->reveal(),
×
UNCOV
609
            resourceClassResolver: $resourceClassResolverProphecy->reveal(),
×
UNCOV
610
            definitionNameFactory: $definitionNameFactory,
×
UNCOV
611
        );
×
UNCOV
612
        $resultSchema = $schemaFactory->buildSchema(NotAResource::class);
×
613

UNCOV
614
        $rootDefinitionKey = $resultSchema->getRootDefinitionKey();
×
UNCOV
615
        $definitions = $resultSchema->getDefinitions();
×
616

UNCOV
617
        $this->assertSame((new \ReflectionClass(NotAResource::class))->getShortName(), $rootDefinitionKey);
×
UNCOV
618
        $this->assertTrue(isset($definitions[$rootDefinitionKey]));
×
UNCOV
619
        $this->assertArrayHasKey('properties', $definitions[$rootDefinitionKey]);
×
UNCOV
620
        $this->assertArrayHasKey('foo', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
621
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['foo']);
×
UNCOV
622
        $this->assertArrayNotHasKey('additionalProperties', $definitions[$rootDefinitionKey]['properties']['foo']);
×
UNCOV
623
        $this->assertSame('array', $definitions[$rootDefinitionKey]['properties']['foo']['type']);
×
UNCOV
624
        $this->assertArrayHasKey('bar', $definitions[$rootDefinitionKey]['properties']);
×
UNCOV
625
        $this->assertArrayHasKey('type', $definitions[$rootDefinitionKey]['properties']['bar']);
×
UNCOV
626
        $this->assertArrayHasKey('additionalProperties', $definitions[$rootDefinitionKey]['properties']['bar']);
×
UNCOV
627
        $this->assertSame('object', $definitions[$rootDefinitionKey]['properties']['bar']['type']);
×
UNCOV
628
        $this->assertSame('string', $definitions[$rootDefinitionKey]['properties']['bar']['additionalProperties']);
×
629
    }
630
}
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

© 2026 Coveralls, Inc