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

api-platform / core / 14375359694

10 Apr 2025 08:01AM UTC coverage: 8.491% (+0.07%) from 8.425%
14375359694

push

github

web-flow
fix(hydra): use correctly enable_docs (#7062)

18 of 118 new or added lines in 5 files covered. (15.25%)

508 existing lines in 190 files now uncovered.

13401 of 157825 relevant lines covered (8.49%)

22.87 hits per line

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

0.0
/src/Hydra/Tests/Serializer/DocumentationNormalizerTest.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\Hydra\Tests\Serializer;
15

16
use ApiPlatform\Documentation\Documentation;
17
use ApiPlatform\Hydra\Serializer\DocumentationNormalizer;
18
use ApiPlatform\Hydra\Tests\Fixtures\CustomConverter;
19
use ApiPlatform\JsonLd\ContextBuilder;
20
use ApiPlatform\Metadata\ApiProperty;
21
use ApiPlatform\Metadata\ApiResource;
22
use ApiPlatform\Metadata\Get;
23
use ApiPlatform\Metadata\GetCollection;
24
use ApiPlatform\Metadata\Operations;
25
use ApiPlatform\Metadata\Post;
26
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
27
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
28
use ApiPlatform\Metadata\Property\PropertyNameCollection;
29
use ApiPlatform\Metadata\Put;
30
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
31
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
32
use ApiPlatform\Metadata\Resource\ResourceNameCollection;
33
use ApiPlatform\Metadata\ResourceClassResolverInterface;
34
use ApiPlatform\Metadata\UrlGeneratorInterface;
35
use PHPUnit\Framework\TestCase;
36
use Prophecy\Argument;
37
use Prophecy\PhpUnit\ProphecyTrait;
38
use Symfony\Component\PropertyInfo\Type;
39

40
use const ApiPlatform\JsonLd\HYDRA_CONTEXT;
41

42
/**
43
 * @author Amrouche Hamza <hamza.simperfit@gmail.com>
44
 */
45
class DocumentationNormalizerTest extends TestCase
46
{
47
    use ProphecyTrait;
48

49
    public function testNormalize(): void
50
    {
51
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
52
        $resourceMetadataFactoryProphecy->create('dummy')->shouldBeCalled()->willReturn(new ResourceMetadataCollection('dummy', [
×
53
            (new ApiResource())->withShortName('dummy')->withDescription('dummy')->withTypes(['#dummy'])->withOperations(new Operations([
×
54
                'get' => (new Get())->withHydraContext(['hydra:foo' => 'bar', 'hydra:title' => 'foobar'])->withTypes(['#dummy'])->withShortName('dummy'),
×
55
                'put' => (new Put())->withShortName('dummy'),
×
56
                'get_collection' => (new GetCollection())->withShortName('dummy'),
×
57
                'post' => (new Post())->withShortName('dummy'),
×
58
            ])),
×
59
            (new ApiResource())->withShortName('relatedDummy')->withOperations(new Operations(['get' => (new Get())->withTypes(['#relatedDummy'])->withShortName('relatedDummy')])),
×
60
        ]));
×
61
        $resourceMetadataFactoryProphecy->create('relatedDummy')->shouldBeCalled()->willReturn(new ResourceMetadataCollection('relatedDummy', [
×
62
            (new ApiResource())->withShortName('relatedDummy')->withOperations(new Operations(['get' => (new Get())->withShortName('relatedDummy')])),
×
63
        ]));
×
64

65
        $this->doTestNormalize($resourceMetadataFactoryProphecy->reveal());
×
66
    }
67

68
    private function doTestNormalize($resourceMetadataFactory = null): void
69
    {
70
        $title = 'Test Api';
×
71
        $desc = 'test ApiGerard';
×
72
        $version = '0.0.0';
×
73
        $documentation = new Documentation(new ResourceNameCollection(['dummy' => 'dummy']), $title, $desc, $version);
×
74

75
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
76
        $propertyNameCollectionFactoryProphecy->create('dummy', [])->shouldBeCalled()->willReturn(new PropertyNameCollection(['name', 'description', 'nameConverted', 'relatedDummy', 'iri']));
×
77

78
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
79
        $propertyMetadataFactoryProphecy->create('dummy', 'name', Argument::type('array'))->shouldBeCalled()->willReturn(
×
80
            (new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('name')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true)
×
81
        );
×
82
        $propertyMetadataFactoryProphecy->create('dummy', 'description', Argument::type('array'))->shouldBeCalled()->willReturn(
×
83
            (new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('description')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true)->withJsonldContext(['@type' => '@id'])
×
84
        );
×
85
        $propertyMetadataFactoryProphecy->create('dummy', 'nameConverted', Argument::type('array'))->shouldBeCalled()->willReturn(
×
86
            (new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('name converted')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true)
×
87
        );
×
88
        $propertyMetadataFactoryProphecy->create('dummy', 'relatedDummy', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_OBJECT, false, 'dummy', true, null, new Type(Type::BUILTIN_TYPE_OBJECT, false, 'relatedDummy'))])->withDescription('This is a name.')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true));
×
89
        $propertyMetadataFactoryProphecy->create('dummy', 'iri', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withIris(['https://schema.org/Dummy']));
×
90

91
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
92
        $resourceClassResolverProphecy->isResourceClass(Argument::type('string'))->willReturn(true);
×
93

94
        $urlGenerator = $this->prophesize(UrlGeneratorInterface::class);
×
95
        $urlGenerator->generate('api_entrypoint')->willReturn('/')->shouldBeCalledTimes(1);
×
96
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'])->willReturn('/doc')->shouldBeCalledTimes(1);
×
97

98
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'], 0)->willReturn('/doc')->shouldBeCalledTimes(1);
×
99

