1717use CodeIgniter \Format \FormatterInterface ;
1818use CodeIgniter \Format \JSONFormatter ;
1919use CodeIgniter \Format \XMLFormatter ;
20+ use CodeIgniter \HTTP \RequestInterface ;
21+ use CodeIgniter \HTTP \ResponseInterface ;
2022use CodeIgniter \HTTP \SiteURI ;
2123use CodeIgniter \HTTP \UserAgent ;
2224use CodeIgniter \Test \CIUnitTestCase ;
2325use CodeIgniter \Test \Mock \MockIncomingRequest ;
2426use CodeIgniter \Test \Mock \MockResponse ;
2527use Config \App ;
2628use Config \Cookie ;
29+ use Config \Services ;
2730use PHPUnit \Framework \Attributes \Group ;
2831use stdClass ;
2932
@@ -82,6 +85,12 @@ private function createCookieConfig(): Cookie
8285 return $ cookie ;
8386 }
8487
88+ /**
89+ * @param array<string, string> $userHeaders
90+ *
91+ * @phpstan-assert RequestInterface $this->request
92+ * @phpstan-assert ResponseInterface $this->response
93+ */
8594 private function createRequestAndResponse (string $ routePath = '' , array $ userHeaders = []): void
8695 {
8796 $ config = $ this ->createAppConfig ();
@@ -97,29 +106,28 @@ private function createRequestAndResponse(string $routePath = '', array $userHea
97106 $ this ->response = new MockResponse ($ config );
98107 }
99108
100- // Insert headers into request.
101- $ headers = [
102- 'Accept ' => 'text/html ' ,
103- ];
104- $ headers = array_merge ($ headers , $ userHeaders );
109+ $ headers = array_merge (['Accept ' => 'text/html ' ], $ userHeaders );
105110
106111 foreach ($ headers as $ key => $ value ) {
107112 $ this ->request ->setHeader ($ key , $ value );
108113 }
109114 }
110115
116+ /**
117+ * @param array<string, string> $userHeaders
118+ */
111119 protected function makeController (string $ routePath = '' , array $ userHeaders = []): object
112120 {
113121 $ this ->createRequestAndResponse ($ routePath , $ userHeaders );
114122
115- // Create the controller class finally.
116123 return new class ($ this ->request , $ this ->response , $ this ->formatter ) {
117124 use ResponseTrait;
118125
119- protected $ formatter ;
120-
121- public function __construct (protected $ request , protected $ response , $ formatter )
122- {
126+ public function __construct (
127+ protected RequestInterface $ request ,
128+ protected ResponseInterface $ response ,
129+ ?FormatterInterface $ formatter ,
130+ ) {
123131 $ this ->formatter = $ formatter ;
124132 }
125133
@@ -173,11 +181,13 @@ public function testNoFormatterWithStringAsHtmlTrue(): void
173181 $ controller = new class ($ this ->request , $ this ->response , $ this ->formatter ) {
174182 use ResponseTrait;
175183
176- protected $ formatter ;
177184 protected bool $ stringAsHtml = true ;
178185
179- public function __construct (protected $ request , protected $ response , $ formatter )
180- {
186+ public function __construct (
187+ protected RequestInterface $ request ,
188+ protected ResponseInterface $ response ,
189+ ?FormatterInterface $ formatter ,
190+ ) {
181191 $ this ->formatter = $ formatter ;
182192 }
183193 };
@@ -291,11 +301,13 @@ public function testRespondSetsCorrectBodyAndStatusWithStringAsHtmlTrue(): void
291301 $ controller = new class ($ this ->request , $ this ->response , $ this ->formatter ) {
292302 use ResponseTrait;
293303
294- protected $ formatter ;
295304 protected bool $ stringAsHtml = true ;
296305
297- public function __construct (protected $ request , protected $ response , $ formatter )
298- {
306+ public function __construct (
307+ protected RequestInterface $ request ,
308+ protected ResponseInterface $ response ,
309+ ?FormatterInterface $ formatter ,
310+ ) {
299311 $ this ->formatter = $ formatter ;
300312 }
301313 };
@@ -546,8 +558,8 @@ public function testValidContentTypes(): void
546558
547559 private function tryValidContentType (string $ mimeType , string $ contentType ): void
548560 {
549- $ original = $ _SERVER ;
550- $ _SERVER [ 'CONTENT_TYPE ' ] = $ mimeType ;
561+ $ originalContentType = Services:: superglobals ()-> server ( ' CONTENT_TYPE ' ) ?? '' ;
562+ Services:: superglobals ()-> setServer ( 'CONTENT_TYPE ' , $ mimeType) ;
551563
552564 $ this ->makeController ('' , ['Accept ' => $ mimeType ]);
553565 $ this ->assertSame (
@@ -563,7 +575,7 @@ private function tryValidContentType(string $mimeType, string $contentType): voi
563575 'Response header pre-response... ' ,
564576 );
565577
566- $ _SERVER = $ original ;
578+ Services:: superglobals ()-> setServer ( ' CONTENT_TYPE ' , $ originalContentType ) ;
567579 }
568580
569581 public function testValidResponses (): void
@@ -609,9 +621,11 @@ public function testFormatByRequestNegotiateIfFormatIsNotJsonOrXML(): void
609621 $ controller = new class ($ request , $ response ) {
610622 use ResponseTrait;
611623
612- public function __construct (protected $ request , protected $ response )
613- {
614- $ this ->format = 'txt ' ;
624+ public function __construct (
625+ protected RequestInterface $ request ,
626+ protected ResponseInterface $ response ,
627+ ) {
628+ $ this ->format = 'txt ' ; // @phpstan-ignore assign.propertyType (needed for testing)
615629 }
616630 };
617631
@@ -659,6 +673,9 @@ public function testXMLResponseFormat(): void
659673 $ this ->assertSame ($ xmlFormatter ->format ($ data ), $ this ->response ->getXML ());
660674 }
661675
676+ /**
677+ * @param list<mixed> $args
678+ */
662679 private function invoke (object $ controller , string $ method , array $ args = []): object
663680 {
664681 $ method = self ::getPrivateMethodInvoker ($ controller , $ method );
0 commit comments