22
33namespace Tests \Feature ;
44
5+ use Carbon \Carbon ;
56use Carbon \CarbonInterval ;
6- use Carsdotcom \ApiRequest \Exceptions \ UpstreamException ;
7+ use Carsdotcom \ApiRequest \AbstractRequest ;
78use Carsdotcom \ApiRequest \Exceptions \ToDoException ;
9+ use Carsdotcom \ApiRequest \Exceptions \UpstreamException ;
810use Carsdotcom \ApiRequest \Testing \GuzzleTapper ;
11+ use Carsdotcom \ApiRequest \Testing \MocksGuzzleInstance ;
12+ use Carsdotcom \ApiRequest \Testing \RequestClassAssertions ;
913use Carsdotcom \ApiRequest \Traits \EncodeRequestJSON ;
1014use Carsdotcom \ApiRequest \Traits \ParseResponseJSON ;
1115use Carsdotcom \ApiRequest \Traits \ParseResponseJSONOrThrow ;
12- use Carbon \Carbon ;
1316use GuzzleHttp \Client ;
1417use GuzzleHttp \Exception \ClientException ;
1518use GuzzleHttp \Exception \ConnectException ;
1619use GuzzleHttp \Exception \ServerException ;
17- use GuzzleHttp \Handler \MockHandler ;
18- use GuzzleHttp \HandlerStack ;
1920use GuzzleHttp \Promise \Promise ;
2021use GuzzleHttp \Promise \PromiseInterface ;
2122use GuzzleHttp \Promise \RejectedPromise ;
2728use Illuminate \Support \Facades \Storage ;
2829use Tests \BaseTestCase ;
2930use Tests \MockClasses \ConcreteRequest ;
30- use Carsdotcom \ApiRequest \Testing \MocksGuzzleInstance ;
3131use TiMacDonald \Log \LogEntry ;
3232use TiMacDonald \Log \LogFake ;
3333
3434class AbstractRequestTest extends BaseTestCase
3535{
3636 use MocksGuzzleInstance;
37+ use RequestClassAssertions;
3738
3839 protected function setUp (): void
3940 {
@@ -72,6 +73,7 @@ public function testCacheMissUsesGuzzle(): void
7273 self ::assertSame (['awesome ' => 'sauce ' ], $ result );
7374 // Result was cached
7475 self ::assertTrue ($ requestClass ->canBeFulfilledByCache ());
76+ self ::assertRequestCacheBodyContains ('sauce ' , $ requestClass );
7577 }
7678
7779 public function testCacheHitAfterFirstRequest (): void
@@ -208,7 +210,7 @@ public function testPurgeCache(): void
208210 self ::assertTrue ($ firstRequest ->canBeFulfilledByCache ());
209211 }
210212
211- public function testCacheDisabledInChildClass (): void
213+ public function testCacheDisabledWrite (): void
212214 {
213215 $ tapper = $ this ->mockGuzzleWithTapper ();
214216 $ tapper ->addMatchBody ('POST ' , '/awesome/ ' , '{"awesome":"sauce"} ' );
@@ -223,7 +225,39 @@ public function testCacheDisabledInChildClass(): void
223225 $ request ->sync ();
224226
225227 self ::assertSame (1 , $ tapper ->getCountLike ('POST ' , '/awesome/ ' ));
228+ // Still not in cache
229+ self ::assertFalse ($ request ->canBeFulfilledByCache ());
230+
231+ // But if something *else* caches it, we'll read from it
232+ self ::mockRequestCachedResponse ($ request , '{"awesome":"possum"} ' );
233+ $ response = $ request ->sync ();
234+ self ::assertSame ('{"awesome":"possum"} ' , $ response , "Should receive cache value, not Tapper value " );
235+ self ::assertSame (1 , $ tapper ->getCountLike ('POST ' , '/awesome/ ' ));
236+ }
237+
238+ public function testCacheDisabledRead (): void
239+ {
240+ $ tapper = $ this ->mockGuzzleWithTapper ();
241+ $ tapper ->addMatchBody ('POST ' , '/awesome/ ' , '{"awesome":"sauce"} ' );
242+
243+ $ request = new ConcreteRequest ();
244+ $ request ->setReadCache (false );
245+
246+ // Not in cache, never been called
226247 self ::assertFalse ($ request ->canBeFulfilledByCache ());
248+ self ::assertSame (0 , $ tapper ->getCountLike ('POST ' , '/awesome/ ' ));
249+
250+ $ response = $ request ->sync ();
251+ self ::assertSame ('{"awesome":"sauce"} ' , $ response , "Should receive Tapper value, ignoring cache " );
252+ self ::assertSame (1 , $ tapper ->getCountLike ('POST ' , '/awesome/ ' ));
253+ self ::assertTrue ($ request ->canBeFulfilledByCache ());
254+
255+ // But if the value in cache is manipulated
256+ self ::mockRequestCachedResponse ($ request , '{"awesome":"possum"} ' );
257+ $ response = $ request ->sync ();
258+ self ::assertSame ('{"awesome":"sauce"} ' , $ response , "Should receive Tapper value, ignoring cache " );
259+ // Makes a second request even though a hit was in cache
260+ self ::assertSame (2 , $ tapper ->getCountLike ('POST ' , '/awesome/ ' ));
227261 }
228262
229263 public function testCacheMissRequestFails (): void
@@ -270,7 +304,7 @@ public function testPostProcessMutatesResult(): void
270304 // API returned JSON 42, postProcess doubles it
271305 self ::assertSame (84 , $ result );
272306 // API result (not processed outcome!) was cached
273- self ::requestCacheBodyContains ('42 ' , $ request );
307+ self ::assertRequestCacheBodyContains ('42 ' , $ request );
274308 }
275309
276310 public function testPostProcessCanReject (): void
@@ -733,4 +767,34 @@ protected function getGuzzleClient(): Client
733767 self ::assertSame ("Server error: `POST https://awesome-api.com/url` resulted in a `500 Internal Server Error` response: \nThis method is not implemented \n" , $ exception ->getMessage ());
734768 }
735769 }
770+
771+ /**
772+ * This test should start failing if you change the format of writeResponseToCache
773+ * This is a reminder to increment CACHE_KEY_SEED before you fix this test,
774+ */
775+ public function testCacheStructureCanary (): void
776+ {
777+ $ firstLogTime = '2018-01-01T00:00:00.000000+00:00 ' ;
778+ Carbon::setTestNow ($ firstLogTime );
779+
780+ $ this ->mockGuzzleWithTapper ()->addMatchBody ('POST ' , '/awesome/ ' , '{"awesome":"sauce"} ' );
781+ $ request = $ this ->mockRequestWithLog ();
782+ $ request ->setWriteCache (true )->sync ();
783+ self ::assertTrue ($ request ->canBeFulfilledByCache ());
784+
785+ $ cached = Cache::tags ([])->get ($ request ->cacheKey ());
786+ self ::assertIsArray ($ cached );
787+ self ::assertSame (['logs ' , 'response ' ], array_keys ($ cached )); // No new keys, no removed keys
788+ self ::assertSame ([
789+ 0 => 200 ,
790+ 1 => [],
791+ 2 => '{"awesome":"sauce"} ' ,
792+ 3 => '1.1 ' ,
793+ 4 => 'OK ' ,
794+ ], $ cached ['response ' ]);
795+ self ::assertSame ([ "2018-01-01T00:00:00.000000+00:00 " ], $ cached ['logs ' ]);
796+
797+ // If you modified this test in any way, you need to change the CACHE_KEY_SEED
798+ self ::assertSame ('v2024.8.6 ' , AbstractRequest::CACHE_KEY_SEED );
799+ }
736800}
0 commit comments