Skip to content

Commit d8ae43e

Browse files
authored
feat: allow request middleware to set a response to bypass downloader (#106)
* feat: allow request middleware to set a response to bypass downloader * tests: Add downloader and request tests
1 parent 167e824 commit d8ae43e

File tree

4 files changed

+83
-1
lines changed

4 files changed

+83
-1
lines changed

src/Downloader/Downloader.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,19 @@ public function flush(?callable $callback = null): void
9696

9797
$this->requests = [];
9898

99-
$this->client->pool($requests, function (Response $response) use ($callback): void {
99+
foreach ($requests as $key => $request) {
100+
if ($request->getResponse() !== null) {
101+
$this->onResponseReceived($request->getResponse(), $callback);
102+
103+
unset($requests[$key]);
104+
}
105+
}
106+
107+
if (\count($requests) === 0) {
108+
return;
109+
}
110+
111+
$this->client->pool(\array_values($requests), function (Response $response) use ($callback): void {
100112
$this->onResponseReceived($response, $callback);
101113
});
102114
}

src/Http/Request.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ final class Request implements DroppableInterface
3434

3535
private RequestInterface $psrRequest;
3636

37+
private ?Response $response = null;
38+
3739
/**
3840
* An array of Guzzle request options.
3941
* See https://docs.guzzlephp.org/en/stable/request-options.html.
@@ -120,4 +122,17 @@ public function getParseCallback(): Closure
120122
{
121123
return $this->parseCallback;
122124
}
125+
126+
public function getResponse(): ?Response
127+
{
128+
return $this->response;
129+
}
130+
131+
public function withResponse(?Response $response): self
132+
{
133+
$clone = clone $this;
134+
$clone->response = $response;
135+
136+
return $clone;
137+
}
123138
}

tests/Downloader/DownloaderTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,46 @@ public function testDontCallParseCallbackIfProcessedResponseWasDroppedByExtensio
333333

334334
self::assertFalse($called);
335335
}
336+
337+
public function testDontSendRequestIfHasResponse(): void
338+
{
339+
$request = $this->makeRequest();
340+
$request = $request->withResponse($this->makeResponse($request));
341+
342+
$this->downloader->prepare($request);
343+
$this->downloader->flush();
344+
345+
$this->client->assertRequestWasNotSent($request);
346+
}
347+
348+
public function testResponseDispatchedWhenNotSent(): void
349+
{
350+
$request = $this->makeRequest();
351+
$request = $request->withResponse($this->makeResponse($request));
352+
353+
$this->downloader->prepare($request);
354+
$this->dispatcher->assertNotDispatched(ResponseReceiving::NAME);
355+
356+
$this->downloader->flush();
357+
$this->dispatcher->assertDispatched(
358+
ResponseReceiving::NAME,
359+
static fn (ResponseReceiving $event) => $event->response->getRequest()->getUri() === $request->getUri(),
360+
);
361+
362+
$this->client->assertRequestWasNotSent($request);
363+
}
364+
365+
public function testPassRequestsThroughRequestHandlersWhenHasResponse(): void
366+
{
367+
$request = $this->makeRequest();
368+
$request = $request->withResponse($this->makeResponse($request));
369+
370+
$middleware = new FakeMiddleware();
371+
372+
$this->downloader
373+
->withMiddleware($middleware)
374+
->prepare($request);
375+
376+
$middleware->assertRequestHandled($request);
377+
}
336378
}

tests/Http/RequestTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ public function testReturnsUnderlyingGuzzleRequest(): void
106106
self::assertSame('::request-uri::', (string) $request->getPsrRequest()->getUri());
107107
}
108108

109+
public function testAddingResponseDoesntMutateRequest(): void
110+
{
111+
$requestA = $this->makeRequest('::request-uri::');
112+
113+
$response = $this->makeResponse($requestA);
114+
115+
$requestB = $requestA->withResponse($response);
116+
117+
self::assertNotSame($requestA, $requestB);
118+
self::assertNull($requestA->getResponse());
119+
self::assertSame($response, $requestB->getResponse());
120+
}
121+
109122
protected function createDroppable(): DroppableInterface
110123
{
111124
return $this->makeRequest();

0 commit comments

Comments
 (0)