2626
2727class PostCreateContactHandlerTest extends TestCase
2828{
29+ /**
30+ * @return array{
31+ * check_proxy_headers: bool,
32+ * trusted_proxies: array<non-empty-string>,
33+ * attribute_name: non-empty-string,
34+ * headers_to_inspect: array<non-empty-string>,
35+ * }
36+ */
37+ private function ipAddressConfig (): array
38+ {
39+ return [
40+ 'check_proxy_headers ' => false ,
41+ 'trusted_proxies ' => [],
42+ 'attribute_name ' => 'ipAddress ' ,
43+ 'headers_to_inspect ' => [],
44+ ];
45+ }
46+
2947 /**
3048 * @return array<string, string>
3149 */
@@ -74,7 +92,12 @@ public function testValidSubmissionRedirectsOnSuccess(): void
7492 ->with ('app::create-contact-form ' , [], ['contact ' => 'sent ' ], 'contact-form ' )
7593 ->willReturn ('/contact/?contact=sent#contact-form ' );
7694
77- $ handler = new PostCreateContactHandler ($ template , $ urlHelper , $ this ->service (new MailResult (true )));
95+ $ handler = new PostCreateContactHandler (
96+ $ template ,
97+ $ urlHelper ,
98+ $ this ->service (new MailResult (true )),
99+ $ this ->ipAddressConfig ()
100+ );
78101 $ response = $ handler ->handle ($ request );
79102
80103 $ this ->assertInstanceOf (RedirectResponse::class, $ response );
@@ -113,7 +136,8 @@ public function testMissingRequiredFieldsRerendersWithErrors(): void
113136 $ handler = new PostCreateContactHandler (
114137 $ template ,
115138 $ this ->createStub (UrlHelper::class),
116- $ this ->service (new MailResult (true ))
139+ $ this ->service (new MailResult (true )),
140+ $ this ->ipAddressConfig ()
117141 );
118142 $ response = $ handler ->handle ($ request );
119143
@@ -150,7 +174,8 @@ public function testRerenderKeepsAnyExtraQueryParamsAsDynamicHiddenFields(): voi
150174 $ handler = new PostCreateContactHandler (
151175 $ template ,
152176 $ this ->createStub (UrlHelper::class),
153- $ this ->service (new MailResult (true ))
177+ $ this ->service (new MailResult (true )),
178+ $ this ->ipAddressConfig ()
154179 );
155180 $ handler ->handle ($ request );
156181 }
@@ -179,7 +204,8 @@ public function testMailTransportFailureRerendersWithMailFailedFlag(): void
179204 $ handler = new PostCreateContactHandler (
180205 $ template ,
181206 $ this ->createStub (UrlHelper::class),
182- $ this ->service (new RuntimeException ('SMTP connection refused ' ))
207+ $ this ->service (new RuntimeException ('SMTP connection refused ' )),
208+ $ this ->ipAddressConfig ()
183209 );
184210 $ response = $ handler ->handle ($ request );
185211
@@ -197,7 +223,7 @@ public function testFailedTurnstileRerendersWithCaptchaErrorAndSendsNothing(): v
197223
198224 $ request = $ this ->createStub (ServerRequestInterface::class);
199225 $ request ->method ('getParsedBody ' )->willReturn ($ data );
200- $ request ->method ('getServerParams ' )->willReturn ([ ' REMOTE_ADDR ' => '203.0.113.5 ' ]);
226+ $ request ->method ('getAttribute ' )->willReturnMap ([[ ' ipAddress ' , null , '203.0.113.5 ' ] ]);
201227
202228 $ contactService = $ this ->createMock (ContactService::class);
203229 $ contactService ->method ('normalize ' )->willReturn ([
@@ -232,10 +258,55 @@ public function testFailedTurnstileRerendersWithCaptchaErrorAndSendsNothing(): v
232258 )
233259 ->willReturn ('<html></html> ' );
234260
235- $ handler = new PostCreateContactHandler ($ template , $ this ->createStub (UrlHelper::class), $ contactService );
261+ $ handler = new PostCreateContactHandler (
262+ $ template ,
263+ $ this ->createStub (UrlHelper::class),
264+ $ contactService ,
265+ $ this ->ipAddressConfig ()
266+ );
236267 $ response = $ handler ->handle ($ request );
237268
238269 $ this ->assertInstanceOf (HtmlResponse::class, $ response );
239270 $ this ->assertSame (200 , $ response ->getStatusCode ());
240271 }
272+
273+ /**
274+ * @throws Exception
275+ */
276+ public function testValidSubmissionSendsTheIpAddressFromTheRequestAttribute (): void
277+ {
278+ $ request = $ this ->createStub (ServerRequestInterface::class);
279+ $ request ->method ('getParsedBody ' )->willReturn ($ this ->validData ());
280+ $ request ->method ('getAttribute ' )->willReturnMap ([['ipAddress ' , null , '203.0.113.5 ' ]]);
281+
282+ $ contactService = $ this ->createMock (ContactService::class);
283+ $ contactService ->method ('normalize ' )->willReturn ([
284+ 'topic ' => 'migration ' ,
285+ 'name ' => 'Jane Doe ' ,
286+ 'email ' => 'jane@example.com ' ,
287+ 'company ' => 'Acme Inc ' ,
288+ 'stack ' => 'ZF3, PHP 7.4 ' ,
289+ 'message ' => 'We would like to talk about migrating our platform. ' ,
290+ 'query ' => '' ,
291+ ]);
292+ $ contactService ->method ('validate ' )->willReturn ([]);
293+ $ contactService ->method ('verifyTurnstile ' )->willReturn (true );
294+ $ contactService
295+ ->expects ($ this ->once ())
296+ ->method ('send ' )
297+ ->with ($ this ->anything (), '203.0.113.5 ' )
298+ ->willReturn (true );
299+
300+ $ urlHelper = $ this ->createStub (UrlHelper::class);
301+ $ urlHelper ->method ('generate ' )->willReturn ('/contact/?contact=sent#contact-form ' );
302+
303+ $ response = (new PostCreateContactHandler (
304+ $ this ->createStub (TemplateRendererInterface::class),
305+ $ urlHelper ,
306+ $ contactService ,
307+ $ this ->ipAddressConfig ()
308+ ))->handle ($ request );
309+
310+ $ this ->assertInstanceOf (RedirectResponse::class, $ response );
311+ }
241312}
0 commit comments