@@ -894,4 +894,53 @@ public function testResponseInfluencingHeadersAffectCacheKey()
894894 self ::assertSame (200 , $ response ->getStatusCode ());
895895 self ::assertSame ('response for fr ' , $ response ->getContent ());
896896 }
897+
898+ public function testUnsafeInvalidationInBypassFlow ()
899+ {
900+ $ mockClient = new MockHttpClient ([
901+ new MockResponse ('initial get ' , ['http_code ' => 200 , 'response_headers ' => ['Cache-Control ' => 'max-age=300 ' ]]),
902+ new MockResponse ('' , ['http_code ' => 204 ]),
903+ new MockResponse ('after invalidate ' , ['http_code ' => 200 ]),
904+ ]);
905+
906+ $ client = new CachingHttpClient ($ mockClient , $ this ->cacheAdapter );
907+
908+ // Warm cache with GET
909+ $ response = $ client ->request ('GET ' , 'http://example.com/unsafe-test ' );
910+ self ::assertSame (200 , $ response ->getStatusCode ());
911+ self ::assertSame ('initial get ' , $ response ->getContent ());
912+
913+ // Unsafe POST with body (bypasses cache but invalidates on success)
914+ $ client ->request ('POST ' , 'http://example.com/unsafe-test ' , ['body ' => 'invalidate ' ]);
915+
916+ // Next GET should miss cache and fetch new
917+ $ response = $ client ->request ('GET ' , 'http://example.com/unsafe-test ' );
918+ self ::assertSame (200 , $ response ->getStatusCode ());
919+ self ::assertSame ('after invalidate ' , $ response ->getContent ());
920+ }
921+
922+ public function testNoInvalidationOnErrorInBypassFlow ()
923+ {
924+ $ mockClient = new MockHttpClient ([
925+ new MockResponse ('initial get ' , ['http_code ' => 200 , 'response_headers ' => ['Cache-Control ' => 'max-age=300 ' ]]),
926+ new MockResponse ('server error ' , ['http_code ' => 500 ]),
927+ new MockResponse ('should not be fetched ' ),
928+ ]);
929+
930+ $ client = new CachingHttpClient ($ mockClient , $ this ->cacheAdapter );
931+
932+ // Warm cache with GET
933+ $ response = $ client ->request ('GET ' , 'http://example.com/no-invalidate-test ' );
934+ self ::assertSame (200 , $ response ->getStatusCode ());
935+ self ::assertSame ('initial get ' , $ response ->getContent ());
936+
937+ // Unsafe POST with body (bypasses cache, but 500 shouldn't invalidate)
938+ $ response = $ client ->request ('POST ' , 'http://example.com/no-invalidate-test ' , ['body ' => 'no invalidate ' ]);
939+ self ::assertSame (500 , $ response ->getStatusCode ());
940+
941+ // Next GET should hit cache
942+ $ response = $ client ->request ('GET ' , 'http://example.com/no-invalidate-test ' );
943+ self ::assertSame (200 , $ response ->getStatusCode ());
944+ self ::assertSame ('initial get ' , $ response ->getContent ());
945+ }
897946}
0 commit comments