Skip to content

Instantly share code, notes, and snippets.

@bpolaszek
Created July 26, 2021 10:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bpolaszek/be21b7526fbe2e79ea26ab042a8a6a73 to your computer and use it in GitHub Desktop.
Save bpolaszek/be21b7526fbe2e79ea26ab042a8a6a73 to your computer and use it in GitHub Desktop.
Pest Api-Platform Client
<?php
declare(strict_types=1);
namespace App\Tests;
use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
use function array_replace;
use function array_shift;
final class ApiClient
{
private Client $client;
private ?string $token = null;
/**
* @var ResponseInterface[]
*/
private array $mocks = [];
public function __construct(Client $client, ?UserInterface $user = null)
{
$this->client = $client;
if (null === $user) {
return;
}
$this->token = jwt($user);
}
public function withAccessToken(?string $accessToken): self
{
$clone = clone $this;
$clone->token = $accessToken;
return $clone;
}
public function as(?UserInterface $user): self
{
return new self($this->client, $user);
}
/**
* @param array<string, mixed> $options
*/
public function get(string $url, array $options = []): ResponseInterface
{
return $this->request('GET', $url, $this->withOptions($options));
}
/**
* @param array<string, mixed> $data
* @param array<string, mixed> $options
*/
public function post(string $url, array $data = [], array $options = []): ResponseInterface
{
$options['json'] = $data;
return $this->request('POST', $url, $this->withOptions($options));
}
/**
* @param array<string, mixed> $data
* @param array<string, mixed> $options
*/
public function put(string $url, array $data = [], array $options = []): ResponseInterface
{
$options['json'] = $data;
return $this->request('PUT', $url, $this->withOptions($options));
}
/**
* @param array<string, mixed> $data
* @param array<string, mixed> $options
*/
public function patch(string $url, array $data = [], array $options = []): ResponseInterface
{
$options['json'] = $data;
$options['headers'] = array_replace(
['Content-Type' => 'application/merge-patch+json'],
$options['headers'] ?? []
);
return $this->request('PATCH', $url, $this->withOptions($options));
}
/**
* @param array<string, mixed> $options
*/
public function delete(string $url, array $options = []): ResponseInterface
{
return $this->request('DELETE', $url, $this->withOptions($options));
}
/**
* Mocks the next response.
*/
public function mock(ResponseInterface $response): void
{
$this->mocks[] = $response;
}
/**
* @param array<string, mixed> $options
*/
private function request(string $method, string $url, array $options): ResponseInterface
{
if ([] !== $this->mocks) {
return (new MockHttpClient(array_shift($this->mocks), Client::API_OPTIONS_DEFAULTS['base_uri']))
->request($method, $url, $options);
}
$this->client->request($method, $url, $options);
/** @var ResponseInterface $response */
$response = $this->client->getResponse();
return $response;
}
/**
* @param array<string, mixed> $options
*
* @return array<string, mixed>
*/
private function withOptions(array $options): array
{
if (null !== $this->token) {
$options['auth_bearer'] = $this->token;
}
return $options;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment