Skip to content

Commit

Permalink
ISSUE-41 - Consecutive calls (#44)
Browse files Browse the repository at this point in the history
Co-authored-by: Fabrizio Gargiulo <[email protected]>
  • Loading branch information
doppiogancio and Fabrizio Gargiulo authored Aug 25, 2023
1 parent 4f12098 commit 01bb9cc
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/MockedClient/Route/ConsecutiveCallsRouteBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace DoppioGancio\MockedClient\Route;

use Psr\Http\Message\ResponseInterface;

class ConsecutiveCallsRouteBuilder extends RouteBuilder
{
/** @var ResponseInterface[] */
private array $responses = [];

public function new(): self
{
return new self($this->responseFactory, $this->streamFactory);
}

public function withResponse(ResponseInterface $response): self
{
$this->responses[] = $response;

return $this;
}

public function build(): Route
{
return $this->buildRoute(
$this->method,
$this->path,
(new ConsecutiveCallsRouteHandler($this->responses))(...),
);
}
}
30 changes: 30 additions & 0 deletions src/MockedClient/Route/ConsecutiveCallsRouteHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace DoppioGancio\MockedClient\Route;

use DoppioGancio\MockedClient\Route\Exception\TooManyConsecutiveCalls;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

use function count;

class ConsecutiveCallsRouteHandler
{
private int $currentResponse = 0;

/** @param ResponseInterface[] $responses */
public function __construct(private readonly array $responses)
{
}

public function __invoke(RequestInterface $request): ResponseInterface
{
if ($this->currentResponse === count($this->responses)) {
throw new TooManyConsecutiveCalls($request, $this->responses);
}

return $this->responses[$this->currentResponse++];
}
}
27 changes: 27 additions & 0 deletions src/MockedClient/Route/Exception/TooManyConsecutiveCalls.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace DoppioGancio\MockedClient\Route\Exception;

use Exception;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Throwable;

use function sprintf;

class TooManyConsecutiveCalls extends Exception
{
/** @param ResponseInterface[] $responses */
public function __construct(
RequestInterface $request,
public readonly array $responses,
int $code = 0,
Throwable|null $previous = null,
) {
$message = sprintf('Endpoint "%s" has been called too many times', $request->getUri()->getPath());

parent::__construct($message, $code, $previous);
}
}
54 changes: 54 additions & 0 deletions tests/Route/ConsecutiveCallsRouteBuilderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace DoppioGancio\MockedClient\Tests\Route;

use DoppioGancio\MockedClient\Route\ConsecutiveCallsRouteBuilder;
use DoppioGancio\MockedClient\Route\Exception\TooManyConsecutiveCalls;
use GuzzleHttp\Psr7\Request;
use Http\Discovery\Psr17FactoryDiscovery;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;

use function assert;
use function json_decode;

class ConsecutiveCallsRouteBuilderTest extends TestCase
{
public function testRoute(): void
{
$builder = new ConsecutiveCallsRouteBuilder(
Psr17FactoryDiscovery::findResponseFactory(),
Psr17FactoryDiscovery::findStreamFactory(),
);

$route = $builder->withMethod('GET')
->withPath('/country')
->withStringResponse('{"id":"+43","code":"AU","name":"Austria"}')
->withStringResponse('{"id":"+39","code":"IT","name":"Italy"}')
->build();

// Request #1
$response = $route->getHandler()(new Request('GET', '/country'));
assert($response instanceof ResponseInterface);

$this->assertEquals(200, $response->getStatusCode());

$data = json_decode($response->getBody()->getContents(), true);
$this->assertEquals('Austria', $data['name']);

// Request #2
$response = $route->getHandler()(new Request('GET', '/country'));
assert($response instanceof ResponseInterface);

$this->assertEquals(200, $response->getStatusCode());

$data = json_decode($response->getBody()->getContents(), true);
$this->assertEquals('Italy', $data['name']);

// Request #3 - Called too many times
$this->expectException(TooManyConsecutiveCalls::class);
$route->getHandler()(new Request('GET', '/country'));
}
}

0 comments on commit 01bb9cc

Please sign in to comment.