100
        $documentationNormalizer = new DocumentationNormalizer(
×
101
            $resourceMetadataFactory,
×
102
            $propertyNameCollectionFactoryProphecy->reveal(),
×
103
            $propertyMetadataFactoryProphecy->reveal(),
×
104
            $resourceClassResolverProphecy->reveal(),
×
105
            $urlGenerator->reveal(),
×
106
            new CustomConverter()
×
107
        );
×
108

109
        $expected = [
×
110
            '@context' => [
×
111
                HYDRA_CONTEXT,
×
112
                [
×
113
                    '@vocab' => '/doc#',
×
114
                    'hydra' => 'http://www.w3.org/ns/hydra/core#',
×
115
                    'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
×
116
                    'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
×
117
                    'xmls' => 'http://www.w3.org/2001/XMLSchema#',
×
118
                    'owl' => 'http://www.w3.org/2002/07/owl#',
×
119
                    'schema' => 'https://schema.org/',
×
120
                    'domain' => [
×
121
                        '@id' => 'rdfs:domain',
×
122
                        '@type' => '@id',
×
123
                    ],
×
124
                    'range' => [
×
125
                        '@id' => 'rdfs:range',
×
126
                        '@type' => '@id',
×
127
                    ],
×
128
                    'subClassOf' => [
×
129
                        '@id' => 'rdfs:subClassOf',
×
130
                        '@type' => '@id',
×
131
                    ],
×
132
                ],
×
133
            ],
×
134
            '@id' => '/doc',
×
135
            '@type' => 'hydra:ApiDocumentation',
×
136
            'hydra:title' => 'Test Api',
×
137
            'hydra:description' => 'test ApiGerard',
×
138
            'hydra:supportedClass' => [
×
139
                [
×
140
                    '@id' => '#dummy',
×
141
                    '@type' => 'hydra:Class',
×
142
                    'hydra:title' => 'dummy',
×
143
                    'hydra:description' => 'dummy',
×
144
                    'hydra:supportedProperty' => [
×
145
                        [
×
146
                            '@type' => 'hydra:SupportedProperty',
×
147
                            'hydra:property' => [
×
148
                                '@id' => '#dummy/name',
×
149
                                '@type' => 'rdf:Property',
×
150
                                'label' => 'name',
×
151
                                'domain' => '#dummy',
×
152
                                'range' => 'xmls:string',
×
153
                            ],
×
154
                            'hydra:title' => 'name',
×
155
                            'hydra:required' => false,
×
156
                            'hydra:readable' => true,
×
157
                            'hydra:writeable' => true,
×
158
                            'hydra:description' => 'name',
×
159
                        ],
×
160
                        [
×
161
                            '@type' => 'hydra:SupportedProperty',
×
162
                            'hydra:property' => [
×
163
                                '@id' => '#dummy/description',
×
164
                                '@type' => 'rdf:Property',
×
165
                                'label' => 'description',
×
166
                                'domain' => '#dummy',
×
167
                                'range' => '@id',
×
168
                            ],
×
169
                            'hydra:title' => 'description',
×
170
                            'hydra:required' => false,
×
171
                            'hydra:readable' => true,
×
172
                            'hydra:writeable' => true,
×
173
                            'hydra:description' => 'description',
×
174
                        ],
×
175
                        [
×
176
                            '@type' => 'hydra:SupportedProperty',
×
177
                            'hydra:property' => [
×
178
                                '@id' => '#dummy/name_converted',
×
179
                                '@type' => 'rdf:Property',
×
180
                                'label' => 'name_converted',
×
181
                                'domain' => '#dummy',
×
182
                                'range' => 'xmls:string',
×
183
                            ],
×
184
                            'hydra:title' => 'name_converted',
×
185
                            'hydra:required' => false,
×
186
                            'hydra:readable' => true,
×
187
                            'hydra:writeable' => true,
×
188
                            'hydra:description' => 'name converted',
×
189
                        ],
×
190
                        [
×
191
                            '@type' => 'hydra:SupportedProperty',
×
192
                            'hydra:property' => [
×
193
                                '@id' => '#dummy/relatedDummy',
×
194
                                '@type' => 'rdf:Property',
×
195
                                'label' => 'relatedDummy',
×
196
                                'domain' => '#dummy',
×
197
                                'range' => '#relatedDummy',
×
198
                            ],
×
199
                            'hydra:title' => 'relatedDummy',
×
200
                            'hydra:required' => false,
×
201
                            'hydra:readable' => true,
×
202
                            'hydra:writeable' => true,
×
203
                            'hydra:description' => 'This is a name.',
×
204
                        ],
×
205
                        [
×
206
                            '@type' => 'hydra:SupportedProperty',
×
207
                            'hydra:property' => [
×
208
                                '@id' => 'https://schema.org/Dummy',
×
209
                                '@type' => 'rdf:Property',
×
210
                                'label' => 'iri',
×
211
                                'domain' => '#dummy',
×
212
                            ],
×
213
                            'hydra:title' => 'iri',
×
214
                            'hydra:required' => null,
×
215
                            'hydra:readable' => null,
×
216
                            'hydra:writeable' => false,
×
217
                        ],
×
218
                    ],
×
219
                    'hydra:supportedOperation' => [
×
220
                        [
×
221
                            '@type' => ['hydra:Operation', 'schema:FindAction'],
×
222
                            'hydra:method' => 'GET',
×
223
                            'hydra:title' => 'foobar',
×
224
                            'returns' => 'dummy',
×
225
                            'hydra:foo' => 'bar',
×
226
                            'hydra:description' => 'Retrieves a dummy resource.',
×
227
                        ],
×
228
                        [
×
229
                            '@type' => ['hydra:Operation', 'schema:ReplaceAction'],
×
230
                            'expects' => 'dummy',
×
231
                            'hydra:method' => 'PUT',
×
232
                            'hydra:title' => 'putdummy',
×
233
                            'hydra:description' => 'Replaces the dummy resource.',
×
234
                            'returns' => 'dummy',
×
235
                        ],
×
236
                        [
×
237
                            '@type' => ['hydra:Operation', 'schema:FindAction'],
×
238
                            'hydra:method' => 'GET',
×
239
                            'hydra:title' => 'getrelatedDummy',
×
240
                            'hydra:description' => 'Retrieves a relatedDummy resource.',
×
241
                            'returns' => 'relatedDummy',
×
242
                        ],
×
243
                    ],
×
244
                ],
×
245
                [
×
246
                    '@id' => '#Entrypoint',
×
247
                    '@type' => 'hydra:Class',
×
248
                    'hydra:title' => 'Entrypoint',
×
249
                    'hydra:supportedProperty' => [
×
250
                        [
×
251
                            '@type' => 'hydra:SupportedProperty',
×
252
                            'hydra:property' => [
×
253
                                '@id' => '#Entrypoint/dummy',
×
254
                                '@type' => 'hydra:Link',
×
255
                                'domain' => '#Entrypoint',
×
256
                                'range' => [
×
257
                                    ['@id' => 'hydra:Collection'],
×
258
                                    [
×
259
                                        'owl:equivalentClass' => [
×
260
                                            'owl:onProperty' => ['@id' => 'hydra:member'],
×
261
                                            'owl:allValuesFrom' => ['@id' => '#dummy'],
×
262
                                        ],
×
263
                                    ],
×
264
                                ],
×
265
                                'owl:maxCardinality' => 1,
×
266
                                'hydra:supportedOperation' => [
×
267
                                    [
×
268
                                        '@type' => ['hydra:Operation', 'schema:FindAction'],
×
269
                                        'hydra:method' => 'GET',
×
270
                                        'hydra:title' => 'getdummyCollection',
×
271
                                        'hydra:description' => 'Retrieves the collection of dummy resources.',
×
272
                                        'returns' => 'hydra:Collection',
×
273
                                    ],
×
274
                                    [
×
275
                                        '@type' => ['hydra:Operation', 'schema:CreateAction'],
×
276
                                        'expects' => 'dummy',
×
277
                                        'hydra:method' => 'POST',
×
278
                                        'hydra:title' => 'postdummy',
×
279
                                        'hydra:description' => 'Creates a dummy resource.',
×
280
                                        'returns' => 'dummy',
×
281
                                    ],
×
282
                                ],
×
283
                            ],
×
284
                            'hydra:title' => 'getdummyCollection',
×
285
                            'hydra:description' => 'The collection of dummy resources',
×
286
                            'hydra:readable' => true,
×
287
                            'hydra:writeable' => false,
×
288
                        ],
×
289
                    ],
×
290
                    'hydra:supportedOperation' => [
×
291
                        '@type' => 'hydra:Operation',
×
292
                        'hydra:method' => 'GET',
×
293
                        'hydra:title' => 'index',
×
294
                        'hydra:description' => 'The API Entrypoint.',
×
295
                        'hydra:returns' => 'Entrypoint',
×
296
                    ],
×
297
                ],
×
298
                [
×
299
                    '@id' => '#ConstraintViolationList',
×
300
                    '@type' => 'hydra:Class',
×
301
                    'hydra:title' => 'ConstraintViolationList',
×
302
                    'hydra:description' => 'A constraint violation List.',
×
303
                    'hydra:supportedProperty' => [
×
304
                        [
×
305
                            '@type' => 'hydra:SupportedProperty',
×
306
                            'hydra:property' => [
×
307
                                '@id' => '#ConstraintViolationList/propertyPath',
×
308
                                '@type' => 'rdf:Property',
×
309
                                'rdfs:label' => 'propertyPath',
×
310
                                'domain' => '#ConstraintViolationList',
×
311
                                'range' => 'xmls:string',
×
312
                            ],
×
313
                            'hydra:title' => 'propertyPath',
×
314
                            'hydra:description' => 'The property path of the violation',
×
315
                            'hydra:readable' => true,
×
316
                            'hydra:writeable' => false,
×
317
                        ],
×
318
                        [
×
319
                            '@type' => 'hydra:SupportedProperty',
×
320
                            'hydra:property' => [
×
321
                                '@id' => '#ConstraintViolationList/message',
×
322
                                '@type' => 'rdf:Property',
×
323
                                'rdfs:label' => 'message',
×
324
                                'domain' => '#ConstraintViolationList',
×
325
                                'range' => 'xmls:string',
×
326
                            ],
×
327
                            'hydra:title' => 'message',
×
328
                            'hydra:description' => 'The message associated with the violation',
×
329
                            'hydra:readable' => true,
×
330
                            'hydra:writeable' => false,
×
331
                        ],
×
332
                    ],
×
333
                ],
×
334
            ],
×
335
            'hydra:entrypoint' => '/',
×
336
        ];
