1111
1212namespace Symfony \Component \HttpKernel \Tests \HttpCache ;
1313
14+ use Symfony \Bridge \PhpUnit \ExpectDeprecationTrait ;
15+ use Symfony \Component \EventDispatcher \EventDispatcher ;
1416use Symfony \Component \HttpFoundation \Request ;
1517use Symfony \Component \HttpFoundation \Response ;
18+ use Symfony \Component \HttpKernel \Event \TerminateEvent ;
1619use Symfony \Component \HttpKernel \HttpCache \Esi ;
1720use Symfony \Component \HttpKernel \HttpCache \HttpCache ;
18- use Symfony \Component \HttpKernel \HttpCache \Store ;
1921use Symfony \Component \HttpKernel \HttpCache \StoreInterface ;
2022use Symfony \Component \HttpKernel \HttpKernelInterface ;
2123use Symfony \Component \HttpKernel \Kernel ;
2527 */
2628class HttpCacheTest extends HttpCacheTestCase
2729{
30+ use ExpectDeprecationTrait;
31+
2832 public function testTerminateDelegatesTerminationOnlyForTerminableInterface ()
2933 {
3034 $ storeMock = $ this ->getMockBuilder (StoreInterface::class)
@@ -33,7 +37,7 @@ public function testTerminateDelegatesTerminationOnlyForTerminableInterface()
3337
3438 // does not implement TerminableInterface
3539 $ kernel = new TestKernel ();
36- $ httpCache = new HttpCache ($ kernel , $ storeMock );
40+ $ httpCache = new HttpCache ($ kernel , $ storeMock, null , [ ' terminate_on_cache_hit ' => false ] );
3741 $ httpCache ->terminate (Request::create ('/ ' ), new Response ());
3842
3943 $ this ->assertFalse ($ kernel ->terminateCalled , 'terminate() is never called if the kernel class does not implement TerminableInterface ' );
@@ -47,10 +51,108 @@ public function testTerminateDelegatesTerminationOnlyForTerminableInterface()
4751 $ kernelMock ->expects ($ this ->once ())
4852 ->method ('terminate ' );
4953
50- $ kernel = new HttpCache ($ kernelMock , $ storeMock );
54+ $ kernel = new HttpCache ($ kernelMock , $ storeMock, null , [ ' terminate_on_cache_hit ' => false ] );
5155 $ kernel ->terminate (Request::create ('/ ' ), new Response ());
5256 }
5357
58+ public function testDoesNotCallTerminateOnFreshResponse ()
59+ {
60+ $ terminateEvents = [];
61+
62+ $ eventDispatcher = $ this ->createMock (EventDispatcher::class);
63+ $ eventDispatcher
64+ ->expects ($ this ->any ())
65+ ->method ('dispatch ' )
66+ ->with ($ this ->callback (function ($ event ) use (&$ terminateEvents ) {
67+ if ($ event instanceof TerminateEvent) {
68+ $ terminateEvents [] = $ event ;
69+ }
70+
71+ return true ;
72+ }));
73+
74+ $ this ->setNextResponse (
75+ 200 ,
76+ [
77+ 'ETag ' => '1234 ' ,
78+ 'Cache-Control ' => 'public, s-maxage=60 ' ,
79+ ],
80+ 'Hello World ' ,
81+ null ,
82+ $ eventDispatcher
83+ );
84+
85+ $ this ->request ('GET ' , '/ ' );
86+ $ this ->assertHttpKernelIsCalled ();
87+ $ this ->assertEquals (200 , $ this ->response ->getStatusCode ());
88+ $ this ->assertTraceContains ('miss ' );
89+ $ this ->assertTraceContains ('store ' );
90+ $ this ->cache ->terminate ($ this ->request , $ this ->response );
91+
92+ sleep (2 );
93+
94+ $ this ->request ('GET ' , '/ ' );
95+ $ this ->assertHttpKernelIsNotCalled ();
96+ $ this ->assertEquals (200 , $ this ->response ->getStatusCode ());
97+ $ this ->assertTraceContains ('fresh ' );
98+ $ this ->assertEquals (2 , $ this ->response ->headers ->get ('Age ' ));
99+ $ this ->cache ->terminate ($ this ->request , $ this ->response );
100+
101+ $ this ->assertCount (1 , $ terminateEvents );
102+ }
103+
104+ /**
105+ * @group legacy
106+ */
107+ public function testDoesCallTerminateOnFreshResponseIfConfigured ()
108+ {
109+ $ this ->expectDeprecation ('Since symfony/http-kernel 6.2: Setting "terminate_on_cache_hit" to "true" is deprecated and will be changed to "false" in Symfony 7.0. ' );
110+
111+ $ terminateEvents = [];
112+
113+ $ eventDispatcher = $ this ->createMock (EventDispatcher::class);
114+ $ eventDispatcher
115+ ->expects ($ this ->any ())
116+ ->method ('dispatch ' )
117+ ->with ($ this ->callback (function ($ event ) use (&$ terminateEvents ) {
118+ if ($ event instanceof TerminateEvent) {
119+ $ terminateEvents [] = $ event ;
120+ }
121+
122+ return true ;
123+ }));
124+
125+ $ this ->setNextResponse (
126+ 200 ,
127+ [
128+ 'ETag ' => '1234 ' ,
129+ 'Cache-Control ' => 'public, s-maxage=60 ' ,
130+ ],
131+ 'Hello World ' ,
132+ null ,
133+ $ eventDispatcher
134+ );
135+ $ this ->cacheConfig ['terminate_on_cache_hit ' ] = true ;
136+
137+ $ this ->request ('GET ' , '/ ' );
138+ $ this ->assertHttpKernelIsCalled ();
139+ $ this ->assertEquals (200 , $ this ->response ->getStatusCode ());
140+ $ this ->assertTraceContains ('miss ' );
141+ $ this ->assertTraceContains ('store ' );
142+ $ this ->cache ->terminate ($ this ->request , $ this ->response );
143+
144+ sleep (2 );
145+
146+ $ this ->request ('GET ' , '/ ' );
147+ $ this ->assertHttpKernelIsNotCalled ();
148+ $ this ->assertEquals (200 , $ this ->response ->getStatusCode ());
149+ $ this ->assertTraceContains ('fresh ' );
150+ $ this ->assertEquals (2 , $ this ->response ->headers ->get ('Age ' ));
151+ $ this ->cache ->terminate ($ this ->request , $ this ->response );
152+
153+ $ this ->assertCount (2 , $ terminateEvents );
154+ }
155+
54156 public function testPassesOnNonGetHeadRequests ()
55157 {
56158 $ this ->setNextResponse (200 );
0 commit comments