@@ -136,6 +136,49 @@ public function testQueryParameterWithPropertyPlaceholder(): void
136136 $ this ->assertSame ('static_param ' , $ staticParam ->getKey ());
137137 }
138138
139+ public function testQueryParameterWithNestedPropertyPlaceholder (): void
140+ {
141+ $ nameCollection = $ this ->createStub (PropertyNameCollectionFactoryInterface::class);
142+ $ nameCollection ->method ('create ' )->willReturn (new PropertyNameCollection (['id ' , 'name ' , 'related ' ]));
143+
144+ $ propertyMetadata = $ this ->createStub (PropertyMetadataFactoryInterface::class);
145+ $ propertyMetadata ->method ('create ' )->willReturn (
146+ new ApiProperty (readable: true ),
147+ );
148+
149+ $ filterLocator = $ this ->createStub (ContainerInterface::class);
150+ $ filterLocator ->method ('has ' )->willReturn (false );
151+
152+ $ parameterFactory = new ParameterResourceMetadataCollectionFactory (
153+ $ nameCollection ,
154+ $ propertyMetadata ,
155+ new AttributesResourceMetadataCollectionFactory (),
156+ $ filterLocator
157+ );
158+
159+ $ resourceMetadataCollection = $ parameterFactory ->create (HasNestedParameterAttribute::class);
160+ $ operation = $ resourceMetadataCollection ->getOperation (forceCollection: true );
161+ $ parameters = $ operation ->getParameters ();
162+
163+ $ this ->assertInstanceOf (Parameters::class, $ parameters );
164+
165+ $ this ->assertFalse ($ parameters ->has ('search[:property] ' ));
166+ $ this ->assertTrue ($ parameters ->has ('search[name] ' ));
167+ $ this ->assertTrue ($ parameters ->has ('search[related.nested] ' ));
168+
169+ $ searchNameParam = $ parameters ->get ('search[name] ' );
170+ $ this ->assertInstanceOf (QueryParameter::class, $ searchNameParam );
171+ $ this ->assertNull ($ searchNameParam ->getDescription ());
172+ $ this ->assertSame ('name ' , $ searchNameParam ->getProperty ());
173+ $ this ->assertSame ('search[name] ' , $ searchNameParam ->getKey ());
174+
175+ $ searchRelatedNestedParam = $ parameters ->get ('search[related.nested] ' );
176+ $ this ->assertInstanceOf (QueryParameter::class, $ searchRelatedNestedParam );
177+ $ this ->assertNull ($ searchRelatedNestedParam ->getDescription ());
178+ $ this ->assertSame ('related.nested ' , $ searchRelatedNestedParam ->getProperty ());
179+ $ this ->assertSame ('search[related.nested] ' , $ searchRelatedNestedParam ->getKey ());
180+ }
181+
139182 public function testParameterFactoryNoFilter (): void
140183 {
141184 $ nameCollection = $ this ->createStub (PropertyNameCollectionFactoryInterface::class);
@@ -220,3 +263,21 @@ class HasParameterAttribute
220263 public $ name ;
221264 public $ description ;
222265}
266+
267+ #[ApiResource(
268+ operations: [
269+ new GetCollection (
270+ parameters: [
271+ 'search[:property] ' => new QueryParameter (
272+ properties: ['name ' , 'related.nested ' ]
273+ ),
274+ ]
275+ ),
276+ ]
277+ )]
278+ class HasNestedParameterAttribute
279+ {
280+ public $ id ;
281+ public $ name ;
282+ public $ related ;
283+ }
0 commit comments