×
337

338
        $this->assertEquals($expected, $documentationNormalizer->normalize($documentation));
×
339
        $this->assertTrue($documentationNormalizer->supportsNormalization($documentation, 'jsonld'));
×
340
        $this->assertFalse($documentationNormalizer->supportsNormalization($documentation, 'hal'));
×
341
        $this->assertEmpty($documentationNormalizer->getSupportedTypes('json'));
×
342
        $this->assertSame([Documentation::class => true], $documentationNormalizer->getSupportedTypes($documentationNormalizer::FORMAT));
×
343
    }
344

345
    public function testNormalizeInputOutputClass(): void
346
    {
347
        $title = 'Test Api';
×
348
        $desc = 'test ApiGerard';
×
349
        $version = '0.0.0';
×
350
        $documentation = new Documentation(new ResourceNameCollection(['dummy' => 'dummy']), $title, $desc, $version);
×
351

352
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
353
        $propertyNameCollectionFactoryProphecy->create('inputClass', Argument::type('array'))->shouldBeCalled()->willReturn(new PropertyNameCollection(['a', 'b']));
×
354
        $propertyNameCollectionFactoryProphecy->create('outputClass', Argument::type('array'))->shouldBeCalled()->willReturn(new PropertyNameCollection(['c', 'd']));
×
355
        $propertyNameCollectionFactoryProphecy->create('dummy', Argument::type('array'))->shouldBeCalled()->willReturn(new PropertyNameCollection([]));
×
356

357
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
358
        $resourceMetadataFactoryProphecy->create('dummy')->shouldBeCalled()->willReturn(new ResourceMetadataCollection('dummy', [
×
359
            (new ApiResource())->withShortName('dummy')->withDescription('dummy')->withTypes(['#dummy'])->withOperations(new Operations([
×
360
                'get' => (new Get())->withTypes(['#dummy'])->withShortName('dummy')->withInput(['class' => 'inputClass'])->withOutput(['class' => 'outputClass']),
×
361
                'put' => (new Put())->withShortName('dummy')->withInput(['class' => null])->withOutput(['class' => 'outputClass']),
×
362
                'get_collection' => (new GetCollection())->withShortName('dummy')->withInput(['class' => 'inputClass'])->withOutput(['class' => 'outputClass']),
×
363
                'post' => (new Post())->withShortName('dummy')->withOutput(['class' => null])->withInput(['class' => 'inputClass']),
×
364
            ])),
×
365
        ]));
×
366

367
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
368
        $propertyMetadataFactoryProphecy->create('inputClass', 'a', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('a')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true));
