@@ -237,4 +237,144 @@ public function testResponseIsExpirableButNotValidateableWhenMasterResponseCombi
237
237
$ this ->assertSame ('60 ' , $ masterResponse ->headers ->getCacheControlDirective ('s-maxage ' ));
238
238
$ this ->assertFalse ($ masterResponse ->isValidateable ());
239
239
}
240
+
241
+ /**
242
+ * @dataProvider cacheControlMergingProvider
243
+ */
244
+ public function testCacheControlMerging (array $ expects , array $ master , array $ surrogates )
245
+ {
246
+ $ cacheStrategy = new ResponseCacheStrategy ();
247
+ $ buildResponse = function ($ config ) {
248
+ $ response = new Response ();
249
+
250
+ foreach ($ config as $ key => $ value ) {
251
+ switch ($ key ) {
252
+ case 'max-age ' :
253
+ $ response ->setMaxAge ($ value );
254
+ break ;
255
+
256
+ case 's-maxage ' :
257
+ $ response ->setSharedMaxAge ($ value );
258
+ break ;
259
+
260
+ case 'private ' :
261
+ $ response ->setPrivate ();
262
+ break ;
263
+
264
+ case 'public ' :
265
+ $ response ->setPublic ();
266
+ break ;
267
+
268
+ default :
269
+ $ response ->headers ->addCacheControlDirective ($ key , $ value );
270
+ }
271
+ }
272
+
273
+ return $ response ;
274
+ };
275
+
276
+ foreach ($ surrogates as $ config ) {
277
+ $ cacheStrategy ->add ($ buildResponse ($ config ));
278
+ }
279
+
280
+ $ response = $ buildResponse ($ master );
281
+ $ cacheStrategy ->update ($ response );
282
+
283
+ foreach ($ expects as $ key => $ value ) {
284
+ if (true === $ value ) {
285
+ $ this ->assertTrue ($ response ->headers ->hasCacheControlDirective ($ key ), sprintf ('Cache-Control header must have "%s" flag ' , $ key ));
286
+ } elseif (false === $ value ) {
287
+ $ this ->assertFalse ($ response ->headers ->hasCacheControlDirective ($ key ), sprintf ('Cache-Control header must NOT have "%s" flag ' , $ key ));
288
+ } else {
289
+ $ this ->assertEquals ($ value , $ response ->headers ->getCacheControlDirective ($ key ), sprintf ('Cache-Control flag "%s" should be "%s" ' , $ key , $ value ));
290
+ }
291
+ }
292
+ }
293
+
294
+ public function cacheControlMergingProvider ()
295
+ {
296
+ yield 'result is public if all responses are public ' => array (
297
+ array ('private ' => false , 'public ' => true ),
298
+ array ('public ' => true ),
299
+ array (
300
+ array ('public ' => true ),
301
+ ),
302
+ );
303
+
304
+ yield 'result is private by default ' => array (
305
+ array ('private ' => true , 'public ' => false ),
306
+ array ('public ' => true ),
307
+ array (
308
+ array (),
309
+ ),
310
+ );
311
+
312
+ yield 'combines public and private responses ' => array (
313
+ array ('must-revalidate ' => false , 'private ' => true , 'public ' => false ),
314
+ array ('public ' => true ),
315
+ array (
316
+ array ('private ' => true ),
317
+ ),
318
+ );
319
+
320
+ yield 'inherits no-cache from surrogates ' => array (
321
+ array ('no-cache ' => true , 'public ' => false ),
322
+ array ('public ' => true ),
323
+ array (
324
+ array ('no-cache ' => true ),
325
+ ),
326
+ );
327
+
328
+ yield 'inherits no-store from surrogate ' => array (
329
+ array ('no-store ' => true , 'public ' => false ),
330
+ array ('public ' => true ),
331
+ array (
332
+ array ('no-store ' => true ),
333
+ ),
334
+ );
335
+
336
+ yield 'resolve to lowest possible max-age ' => array (
337
+ array ('public ' => false , 'private ' => true , 's-maxage ' => false , 'max-age ' => 60 ),
338
+ array ('public ' => true , 'max-age ' => 3600 ),
339
+ array (
340
+ array ('private ' => true , 'max-age ' => 60 ),
341
+ ),
342
+ );
343
+
344
+ yield 'resolves multiple max-age ' => array (
345
+ array ('public ' => false , 'private ' => true , 's-maxage ' => false , 'max-age ' => 60 ),
346
+ array ('private ' => true , 'max-age ' => 100 ),
347
+ array (
348
+ array ('private ' => true , 'max-age ' => 3600 ),
349
+ array ('public ' => true , 'max-age ' => 60 , 's-maxage ' => 60 ),
350
+ array ('private ' => true , 'max-age ' => 60 ),
351
+ ),
352
+ );
353
+
354
+ yield 'merge max-age and s-maxage ' => array (
355
+ array ('public ' => true , 's-maxage ' => 60 , 'max-age ' => null ),
356
+ array ('public ' => true , 's-maxage ' => 3600 ),
357
+ array (
358
+ array ('public ' => true , 'max-age ' => 60 ),
359
+ ),
360
+ );
361
+
362
+ yield 'result is private when combining private responses ' => array (
363
+ array ('no-cache ' => false , 'must-revalidate ' => false , 'private ' => true ),
364
+ array ('s-maxage ' => 60 , 'private ' => true ),
365
+ array (
366
+ array ('s-maxage ' => 60 , 'private ' => true ),
367
+ ),
368
+ );
369
+
370
+ yield 'result can have s-maxage and max-age ' => array (
371
+ array ('public ' => true , 'private ' => false , 's-maxage ' => 60 , 'max-age ' => 30 ),
372
+ array ('s-maxage ' => 100 , 'max-age ' => 2000 ),
373
+ array (
374
+ array ('s-maxage ' => 1000 , 'max-age ' => 30 ),
375
+ array ('s-maxage ' => 500 , 'max-age ' => 500 ),
376
+ array ('s-maxage ' => 60 , 'max-age ' => 1000 ),
377
+ ),
378
+ );
379
+ }
240
380
}
0 commit comments