128 lines
4.8 KiB
PHP
128 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\BpnConnect;
|
|
|
|
use App\BpnConnect\Exception\BpnConnectException;
|
|
use App\BpnConnect\Model\TravelMailingRecipient;
|
|
use App\BpnConnect\TravelsClient;
|
|
use App\Enum\BusLeg;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\NullLogger;
|
|
use Symfony\Component\HttpClient\MockHttpClient;
|
|
use Symfony\Component\HttpClient\Response\MockResponse;
|
|
|
|
class TravelsClientTest extends TestCase
|
|
{
|
|
public function testGetMailingRecipientsQueriesTheTravelCodeAndMapsTheRecipients(): void
|
|
{
|
|
$requests = [];
|
|
$http = new MockHttpClient(function (string $method, string $url, array $options) use (&$requests): MockResponse {
|
|
$requests[] = [$method, $url, $options];
|
|
|
|
return $this->jsonResponse([
|
|
'meta' => ['travel_code' => 'LPJMP281126', 'row_count' => 2, 'execution_time_ms' => 12],
|
|
'data' => [
|
|
['email' => '[email protected]', 'first_name' => 'Erika', 'last_name' => 'Muster'],
|
|
['email' => '[email protected]', 'first_name' => 'Max', 'last_name' => 'Muster'],
|
|
],
|
|
]);
|
|
});
|
|
|
|
$response = $this->client($http)->getMailingRecipients('LPJMP281126');
|
|
|
|
self::assertSame('GET', $requests[0][0]);
|
|
self::assertSame('https://bpn-connect.test/api/v1/travels/mailing?travelCode=LPJMP281126', $requests[0][1]);
|
|
self::assertContains('X-API-KEY: secret', $requests[0][2]['headers']);
|
|
self::assertSame('LPJMP281126', $response->travelCode);
|
|
self::assertNull($response->busLeg);
|
|
self::assertEquals([
|
|
new TravelMailingRecipient('[email protected]', 'Erika', 'Muster'),
|
|
new TravelMailingRecipient('[email protected]', 'Max', 'Muster'),
|
|
], $response->data);
|
|
}
|
|
|
|
public function testGetMailingRecipientsPassesTheBusLegAndAcceptsItsEcho(): void
|
|
{
|
|
$requests = [];
|
|
$http = new MockHttpClient(function (string $method, string $url) use (&$requests): MockResponse {
|
|
$requests[] = $url;
|
|
|
|
return $this->jsonResponse([
|
|
'meta' => ['travel_code' => 'LPJMP281126', 'bus_leg' => 'outbound', 'row_count' => 1, 'execution_time_ms' => 12],
|
|
'data' => [
|
|
['email' => '[email protected]', 'first_name' => 'Erika', 'last_name' => 'Muster'],
|
|
],
|
|
]);
|
|
});
|
|
|
|
$response = $this->client($http)->getMailingRecipients('LPJMP281126', BusLeg::Outbound);
|
|
|
|
self::assertSame(['https://bpn-connect.test/api/v1/travels/mailing?travelCode=LPJMP281126&busLeg=outbound'], $requests);
|
|
self::assertSame(BusLeg::Outbound, $response->busLeg);
|
|
self::assertCount(1, $response->data);
|
|
}
|
|
|
|
public function testABusLegTheServerDidNotApplyIsRejected(): void
|
|
{
|
|
// What a bpn-connect without the filter answers: everyone, and no bus_leg in meta.
|
|
$http = new MockHttpClient($this->jsonResponse([
|
|
'meta' => ['travel_code' => 'LPJMP281126', 'row_count' => 1, 'execution_time_ms' => 12],
|
|
'data' => [
|
|
['email' => '[email protected]', 'first_name' => 'Erika', 'last_name' => 'Muster'],
|
|
],
|
|
]));
|
|
|
|
$this->expectException(BpnConnectException::class);
|
|
|
|
$this->client($http)->getMailingRecipients('LPJMP281126', BusLeg::Outbound);
|
|
}
|
|
|
|
public function testAnUnknownTravelCodeYieldsAnEmptyList(): void
|
|
{
|
|
$http = new MockHttpClient($this->jsonResponse([
|
|
'meta' => ['travel_code' => 'NOPE', 'row_count' => 0, 'execution_time_ms' => 3],
|
|
'data' => [],
|
|
]));
|
|
|
|
$response = $this->client($http)->getMailingRecipients('NOPE');
|
|
|
|
self::assertSame('NOPE', $response->travelCode);
|
|
self::assertSame([], $response->data);
|
|
}
|
|
|
|
public function testAnHttpErrorIsWrappedInADomainException(): void
|
|
{
|
|
$http = new MockHttpClient(new MockResponse('{"error":"internal error"}', ['http_code' => 500]));
|
|
|
|
$this->expectException(BpnConnectException::class);
|
|
|
|
$this->client($http)->getMailingRecipients('LPJMP281126');
|
|
}
|
|
|
|
public function testAnUnconfiguredClientFailsBeforeRequesting(): void
|
|
{
|
|
$client = new TravelsClient(new MockHttpClient(), new NullLogger());
|
|
|
|
$this->expectException(BpnConnectException::class);
|
|
|
|
$client->getMailingRecipients('LPJMP281126');
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $payload
|
|
*/
|
|
private function jsonResponse(array $payload): MockResponse
|
|
{
|
|
return new MockResponse(json_encode($payload, JSON_THROW_ON_ERROR), [
|
|
'response_headers' => ['content-type' => 'application/json'],
|
|
]);
|
|
}
|
|
|
|
private function client(MockHttpClient $http): TravelsClient
|
|
{
|
|
return new TravelsClient($http, new NullLogger(), 'https://bpn-connect.test', 'secret');
|
|
}
|
|
}
|