×
369
        $propertyMetadataFactoryProphecy->create('inputClass', 'b', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('b')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true));
×
370
        $propertyMetadataFactoryProphecy->create('outputClass', 'c', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('c')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true));
×
371
        $propertyMetadataFactoryProphecy->create('outputClass', 'd', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('d')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true));
×
372

373
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
374
        $resourceClassResolverProphecy->isResourceClass(Argument::type('string'))->willReturn(true);
×
375

376
        $urlGenerator = $this->prophesize(UrlGeneratorInterface::class);
×
377
        $urlGenerator->generate('api_entrypoint')->willReturn('/')->shouldBeCalledTimes(1);
×
378
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'])->willReturn('/doc')->shouldBeCalledTimes(1);
×
379
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'], 0)->willReturn('/doc')->shouldBeCalledTimes(1);
×
380

381
        $documentationNormalizer = new DocumentationNormalizer(
×
382
            $resourceMetadataFactoryProphecy->reveal(),
×
383
            $propertyNameCollectionFactoryProphecy->reveal(),
×
384
            $propertyMetadataFactoryProphecy->reveal(),
×
385
            $resourceClassResolverProphecy->reveal(),
×
386
            $urlGenerator->reveal()
×
387
        );
×
388

389
        $expected = [
×
390
            '@id' => '#dummy',
×
391
            '@type' => 'hydra:Class',
×
392
            'hydra:title' => 'dummy',
×
393
            'hydra:supportedProperty' => [
×
394
                [
×
395
                    '@type' => 'hydra:SupportedProperty',
×
396
                    'hydra:property' => [
×
397
                        '@id' => '#dummy/a',
×
398
                        '@type' => 'rdf:Property',
×
399
                        'label' => 'a',
×
400
                        'domain' => '#dummy',
×
401
                        'range' => 'xmls:string',
×
402
                    ],
×
403
                    'hydra:title' => 'a',
×
404
                    'hydra:required' => false,
×
405
                    'hydra:readable' => true,
×
406
                    'hydra:writeable' => true,
×
407
                    'hydra:description' => 'a',
×
408
                ],
×
409
                [
×
410
                    '@type' => 'hydra:SupportedProperty',
×
411
                    'hydra:property' => [
×
412
                        '@id' => '#dummy/b',
×
413
                        '@type' => 'rdf:Property',
×
414
                        'label' => 'b',
×
415
                        'domain' => '#dummy',
×
416
                        'range' => 'xmls:string',
×
417
                    ],
×
418
                    'hydra:title' => 'b',
×
419
                    'hydra:required' => false,
×
420
                    'hydra:readable' => true,
×
421
                    'hydra:writeable' => true,
×
422
                    'hydra:description' => 'b',
×
423
                ],
×
424
                [
×
425
                    '@type' => 'hydra:SupportedProperty',
×
426
                    'hydra:property' => [
×
427
                        '@id' => '#dummy/c',
×
428
                        '@type' => 'rdf:Property',
×
429
                        'label' => 'c',
×
430
                        'domain' => '#dummy',
×
431
                        'range' => 'xmls:string',
×
432
                    ],
×
433
                    'hydra:title' => 'c',
×
434
                    'hydra:required' => false,
×
435
                    'hydra:readable' => true,
×
436
                    'hydra:writeable' => true,
×
437
                    'hydra:description' => 'c',
×
438
                ],
×
439
                [
×
440
                    '@type' => 'hydra:SupportedProperty',
×
441
                    'hydra:property' => [
×
442
                        '@id' => '#dummy/d',
×
443
                        '@type' => 'rdf:Property',
×
444
                        'label' => 'd',
×
445
                        'domain' => '#dummy',
×
446
                        'range' => 'xmls:string',
×
447
                    ],
×
448
                    'hydra:title' => 'd',
×
449
                    'hydra:required' => false,
×
450
                    'hydra:readable' => true,
×
451
                    'hydra:writeable' => true,
×
452
                    'hydra:description' => 'd',
×
453
                ],
×
454
            ],
×
455
            'hydra:supportedOperation' => [
×
456
                [
×
457
                    '@type' => [
×
458
                        'hydra:Operation',
×
459
                        'schema:FindAction',
×
460
                    ],
×
461
                    'hydra:method' => 'GET',
×
462
                    'hydra:title' => 'getdummy',
×
463
                    'hydra:description' => 'Retrieves a dummy resource.',
×
464
                    'returns' => 'dummy',
×
465
                ],
×
466
                [
×
467
                    '@type' => [
×
468
                        'hydra:Operation',
×
469
                        'schema:ReplaceAction',
×
470
                    ],
×
471
                    'expects' => 'owl:Nothing',
×
472
                    'hydra:method' => 'PUT',
×
473
                    'hydra:title' => 'putdummy',
×
474
                    'hydra:description' => 'Replaces the dummy resource.',
×
475
                    'returns' => 'dummy',
×
476
                ],
×
477
            ],
×
478
            'hydra:description' => 'dummy',
×
479
        ];
