Security update for Core, with self-updated composer
[yaffs-website] / vendor / symfony / http-kernel / Tests / HttpCache / ResponseCacheStrategyTest.php
index f30a3b6ad94abc49767c2410db26ca63c25469e0..5e4c322223eb386ce61d61c94ac337b64338a05f 100644 (file)
@@ -75,4 +75,148 @@ class ResponseCacheStrategyTest extends TestCase
 
         $this->assertFalse($response->headers->hasCacheControlDirective('s-maxage'));
     }
+
+    public function testMasterResponseNotCacheableWhenEmbeddedResponseRequiresValidation()
+    {
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        $embeddedResponse = new Response();
+        $embeddedResponse->setLastModified(new \DateTime());
+        $cacheStrategy->add($embeddedResponse);
+
+        $masterResponse = new Response();
+        $masterResponse->setSharedMaxAge(3600);
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertTrue($masterResponse->headers->hasCacheControlDirective('no-cache'));
+        $this->assertTrue($masterResponse->headers->hasCacheControlDirective('must-revalidate'));
+        $this->assertFalse($masterResponse->isFresh());
+    }
+
+    public function testValidationOnMasterResponseIsNotPossibleWhenItContainsEmbeddedResponses()
+    {
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        // This master response uses the "validation" model
+        $masterResponse = new Response();
+        $masterResponse->setLastModified(new \DateTime());
+        $masterResponse->setEtag('foo');
+
+        // Embedded response uses "expiry" model
+        $embeddedResponse = new Response();
+        $masterResponse->setSharedMaxAge(3600);
+        $cacheStrategy->add($embeddedResponse);
+
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertFalse($masterResponse->isValidateable());
+        $this->assertFalse($masterResponse->headers->has('Last-Modified'));
+        $this->assertFalse($masterResponse->headers->has('ETag'));
+        $this->assertTrue($masterResponse->headers->hasCacheControlDirective('no-cache'));
+        $this->assertTrue($masterResponse->headers->hasCacheControlDirective('must-revalidate'));
+    }
+
+    public function testMasterResponseWithValidationIsUnchangedWhenThereIsNoEmbeddedResponse()
+    {
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        $masterResponse = new Response();
+        $masterResponse->setLastModified(new \DateTime());
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertTrue($masterResponse->isValidateable());
+    }
+
+    public function testMasterResponseWithExpirationIsUnchangedWhenThereIsNoEmbeddedResponse()
+    {
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        $masterResponse = new Response();
+        $masterResponse->setSharedMaxAge(3600);
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertTrue($masterResponse->isFresh());
+    }
+
+    public function testMasterResponseIsNotCacheableWhenEmbeddedResponseIsNotCacheable()
+    {
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        $masterResponse = new Response();
+        $masterResponse->setSharedMaxAge(3600); // Public, cacheable
+
+        /* This response has no validation or expiration information.
+           That makes it uncacheable, it is always stale.
+           (It does *not* make this private, though.) */
+        $embeddedResponse = new Response();
+        $this->assertFalse($embeddedResponse->isFresh()); // not fresh, as no lifetime is provided
+
+        $cacheStrategy->add($embeddedResponse);
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertTrue($masterResponse->headers->hasCacheControlDirective('no-cache'));
+        $this->assertTrue($masterResponse->headers->hasCacheControlDirective('must-revalidate'));
+        $this->assertFalse($masterResponse->isFresh());
+    }
+
+    public function testEmbeddingPrivateResponseMakesMainResponsePrivate()
+    {
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        $masterResponse = new Response();
+        $masterResponse->setSharedMaxAge(3600); // public, cacheable
+
+        // The embedded response might for example contain per-user data that remains valid for 60 seconds
+        $embeddedResponse = new Response();
+        $embeddedResponse->setPrivate();
+        $embeddedResponse->setMaxAge(60); // this would implicitly set "private" as well, but let's be explicit
+
+        $cacheStrategy->add($embeddedResponse);
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertTrue($masterResponse->headers->hasCacheControlDirective('private'));
+        // Not sure if we should pass "max-age: 60" in this case, as long as the response is private and
+        // that's the more conservative of both the master and embedded response...?
+    }
+
+    public function testResponseIsExiprableWhenEmbeddedResponseCombinesExpiryAndValidation()
+    {
+        /* When "expiration wins over validation" (https://symfony.com/doc/current/http_cache/validation.html)
+         * and both the main and embedded response provide s-maxage, then the more restricting value of both
+         * should be fine, regardless of whether the embedded response can be validated later on or must be
+         * completely regenerated.
+         */
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        $masterResponse = new Response();
+        $masterResponse->setSharedMaxAge(3600);
+
+        $embeddedResponse = new Response();
+        $embeddedResponse->setSharedMaxAge(60);
+        $embeddedResponse->setEtag('foo');
+
+        $cacheStrategy->add($embeddedResponse);
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertSame('60', $masterResponse->headers->getCacheControlDirective('s-maxage'));
+    }
+
+    public function testResponseIsExpirableButNotValidateableWhenMasterResponseCombinesExpirationAndValidation()
+    {
+        $cacheStrategy = new ResponseCacheStrategy();
+
+        $masterResponse = new Response();
+        $masterResponse->setSharedMaxAge(3600);
+        $masterResponse->setEtag('foo');
+        $masterResponse->setLastModified(new \DateTime());
+
+        $embeddedResponse = new Response();
+        $embeddedResponse->setSharedMaxAge(60);
+
+        $cacheStrategy->add($embeddedResponse);
+        $cacheStrategy->update($masterResponse);
+
+        $this->assertSame('60', $masterResponse->headers->getCacheControlDirective('s-maxage'));
+        $this->assertFalse($masterResponse->isValidateable());
+    }
 }