24
24
use CodeIgniter \Test \Mock \MockSecurity ;
25
25
use Config \Security as SecurityConfig ;
26
26
use PHPUnit \Framework \Attributes \BackupGlobals ;
27
+ use PHPUnit \Framework \Attributes \DataProvider ;
27
28
use PHPUnit \Framework \Attributes \Group ;
28
29
29
30
/**
@@ -42,13 +43,23 @@ protected function setUp(): void
42
43
$ this ->resetServices ();
43
44
}
44
45
45
- private function createMockSecurity (? SecurityConfig $ config = null ): MockSecurity
46
+ private static function createMockSecurity (SecurityConfig $ config = new SecurityConfig () ): MockSecurity
46
47
{
47
- $ config ??= new SecurityConfig ();
48
-
49
48
return new MockSecurity ($ config );
50
49
}
51
50
51
+ private static function createIncomingRequest (): IncomingRequest
52
+ {
53
+ $ config = new MockAppConfig ();
54
+
55
+ return new IncomingRequest (
56
+ $ config ,
57
+ new SiteURI ($ config ),
58
+ null ,
59
+ new UserAgent (),
60
+ );
61
+ }
62
+
52
63
public function testBasicConfigIsSaved (): void
53
64
{
54
65
$ security = $ this ->createMockSecurity ();
@@ -108,18 +119,6 @@ public function testCSRFVerifyPostThrowsExceptionOnNoMatch(): void
108
119
$ security ->verify ($ request );
109
120
}
110
121
111
- private function createIncomingRequest (): IncomingRequest
112
- {
113
- $ config = new MockAppConfig ();
114
-
115
- return new IncomingRequest (
116
- $ config ,
117
- new SiteURI ($ config ),
118
- null ,
119
- new UserAgent (),
120
- );
121
- }
122
-
123
122
public function testCSRFVerifyPostReturnsSelfOnMatch (): void
124
123
{
125
124
$ _SERVER ['REQUEST_METHOD ' ] = 'POST ' ;
@@ -315,4 +314,73 @@ public function testGetters(): void
315
314
$ this ->assertIsString ($ security ->getCookieName ());
316
315
$ this ->assertIsBool ($ security ->shouldRedirect ());
317
316
}
317
+
318
+ public function testGetPostedTokenReturnsTokenFromPost (): void
319
+ {
320
+ $ _POST ['csrf_test_name ' ] = '8b9218a55906f9dcc1dc263dce7f005a ' ;
321
+ $ request = $ this ->createIncomingRequest ();
322
+ $ method = $ this ->getPrivateMethodInvoker ($ this ->createMockSecurity (), 'getPostedToken ' );
323
+
324
+ $ this ->assertSame ('8b9218a55906f9dcc1dc263dce7f005a ' , $ method ($ request ));
325
+ }
326
+
327
+ public function testGetPostedTokenReturnsTokenFromHeader (): void
328
+ {
329
+ $ _POST = [];
330
+ $ request = $ this ->createIncomingRequest ()->setHeader ('X-CSRF-TOKEN ' , '8b9218a55906f9dcc1dc263dce7f005a ' );
331
+ $ method = $ this ->getPrivateMethodInvoker ($ this ->createMockSecurity (), 'getPostedToken ' );
332
+
333
+ $ this ->assertSame ('8b9218a55906f9dcc1dc263dce7f005a ' , $ method ($ request ));
334
+ }
335
+
336
+ public function testGetPostedTokenReturnsTokenFromJsonBody (): void
337
+ {
338
+ $ _POST = [];
339
+ $ jsonBody = json_encode (['csrf_test_name ' => '8b9218a55906f9dcc1dc263dce7f005a ' ]);
340
+ $ request = $ this ->createIncomingRequest ()->setBody ($ jsonBody );
341
+ $ method = $ this ->getPrivateMethodInvoker ($ this ->createMockSecurity (), 'getPostedToken ' );
342
+
343
+ $ this ->assertSame ('8b9218a55906f9dcc1dc263dce7f005a ' , $ method ($ request ));
344
+ }
345
+
346
+ public function testGetPostedTokenReturnsTokenFromFormBody (): void
347
+ {
348
+ $ _POST = [];
349
+ $ formBody = 'csrf_test_name=8b9218a55906f9dcc1dc263dce7f005a ' ;
350
+ $ request = $ this ->createIncomingRequest ()->setBody ($ formBody );
351
+ $ method = $ this ->getPrivateMethodInvoker ($ this ->createMockSecurity (), 'getPostedToken ' );
352
+
353
+ $ this ->assertSame ('8b9218a55906f9dcc1dc263dce7f005a ' , $ method ($ request ));
354
+ }
355
+
356
+ #[DataProvider('provideGetPostedTokenReturnsNullForInvalidInputs ' )]
357
+ public function testGetPostedTokenReturnsNullForInvalidInputs (string $ case , IncomingRequest $ request ): void
358
+ {
359
+ $ method = $ this ->getPrivateMethodInvoker ($ this ->createMockSecurity (), 'getPostedToken ' );
360
+
361
+ $ this ->assertNull (
362
+ $ method ($ request ),
363
+ sprintf ('Failed asserting that %s returns null on invalid input. ' , $ case ),
364
+ );
365
+ }
366
+
367
+ /**
368
+ * @return iterable<string, array{string, IncomingRequest}>
369
+ */
370
+ public static function provideGetPostedTokenReturnsNullForInvalidInputs (): iterable
371
+ {
372
+ $ testCases = [
373
+ 'empty_post ' => self ::createIncomingRequest (),
374
+ 'invalid_post_data ' => self ::createIncomingRequest ()->setGlobal ('post ' , ['csrf_test_name ' => ['invalid ' => 'data ' ]]),
375
+ 'empty_header ' => self ::createIncomingRequest ()->setHeader ('X-CSRF-TOKEN ' , '' ),
376
+ 'invalid_json_data ' => self ::createIncomingRequest ()->setBody (json_encode (['csrf_test_name ' => ['invalid ' => 'data ' ]])),
377
+ 'invalid_json ' => self ::createIncomingRequest ()->setBody ('{invalid json} ' ),
378
+ 'missing_token_in_body ' => self ::createIncomingRequest ()->setBody ('other=value&another=test ' ),
379
+ 'invalid_form_data ' => self ::createIncomingRequest ()->setBody ('csrf_test_name[]=invalid ' ),
380
+ ];
381
+
382
+ foreach ($ testCases as $ case => $ request ) {
383
+ yield $ case => [$ case , $ request ];
384
+ }
385
+ }
318
386
}
0 commit comments