×
480

481
        $doc = $documentationNormalizer->normalize($documentation);
×
482
        $this->assertEquals($expected, $doc['hydra:supportedClass'][0]);
×
483
    }
484

485
    public function testHasHydraContext(): void
486
    {
487
        $title = 'Test Api';
×
488
        $desc = 'test ApiGerard';
×
489
        $version = '0.0.0';
×
490
        $documentation = new Documentation(new ResourceNameCollection(['dummy' => 'dummy']), $title, $desc, $version);
×
491

492
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
493
        $propertyNameCollectionFactoryProphecy->create('dummy', Argument::type('array'))->shouldBeCalled()->willReturn(new PropertyNameCollection(['name']));
×
494

495
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
496
        $resourceMetadataFactoryProphecy->create('dummy')->shouldBeCalled()->willReturn(new ResourceMetadataCollection('dummy', [
×
497
            (new ApiResource())->withShortName('dummy')->withDescription('dummy')->withTypes(['#dummy'])->withOperations(new Operations([
×
498
                'get' => (new Get())->withTypes(['#dummy'])->withShortName('dummy')->withInput(['class' => 'inputClass'])->withOutput(['class' => 'outputClass']),
×
499
            ])),
×
500
        ]));
×
501

502
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
503
        $propertyMetadataFactoryProphecy->create('dummy', 'name', Argument::type('array'))->shouldBeCalled()->willReturn(
×
504
            (new ApiProperty())
×
505
                ->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])
×
506
                ->withDescription('b')
×
507
                ->withReadable(true)
×
508
                ->withWritable(true)
×
509
                ->withJsonldContext([
×
510
                    'hydra:property' => [
×
511
                        '@type' => 'https://schema.org/Enumeration',
×
512
                    ],
×
513
                ])
×
514
        );
×
515

516
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
517
        $resourceClassResolverProphecy->isResourceClass(Argument::type('string'))->willReturn(true);
×
518

519
        $urlGenerator = $this->prophesize(UrlGeneratorInterface::class);
×
520
        $urlGenerator->generate('api_entrypoint')->willReturn('/')->shouldBeCalledTimes(1);
×
521
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'])->willReturn('/doc')->shouldBeCalledTimes(1);
×
522
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'], 0)->willReturn('/doc')->shouldBeCalledTimes(1);
×
523

524
        $documentationNormalizer = new DocumentationNormalizer(
×
525
            $resourceMetadataFactoryProphecy->reveal(),
×
526
            $propertyNameCollectionFactoryProphecy->reveal(),
×
527
            $propertyMetadataFactoryProphecy->reveal(),
×
528
            $resourceClassResolverProphecy->reveal(),
×
529
            $urlGenerator->reveal()
×
530
        );
×
531

532
        $this->assertEquals([
×
533
            '@id' => '#dummy/name',
×
534
            '@type' => 'https://schema.org/Enumeration',
×
535
            'label' => 'name',
×
536
            'domain' => '#dummy',
×
537
            'range' => 'xmls:string',
×
538
        ], $documentationNormalizer->normalize($documentation)['hydra:supportedClass'][0]['hydra:supportedProperty'][0]['hydra:property']);
×
539
    }
540

541
    public function testNormalizeWithoutPrefix(): void
542
    {
543
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
544
        $resourceMetadataFactoryProphecy->create('dummy')->shouldBeCalled()->willReturn(new ResourceMetadataCollection('dummy', [
×
545
            (new ApiResource())->withShortName('dummy')->withDescription('dummy')->withTypes(['#dummy'])->withOperations(new Operations([
×
546
                'get' => (new Get())->withHydraContext(['foo' => 'bar', 'title' => 'foobar'])->withTypes(['#dummy'])->withShortName('dummy'),
×
547
                'put' => (new Put())->withShortName('dummy'),
×
548
                'get_collection' => (new GetCollection())->withShortName('dummy'),
×
549
                'post' => (new Post())->withShortName('dummy'),
×
550
            ])),
×
551
            (new ApiResource())->withShortName('relatedDummy')->withOperations(new Operations(['get' => (new Get())->withTypes(['#relatedDummy'])->withShortName('relatedDummy')])),
×
552
        ]));
×
553
        $resourceMetadataFactoryProphecy->create('relatedDummy')->shouldBeCalled()->willReturn(new ResourceMetadataCollection('relatedDummy', [
×
554
            (new ApiResource())->withShortName('relatedDummy')->withOperations(new Operations(['get' => (new Get())->withShortName('relatedDummy')])),
×
555
        ]));
×
556

557
        $title = 'Test Api';
×
558
        $desc = 'test ApiGerard';
×
559
        $version = '0.0.0';
×
560
        $documentation = new Documentation(new ResourceNameCollection(['dummy' => 'dummy']), $title, $desc, $version);
×
561

562
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
563
        $propertyNameCollectionFactoryProphecy->create('dummy', [])->shouldBeCalled()->willReturn(new PropertyNameCollection(['name', 'description', 'nameConverted', 'relatedDummy', 'iri']));
×
564

565
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
566
        $propertyMetadataFactoryProphecy->create('dummy', 'name', Argument::type('array'))->shouldBeCalled()->willReturn(
×
567
            (new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('name')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true)
×
568
        );
×
569
        $propertyMetadataFactoryProphecy->create('dummy', 'description', Argument::type('array'))->shouldBeCalled()->willReturn(
×
570
            (new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('description')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true)->withJsonldContext(['@type' => '@id'])
×
571
        );
×
572
        $propertyMetadataFactoryProphecy->create('dummy', 'nameConverted', Argument::type('array'))->shouldBeCalled()->willReturn(
×
573
            (new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_STRING)])->withDescription('name converted')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true)
