Skip to content

Commit 75ffdc4

Browse files
fix(hydra): hide search key when there is parameter without filter (#7773)
* fix(hydra): hide search key when there is parameter without filter * Update tests
1 parent 0f025e8 commit 75ffdc4

3 files changed

Lines changed: 111 additions & 11 deletions

File tree

src/Hydra/Serializer/CollectionFiltersNormalizer.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,15 @@ public function normalize(mixed $object, ?string $format = null, array $context
110110
if ($currentFilters || ($parameters && \count($parameters))) {
111111
$hydraPrefix = $this->getHydraPrefix($context + $this->defaultContext);
112112
['mapping' => $mapping, 'keys' => $keys] = $this->getSearchMappingAndKeys($operation, $resourceClass, $currentFilters, $parameters, [$this, 'getFilter']);
113-
$data[$hydraPrefix.'search'] = [
114-
'@type' => $hydraPrefix.'IriTemplate',
115-
$hydraPrefix.'template' => \sprintf('%s{?%s}', $requestParts['path'], implode(',', $keys)),
116-
$hydraPrefix.'variableRepresentation' => 'BasicRepresentation',
117-
$hydraPrefix.'mapping' => $this->convertMappingToArray($mapping),
118-
];
113+
114+
if ($keys || $mapping) {
115+
$data[$hydraPrefix.'search'] = [
116+
'@type' => $hydraPrefix.'IriTemplate',
117+
$hydraPrefix.'template' => \sprintf('%s{?%s}', $requestParts['path'], implode(',', $keys)),
118+
$hydraPrefix.'variableRepresentation' => 'BasicRepresentation',
119+
$hydraPrefix.'mapping' => $this->convertMappingToArray($mapping),
120+
];
121+
}
119122
}
120123

121124
return $data;

src/Hydra/Tests/Serializer/CollectionFiltersNormalizerTest.php

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use ApiPlatform\Metadata\Exception\InvalidArgumentException;
2424
use ApiPlatform\Metadata\GetCollection;
2525
use ApiPlatform\Metadata\Operations;
26+
use ApiPlatform\Metadata\QueryParameter;
2627
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2728
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2829
use ApiPlatform\Metadata\ResourceClassResolverInterface;
@@ -323,6 +324,106 @@ public function testNormalize(): void
323324
]));
324325
}
325326

327+
public function testNormalizeParametersWithFilter(): void
328+
{
329+
$dummy = new Dummy();
330+
331+
$decoratedProphecy = $this->prophesize(NormalizerInterface::class);
332+
$decoratedProphecy->normalize($dummy, CollectionNormalizer::FORMAT, [
333+
'request_uri' => '/foo?bar=baz',
334+
'resource_class' => Dummy::class,
335+
'operation_name' => 'get',
336+
])->willReturn(['name' => 'foo']);
337+
338+
$filterProphecy = $this->prophesize(FilterInterface::class);
339+
$filterProphecy->getDescription(Dummy::class)->willReturn(['a' => ['property' => 'name', 'required' => true]])->shouldBeCalled();
340+
341+
$filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
342+
$filterLocatorProphecy->has('foo')->willReturn(true)->shouldBeCalled();
343+
$filterLocatorProphecy->get('foo')->willReturn($filterProphecy->reveal())->shouldBeCalled();
344+
345+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
346+
$resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [
347+
(new ApiResource(Dummy::class))
348+
->withShortName('Dummy')
349+
->withOperations(new Operations([
350+
'get' => (new GetCollection())->withShortName('Dummy')->withParameters([new QueryParameter(filter: 'foo')])->withFilters([]),
351+
])),
352+
]));
353+
354+
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
355+
$resourceClassResolverProphecy->getResourceClass($dummy, Dummy::class)->willReturn(Dummy::class);
356+
357+
$normalizer = new CollectionFiltersNormalizer(
358+
$decoratedProphecy->reveal(),
359+
$resourceMetadataFactoryProphecy->reveal(),
360+
$resourceClassResolverProphecy->reveal(),
361+
$filterLocatorProphecy->reveal(),
362+
);
363+
364+
$this->assertEquals([
365+
'name' => 'foo',
366+
'hydra:search' => [
367+
'@type' => 'hydra:IriTemplate',
368+
'hydra:template' => '/foo{?a}',
369+
'hydra:variableRepresentation' => 'BasicRepresentation',
370+
'hydra:mapping' => [
371+
[
372+
'@type' => 'IriTemplateMapping',
373+
'variable' => 'a',
374+
'property' => 'name',
375+
'required' => true,
376+
],
377+
],
378+
],
379+
], $normalizer->normalize($dummy, CollectionNormalizer::FORMAT, [
380+
'request_uri' => '/foo?bar=baz',
381+
'resource_class' => Dummy::class,
382+
'operation_name' => 'get',
383+
]));
384+
}
385+
386+
public function testNormalizeParametersWithoutFilter(): void
387+
{
388+
$dummy = new Dummy();
389+
390+
$decoratedProphecy = $this->prophesize(NormalizerInterface::class);
391+
$decoratedProphecy->normalize($dummy, CollectionNormalizer::FORMAT, [
392+
'request_uri' => '/foo?bar=baz',
393+
'resource_class' => Dummy::class,
394+
'operation_name' => 'get',
395+
])->willReturn(['name' => 'foo']);
396+
397+
$filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
398+
399+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
400+
$resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [
401+
(new ApiResource(Dummy::class))
402+
->withShortName('Dummy')
403+
->withOperations(new Operations([
404+
'get' => (new GetCollection())->withShortName('Dummy')->withParameters([new QueryParameter(hydra: false)])->withFilters([]),
405+
])),
406+
]));
407+
408+
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
409+
$resourceClassResolverProphecy->getResourceClass($dummy, Dummy::class)->willReturn(Dummy::class);
410+
411+
$normalizer = new CollectionFiltersNormalizer(
412+
$decoratedProphecy->reveal(),
413+
$resourceMetadataFactoryProphecy->reveal(),
414+
$resourceClassResolverProphecy->reveal(),
415+
$filterLocatorProphecy->reveal(),
416+
);
417+
418+
$this->assertEquals([
419+
'name' => 'foo',
420+
], $normalizer->normalize($dummy, CollectionNormalizer::FORMAT, [
421+
'request_uri' => '/foo?bar=baz',
422+
'resource_class' => Dummy::class,
423+
'operation_name' => 'get',
424+
]));
425+
}
426+
326427
public function testGetSupportedTypes(): void
327428
{
328429
if (!method_exists(Serializer::class, 'getSupportedTypes')) {

tests/Functional/Parameters/HydraTest.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ public function testHydraTemplate(): void
4545
public function testNoPropertyDescription(): void
4646
{
4747
$response = self::createClient()->request('GET', 'with_parameters_filter_without_property.jsonld');
48-
$this->assertArraySubset(['hydra:search' => [
49-
'hydra:template' => '/with_parameters_filter_without_property.jsonld{?}',
50-
'hydra:mapping' => [
51-
],
52-
]], $response->toArray());
48+
static::assertResponseStatusCodeSame(200);
5349
}
5450
}

0 commit comments

Comments
 (0)