@@ -809,6 +809,42 @@ public function testValidatesCachedResponsesWithETagAndNoFreshnessInformation()
809809 $ this ->assertTraceNotContains ('miss ' );
810810 }
811811
812+ public function testServesResponseWhileFreshAndRevalidatesWithLastModifiedInformation ()
813+ {
814+ $ time = \DateTime::createFromFormat ('U ' , time ());
815+
816+ $ this ->setNextResponse (200 , array (), 'Hello World ' , function (Request $ request , Response $ response ) use ($ time ) {
817+ $ response ->setSharedMaxAge (10 );
818+ $ response ->headers ->set ('Last-Modified ' , $ time ->format (DATE_RFC2822 ));
819+ });
820+
821+ // prime the cache
822+ $ this ->request ('GET ' , '/ ' );
823+
824+ // next request before s-maxage has expired: Serve from cache
825+ // without hitting the backend
826+ $ this ->request ('GET ' , '/ ' );
827+ $ this ->assertHttpKernelIsNotCalled ();
828+ $ this ->assertEquals (200 , $ this ->response ->getStatusCode ());
829+ $ this ->assertEquals ('Hello World ' , $ this ->response ->getContent ());
830+ $ this ->assertTraceContains ('fresh ' );
831+
832+ sleep (15 ); // expire the cache
833+
834+ $ that = $ this ;
835+
836+ $ this ->setNextResponse (304 , array (), '' , function (Request $ request , Response $ response ) use ($ time , $ that ) {
837+ $ that ->assertEquals ($ time ->format (DATE_RFC2822 ), $ request ->headers ->get ('IF_MODIFIED_SINCE ' ));
838+ });
839+
840+ $ this ->request ('GET ' , '/ ' );
841+ $ this ->assertHttpKernelIsCalled ();
842+ $ this ->assertEquals (200 , $ this ->response ->getStatusCode ());
843+ $ this ->assertEquals ('Hello World ' , $ this ->response ->getContent ());
844+ $ this ->assertTraceContains ('stale ' );
845+ $ this ->assertTraceContains ('valid ' );
846+ }
847+
812848 public function testReplacesCachedResponsesWhenValidationResultsInNon304Response ()
813849 {
814850 $ time = \DateTime::createFromFormat ('U ' , time ());
0 commit comments