@@ -151,4 +151,80 @@ public function testSubmitEmptyMultipleData(): void
151151 $ this ->assertTrue ($ form ->isSynchronized ());
152152 $ this ->assertEquals (new ArrayCollection (), $ form ->getData ());
153153 }
154+
155+ public function testCustomChoiceLabelIsPreserved (): void
156+ {
157+ $ project = (new Project ())->setId (123 )->setName ('Foo ' );
158+
159+ $ this ->entityManager
160+ ->method ('contains ' )
161+ ->with ($ project )
162+ ->willReturn (true );
163+ $ this ->repository
164+ ->method ('findBy ' )
165+ ->willReturn ([$ project ]);
166+ $ this ->classMetadata
167+ ->method ('getIdentifierValues ' )
168+ ->with ($ project )
169+ ->willReturn (['id ' => $ project ->getId ()]);
170+
171+ $ form = $ this ->factory ->create (CrudAutocompleteType::class, null , [
172+ 'class ' => Project::class,
173+ 'choice_label ' => static fn (Project $ p ): string => sprintf ('[%d] %s ' , $ p ->getId (),
174+ $ p ->getName ()),
175+ ]);
176+ $ form ->submit (['autocomplete ' => '123 ' ]);
177+
178+ $ this ->assertTrue ($ form ->isSynchronized ());
179+
180+ $ view = $ form ->createView ();
181+
182+ // the user-supplied callable is used to build the option label,
183+ // overriding the default Project::__toString() output
184+ $ this ->assertEquals (
185+ ['123 ' => new ChoiceView ($ project , 123 , '[123] Foo ' )],
186+ $ view ->children ['autocomplete ' ]->vars ['choices ' ],
187+ );
188+ }
189+
190+ public function testAutocompleteCallbackStillWinsWhenChoiceLabelIsNotSet (): void
191+ {
192+ $ project = (new Project ())->setId (123 )->setName ('Foo ' );
193+
194+ $ this ->entityManager
195+ ->method ('contains ' )
196+ ->with ($ project )
197+ ->willReturn (true );
198+ $ this ->repository
199+ ->method ('findBy ' )
200+ ->willReturn ([$ project ]);
201+ $ this ->classMetadata
202+ ->method ('getIdentifierValues ' )
203+ ->with ($ project )
204+ ->willReturn (['id ' => $ project ->getId ()]);
205+
206+ $ form = $ this ->factory ->create (CrudAutocompleteType::class, null , [
207+ 'class ' => Project::class,
208+ 'autocomplete_callback ' => static fn (Project $ p ): string => 'cb: ' .$ p ->getName (),
209+ ]);
210+ $ form ->submit (['autocomplete ' => '123 ' ]);
211+
212+ $ view = $ form ->createView ();
213+
214+ $ this ->assertEquals (
215+ ['123 ' => new ChoiceView ($ project , 123 , 'cb:Foo ' )],
216+ $ view ->children ['autocomplete ' ]->vars ['choices ' ],
217+ );
218+ }
219+
220+ public function testChoiceLabelOptionRejectsInvalidType (): void
221+ {
222+
223+ $ this ->expectException (\Symfony \Component \OptionsResolver \Exception \InvalidOptionsException::class);
224+
225+ $ this ->factory ->create (CrudAutocompleteType::class, null , [
226+ 'class ' => Project::class,
227+ 'choice_label ' => 42 , // int is not in the allowed types
228+ ]);
229+ }
154230}
0 commit comments