@@ -95,6 +95,151 @@ public function testProcessBypassesWithoutMapAttribute(): void
9595 $ processor = new ObjectMapperProcessor ($ objectMapper , $ decorated );
9696 $ this ->assertEquals ($ data , $ processor ->process ($ data , $ operation ));
9797 }
98+
99+ public function testProcessWithNoCustomInputAndNoCustomOutput (): void
100+ {
101+ $ this ->skipIfMapParameterNotAvailable ();
102+
103+ $ entity = new DummyEntity ();
104+ $ persisted = new DummyEntity ();
105+ $ operation = new Post (class: DummyEntity::class, map: true , write: true );
106+
107+ $ objectMapper = $ this ->createMock (ObjectMapperInterface::class);
108+ $ objectMapper ->expects ($ this ->never ())->method ('map ' );
109+
110+ $ decorated = $ this ->createMock (ProcessorInterface::class);
111+ $ decorated ->expects ($ this ->once ())
112+ ->method ('process ' )
113+ ->with ($ entity , $ operation , [], [])
114+ ->willReturn ($ persisted );
115+
116+ $ processor = new ObjectMapperProcessor ($ objectMapper , $ decorated );
117+ $ result = $ processor ->process ($ entity , $ operation );
118+
119+ $ this ->assertSame ($ persisted , $ result );
120+ }
121+
122+ public function testProcessWithNoCustomInputAndCustomOutput (): void
123+ {
124+ $ this ->skipIfMapParameterNotAvailable ();
125+
126+ $ entity = new DummyEntity ();
127+ $ persisted = new DummyEntity ();
128+ $ output = new DummyOutput ();
129+ $ operation = new Post (
130+ class: DummyEntity::class,
131+ output: ['class ' => DummyOutput::class],
132+ map: true ,
133+ write: true
134+ );
135+
136+ $ objectMapper = $ this ->createMock (ObjectMapperInterface::class);
137+ $ objectMapper ->expects ($ this ->once ())
138+ ->method ('map ' )
139+ ->with ($ persisted , DummyOutput::class)
140+ ->willReturn ($ output );
141+
142+ $ decorated = $ this ->createMock (ProcessorInterface::class);
143+ $ decorated ->expects ($ this ->once ())
144+ ->method ('process ' )
145+ ->with ($ entity , $ operation , [], [])
146+ ->willReturn ($ persisted );
147+
148+ $ processor = new ObjectMapperProcessor ($ objectMapper , $ decorated );
149+ $ result = $ processor ->process ($ entity , $ operation );
150+
151+ $ this ->assertSame ($ output , $ result );
152+ }
153+
154+ public function testProcessWithCustomInputAndNoCustomOutput (): void
155+ {
156+ $ this ->skipIfMapParameterNotAvailable ();
157+
158+ $ input = new DummyInput ();
159+ $ entity = new DummyEntity ();
160+ $ persisted = new DummyEntity ();
161+ $ operation = new Post (
162+ class: DummyEntity::class,
163+ input: ['class ' => DummyInput::class],
164+ map: true ,
165+ write: true
166+ );
167+
168+ $ objectMapper = $ this ->createMock (ObjectMapperInterface::class);
169+ $ objectMapper ->expects ($ this ->once ())
170+ ->method ('map ' )
171+ ->with ($ input , null )
172+ ->willReturn ($ entity );
173+
174+ $ decorated = $ this ->createMock (ProcessorInterface::class);
175+ $ decorated ->expects ($ this ->once ())
176+ ->method ('process ' )
177+ ->with ($ entity , $ operation , [], [])
178+ ->willReturn ($ persisted );
179+
180+ $ processor = new ObjectMapperProcessor ($ objectMapper , $ decorated );
181+ $ result = $ processor ->process ($ input , $ operation );
182+
183+ $ this ->assertSame ($ persisted , $ result );
184+ }
185+
186+ public function testProcessWithCustomInputAndCustomOutput (): void
187+ {
188+ $ this ->skipIfMapParameterNotAvailable ();
189+
190+ $ input = new DummyInput ();
191+ $ entity = new DummyEntity ();
192+ $ persisted = new DummyEntity ();
193+ $ output = new DummyOutput ();
194+ $ operation = new Post (
195+ class: DummyEntity::class,
196+ input: ['class ' => DummyInput::class],
197+ output: ['class ' => DummyOutput::class],
198+ map: true ,
199+ write: true
200+ );
201+
202+ $ objectMapper = $ this ->createMock (ObjectMapperInterface::class);
203+ $ objectMapper ->expects ($ this ->exactly (2 ))
204+ ->method ('map ' )
205+ ->willReturnCallback (function ($ data , $ target ) use ($ input , $ entity , $ persisted , $ output ) {
206+ if ($ data === $ input && null === $ target ) {
207+ return $ entity ;
208+ }
209+ if ($ data === $ persisted && DummyOutput::class === $ target ) {
210+ return $ output ;
211+ }
212+ throw new \Exception ('Unexpected map call ' );
213+ });
214+
215+ $ decorated = $ this ->createMock (ProcessorInterface::class);
216+ $ decorated ->expects ($ this ->once ())
217+ ->method ('process ' )
218+ ->with ($ entity , $ operation , [], [])
219+ ->willReturn ($ persisted );
220+
221+ $ processor = new ObjectMapperProcessor ($ objectMapper , $ decorated );
222+ $ result = $ processor ->process ($ input , $ operation );
223+
224+ $ this ->assertSame ($ output , $ result );
225+ }
226+
227+ private function skipIfMapParameterNotAvailable (): void
228+ {
229+ try {
230+ $ reflection = new \ReflectionClass (Post::class);
231+ $ constructor = $ reflection ->getConstructor ();
232+ $ parameters = $ constructor ->getParameters ();
233+ foreach ($ parameters as $ parameter ) {
234+ if ('map ' === $ parameter ->getName ()) {
235+ return ;
236+ }
237+ }
238+ $ this ->markTestSkipped ('The "map" parameter is not available in this version ' );
239+ } catch (\ReflectionException $ e ) {
240+ $ this ->markTestSkipped ('Could not check for "map" parameter availability ' );
241+ }
242+ }
98243}
99244
100245class DummyResourceWithoutMap
@@ -105,3 +250,18 @@ class DummyResourceWithoutMap
105250class DummyResourceWithMap
106251{
107252}
253+
254+ #[Map]
255+ class DummyEntity
256+ {
257+ }
258+
259+ #[Map]
260+ class DummyInput
261+ {
262+ }
263+
264+ #[Map]
265+ class DummyOutput
266+ {
267+ }
0 commit comments