×
574
        );
×
575
        $propertyMetadataFactoryProphecy->create('dummy', 'relatedDummy', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withBuiltinTypes([new Type(Type::BUILTIN_TYPE_OBJECT, false, 'dummy', true, null, new Type(Type::BUILTIN_TYPE_OBJECT, false, 'relatedDummy'))])->withDescription('This is a name.')->withReadable(true)->withWritable(true)->withReadableLink(true)->withWritableLink(true));
×
576
        $propertyMetadataFactoryProphecy->create('dummy', 'iri', Argument::type('array'))->shouldBeCalled()->willReturn((new ApiProperty())->withIris(['https://schema.org/Dummy']));
×
577

578
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
579
        $resourceClassResolverProphecy->isResourceClass(Argument::type('string'))->willReturn(true);
×
580

581
        $urlGenerator = $this->prophesize(UrlGeneratorInterface::class);
×
582
        $urlGenerator->generate('api_entrypoint')->willReturn('/')->shouldBeCalledTimes(1);
×
583
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'])->willReturn('/doc')->shouldBeCalledTimes(1);
×
584

585
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'], 0)->willReturn('/doc')->shouldBeCalledTimes(1);
×
586

587
        $documentationNormalizer = new DocumentationNormalizer(
×
588
            $resourceMetadataFactoryProphecy->reveal(),
×
589
            $propertyNameCollectionFactoryProphecy->reveal(),
×
590
            $propertyMetadataFactoryProphecy->reveal(),
×
591
            $resourceClassResolverProphecy->reveal(),
×
592
            $urlGenerator->reveal(),
×
593
            new CustomConverter()
×
594
        );
×
595

596
        $expected = [
×
597
            '@context' => [
×
598
                HYDRA_CONTEXT,
×
599
                [
×
600
                    '@vocab' => '/doc#',
×
601
                    'hydra' => 'http://www.w3.org/ns/hydra/core#',
×
602
                    'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
×
603
                    'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
×
604
                    'xmls' => 'http://www.w3.org/2001/XMLSchema#',
×
605
                    'owl' => 'http://www.w3.org/2002/07/owl#',
×
606
                    'schema' => 'https://schema.org/',
×
607
                    'domain' => [
×
608
                        '@id' => 'rdfs:domain',
×
609
                        '@type' => '@id',
×
610
                    ],
×
611
                    'range' => [
×
612
                        '@id' => 'rdfs:range',
×
613
                        '@type' => '@id',
×
614
                    ],
×
615
                    'subClassOf' => [
×
616
                        '@id' => 'rdfs:subClassOf',
×
617
                        '@type' => '@id',
×
618
                    ],
×
619
                ],
×
620
            ],
×
621
            '@id' => '/doc',
×
622
            '@type' => 'ApiDocumentation',
×
623
            'title' => 'Test Api',
×
624
            'description' => 'test ApiGerard',
×
625
            'supportedClass' => [
×
626
                [
×
627
                    '@id' => '#dummy',
×
628
                    '@type' => 'Class',
×
629
                    'title' => 'dummy',
×
630
                    'description' => 'dummy',
×
631
                    'supportedProperty' => [
×
632
                        [
×
633
                            '@type' => 'SupportedProperty',
×
634
                            'property' => [
×
635
                                '@id' => '#dummy/name',
×
636
                                '@type' => 'rdf:Property',
×
637
                                'label' => 'name',
×
638
                                'domain' => '#dummy',
×
639
                                'range' => 'xmls:string',
×
640
                            ],
×
641
                            'title' => 'name',
×
642
                            'required' => false,
×
643
                            'readable' => true,
×
644
                            'writeable' => true,
×
645
                            'description' => 'name',
×
646
                        ],
×
647
                        [
×
648
                            '@type' => 'SupportedProperty',
×
649
                            'property' => [
×
650
                                '@id' => '#dummy/description',
×
651
                                '@type' => 'rdf:Property',
×
652
                                'label' => 'description',
×
653
                                'domain' => '#dummy',
×
654
                                'range' => '@id',
×
655
                            ],
×
656
                            'title' => 'description',
×
657
                            'required' => false,
×
658
                            'readable' => true,
×
659
                            'writeable' => true,
×
660
                            'description' => 'description',
×
661
                        ],
×
662
                        [
×
663
                            '@type' => 'SupportedProperty',
×
664
                            'property' => [
×
665
                                '@id' => '#dummy/name_converted',
×
666
                                '@type' => 'rdf:Property',
×
667
                                'label' => 'name_converted',
×
668
                                'domain' => '#dummy',
×
669
                                'range' => 'xmls:string',
×
670
                            ],
×
671
                            'title' => 'name_converted',
×
672
                            'required' => false,
×
673
                            'readable' => true,
×
674
                            'writeable' => true,
×
675
                            'description' => 'name converted',
×
676
                        ],
×
677
                        [
×
678
                            '@type' => 'SupportedProperty',
×
679
                            'property' => [
×
680
                                '@id' => '#dummy/relatedDummy',
×
681
                                '@type' => 'rdf:Property',
×
682
                                'label' => 'relatedDummy',
×
683
                                'domain' => '#dummy',
×
684
                                'range' => '#relatedDummy',
×
685
                            ],
×
686
                            'title' => 'relatedDummy',
×
687
                            'required' => false,
×
688
                            'readable' => true,
×
689
                            'writeable' => true,
×
690
                            'description' => 'This is a name.',
×
691
                        ],
×
692
                        [
×
693
                            '@type' => 'SupportedProperty',
×
694
                            'property' => [
×
695
                                '@id' => 'https://schema.org/Dummy',
×
696
                                '@type' => 'rdf:Property',
×
697
                                'label' => 'iri',
×
698
                                'domain' => '#dummy',
×
699
                            ],
×
700
                            'title' => 'iri',
×
701
                            'required' => null,
×
702
                            'readable' => null,
×
703
                            'writeable' => false,
×
704
                        ],
×
705
                    ],
×
706
                    'supportedOperation' => [
×
707
                        [
×
708
                            '@type' => ['Operation', 'schema:FindAction'],
×
709
                            'method' => 'GET',
×
710
                            'title' => 'foobar',
×
711
                            'returns' => 'dummy',
×
712
                            'foo' => 'bar',
×
713
                            'description' => 'Retrieves a dummy resource.',
×
714
                        ],
×
715
                        [
×
716
                            '@type' => ['Operation', 'schema:ReplaceAction'],
×
717
                            'expects' => 'dummy',
×
718
                            'method' => 'PUT',
×
719
                            'title' => 'putdummy',
×
720
                            'description' => 'Replaces the dummy resource.',
×
721
                            'returns' => 'dummy',
×
722
                        ],
×
723
                        [
×
724
                            '@type' => ['Operation', 'schema:FindAction'],
×
725
                            'method' => 'GET',
×
726
                            'title' => 'getrelatedDummy',
×
727
                            'description' => 'Retrieves a relatedDummy resource.',
×
728
                            'returns' => 'relatedDummy',
×
729
                        ],
×
730
                    ],
×
731
                ],
×
732
                [
×
733
                    '@id' => '#Entrypoint',
×
734
                    '@type' => 'Class',
×
735
                    'title' => 'Entrypoint',
×
736
                    'supportedProperty' => [
×
737
                        [
×
738
                            '@type' => 'SupportedProperty',
×
739
                            'property' => [
×
740
                                '@id' => '#Entrypoint/dummy',
×
741
                                '@type' => 'Link',
×
742
                                'domain' => '#Entrypoint',
×
743
                                'range' => [
×
744
                                    ['@id' => 'Collection'],
×
745
                                    [
×
746
                                        'owl:equivalentClass' => [
×
747
                                            'owl:onProperty' => ['@id' => 'member'],
×
748
                                            'owl:allValuesFrom' => ['@id' => '#dummy'],
×
749
                                        ],
×
750
                                    ],
×
751
                                ],
×
752
                                'owl:maxCardinality' => 1,
×
753
                                'supportedOperation' => [
×
754
                                    [
×
755
                                        '@type' => ['Operation', 'schema:FindAction'],
×
756
                                        'method' => 'GET',
×
757
                                        'title' => 'getdummyCollection',
×
758
                                        'description' => 'Retrieves the collection of dummy resources.',
×
759
                                        'returns' => 'Collection',
×
760
                                    ],
×
761
                                    [
×
762
                                        '@type' => ['Operation', 'schema:CreateAction'],
×
763
                                        'expects' => 'dummy',
×
764
                                        'method' => 'POST',
×
765
                                        'title' => 'postdummy',
×
766
                                        'description' => 'Creates a dummy resource.',
×
767
                                        'returns' => 'dummy',
×
768
                                    ],
×
769
                                ],
×
770
                            ],
×
771
                            'title' => 'getdummyCollection',
×
772
                            'description' => 'The collection of dummy resources',
×
773
                            'readable' => true,
×
774
                            'writeable' => false,
×
775
                        ],
×
776
                    ],
×
777
                    'supportedOperation' => [
×
778
                        '@type' => 'Operation',
×
779
                        'method' => 'GET',
×
780
                        'title' => 'index',
×
781
                        'description' => 'The API Entrypoint.',
×
782
                        'returns' => 'Entrypoint',
×
783
                    ],
×
784
                ],
×
785
                [
×
786
                    '@id' => '#ConstraintViolationList',
×
787
                    '@type' => 'Class',
×
788
                    'title' => 'ConstraintViolationList',
×
789
                    'description' => 'A constraint violation List.',
×
790
                    'supportedProperty' => [
×
791
                        [
×
792
                            '@type' => 'SupportedProperty',
×
793
                            'property' => [
×
794
                                '@id' => '#ConstraintViolationList/propertyPath',
×
795
                                '@type' => 'rdf:Property',
×
796
                                'rdfs:label' => 'propertyPath',
×
797
                                'domain' => '#ConstraintViolationList',
×
798
                                'range' => 'xmls:string',
×
799
                            ],
×
800
                            'title' => 'propertyPath',
×
801
                            'description' => 'The property path of the violation',
×
802
                            'readable' => true,
×
803
                            'writeable' => false,
×
804
                        ],
×
805
                        [
×
806
                            '@type' => 'SupportedProperty',
×
807
                            'property' => [
×
808
                                '@id' => '#ConstraintViolationList/message',
×
809
                                '@type' => 'rdf:Property',
×
810
                                'rdfs:label' => 'message',
×
811
                                'domain' => '#ConstraintViolationList',
×
812
                                'range' => 'xmls:string',
×
813
                            ],
×
814
                            'title' => 'message',
×
815
                            'description' => 'The message associated with the violation',
×
816
                            'readable' => true,
×
817
                            'writeable' => false,
×
818
                        ],
×
819
                    ],
×
820
                ],
×
821
            ],
×
822
            'entrypoint' => '/',
×
823
        ];
×
824

825
        $this->assertEquals($expected, $documentationNormalizer->normalize($documentation, null, [ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX => false]));
×
826
    }
827

828
    public function testNormalizeNoEntrypointAndHideHydraOperation(): void
829
    {
NEW
830
        $title = 'Test Api';
×
NEW
831
        $desc = 'test ApiGerard';
×
NEW
832
        $version = '0.0.0';
×
NEW
833
        $documentation = new Documentation(new ResourceNameCollection(['dummy' => 'dummy']), $title, $desc, $version);
×
834

NEW
835
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
NEW
836
        $resourceMetadataFactoryProphecy->create('dummy')->willReturn(new ResourceMetadataCollection('dummy', [
×
NEW
837
            (new ApiResource())->withHideHydraOperation(true)->withOperations(new Operations([
×
NEW
838
                'get' => new Get(),
×
NEW
839
            ])),
×
NEW
840
        ]));
×
NEW
841
        $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
×
NEW
842
        $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
×
NEW
843
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
NEW
844
        $urlGenerator = $this->prophesize(UrlGeneratorInterface::class);
×
NEW
845
        $urlGenerator->generate('api_doc', ['_format' => 'jsonld'], Argument::any())->willReturn('/doc');
×
846

NEW
847
        $documentationNormalizer = new DocumentationNormalizer(
×
NEW
848
            $resourceMetadataFactoryProphecy->reveal(),
×
NEW
849
            $propertyNameCollectionFactoryProphecy->reveal(),
×
NEW
850
            $propertyMetadataFactoryProphecy->reveal(),
×
NEW
851
            $resourceClassResolverProphecy->reveal(),
×
NEW
852
            $urlGenerator->reveal(),
×
NEW
853
            new CustomConverter(),
×
NEW
854
            [],
×
NEW
855
            false,
×
NEW
856
        );
×
857

NEW
858
        $expected = [
×
NEW
859
            '@context' => [
×
NEW
860
                HYDRA_CONTEXT,
×
NEW
861
                [
×
NEW
862
                    '@vocab' => '/doc#',
×
NEW
863
                    'hydra' => 'http://www.w3.org/ns/hydra/core#',
×
NEW
864
                    'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
×
NEW
865
                    'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
×
NEW
866
                    'xmls' => 'http://www.w3.org/2001/XMLSchema#',
×
NEW
867
                    'owl' => 'http://www.w3.org/2002/07/owl#',
×
NEW
868
                    'schema' => 'https://schema.org/',
×
NEW
869
                    'domain' => [
×
NEW
870
                        '@id' => 'rdfs:domain',
×
NEW
871
                        '@type' => '@id',
×
NEW
872
                    ],
×
NEW
873
                    'range' => [
×
NEW
874
                        '@id' => 'rdfs:range',
×
NEW
875
                        '@type' => '@id',
×
NEW
876
                    ],
×
NEW
877
                    'subClassOf' => [
×
NEW
878
                        '@id' => 'rdfs:subClassOf',
×
NEW
879
                        '@type' => '@id',
×
NEW
880
                    ],
×
NEW
881
                ],
×
NEW
882
            ],
×
NEW
883
            '@id' => '/doc',
×
NEW
884
            '@type' => 'ApiDocumentation',
×
NEW
885
            'title' => 'Test Api',
×
NEW
886
            'description' => 'test ApiGerard',
×
NEW
887
            'supportedClass' => [
×
NEW
888
                [
×
NEW
889
                    '@id' => '#ConstraintViolationList',
×
NEW
890
                    '@type' => 'Class',
×
NEW
891
                    'title' => 'ConstraintViolationList',
×
NEW
892
                    'description' => 'A constraint violation List.',
×
NEW
893
                    'supportedProperty' => [
×
NEW
894
                        [
×
NEW
895
                            '@type' => 'SupportedProperty',
×
NEW
896
                            'property' => [
×
NEW
897
                                '@id' => '#ConstraintViolationList/propertyPath',
×
NEW
898
                                '@type' => 'rdf:Property',
×
NEW
899
                                'rdfs:label' => 'propertyPath',
×
NEW
900
                                'domain' => '#ConstraintViolationList',
×
NEW
901
                                'range' => 'xmls:string',
×
NEW
902
                            ],
×
NEW
903
                            'title' => 'propertyPath',
×
NEW
904
                            'description' => 'The property path of the violation',
×
NEW
905
                            'readable' => true,
×
NEW
906
                            'writeable' => false,
×
NEW
907
                        ],
×
NEW
908
                        [
×
NEW
909
                            '@type' => 'SupportedProperty',
×
NEW
910
                            'property' => [
×
NEW
911
                                '@id' => '#ConstraintViolationList/message',
×
NEW
912
                                '@type' => 'rdf:Property',
×
NEW
913
                                'rdfs:label' => 'message',
×
NEW
914
                                'domain' => '#ConstraintViolationList',
×
NEW
915
                                'range' => 'xmls:string',
×
NEW
916
                            ],
×
NEW
917
                            'title' => 'message',
×
NEW
918
                            'description' => 'The message associated with the violation',
×
NEW
919
                            'readable' => true,
×
NEW
920
                            'writeable' => false,
×
NEW
921
                        ],
×
NEW
922
                    ],
×
NEW
923
                ],
×
NEW
924
            ],
×
NEW
925
        ];
×
926

NEW
927
        $this->assertEquals($expected, $documentationNormalizer->normalize($documentation, null, [ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX => false]));
×
928
    }
929
}
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