pp-planer/tests/Feature/CtsApiSpikeTest.php
Thorsten Bus 04d271f96a style: apply Laravel Pint formatting across codebase
Auto-formatted by Laravel Pint (default Laravel preset): string
concatenation spacing, anonymous class brace placement, constructor
body shorthand, import ordering, and assertion indentation.
2026-03-02 23:02:03 +01:00

120 lines
3.6 KiB
PHP

<?php
use CTApi\CTClient;
use CTApi\CTConfig;
use GuzzleHttp\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
it('syncs mocked future events and song shape through the CTS pipeline', function () {
$eventsPayload = [
'data' => [
[
'domainIdentifier' => '100',
'title' => 'Gottesdienst Sonntag',
'startDate' => '2026-03-08T10:00:00+00:00',
'note' => 'Probe',
],
],
'meta' => [
'pagination' => [
'lastPage' => 1,
],
],
];
$songPayload = [
'data' => [
'songId' => '1',
'name' => 'Way Maker',
'ccli' => '7115744',
'arrangements' => [
['id' => '11', 'name' => 'Normal', 'isDefault' => true],
],
'lyrics' => [
'type' => 'text',
'cclid' => '7115744',
'lyricParts' => [
['key' => 'v1', 'text' => 'Du bist hier'],
],
],
],
];
$mockClient = new CtsApiSpikeMockClient([
'/api/events' => [new Response(200, [], json_encode($eventsPayload, JSON_THROW_ON_ERROR))],
'/api/songs/1' => [new Response(200, [], json_encode($songPayload, JSON_THROW_ON_ERROR))],
]);
$result = \App\Cts\CtsApiSpikeSync::run(
apiUrl: 'https://example.church.tools',
apiToken: 'token-abc',
fromDate: '2026-03-01',
songId: 1,
client: $mockClient,
);
expect($result['events']['count'])->toBe(1)
->and($result['events']['first']['title'])->toBe('Gottesdienst Sonntag')
->and($result['song']['hasCcli'])->toBeTrue()
->and($result['song']['hasLyrics'])->toBeTrue()
->and($result['song']['arrangements_count'])->toBe(1)
->and($result['auth']['method'])->toBe('setApiKey');
$eventsCall = $mockClient->firstCallFor('GET', '/api/events');
expect($eventsCall['options']['query']['from'])->toBe('2026-03-01')
->and($eventsCall['options']['query']['page'])->toBe(1)
->and(CTConfig::getRequestConfig()['query']['login_token'])->toBe('token-abc');
});
it('returns auth blocker when API token is missing', function () {
$result = \App\Cts\CtsApiSpikeSync::run(
apiUrl: 'https://example.church.tools',
apiToken: '',
fromDate: '2026-03-01',
songId: 1,
client: new CtsApiSpikeMockClient([]),
);
expect($result['auth']['ok'])->toBeFalse()
->and($result['auth']['blocker'])->toContain('CTS_API_TOKEN');
});
final class CtsApiSpikeMockClient extends CTClient
{
private array $responsesByUri;
private array $calls = [];
public function __construct(array $responsesByUri)
{
$this->responsesByUri = $responsesByUri;
}
public function get($uri, array $options = []): ResponseInterface
{
$this->calls[] = [
'method' => 'GET',
'uri' => $uri,
'options' => $options,
];
if (! isset($this->responsesByUri[$uri]) || $this->responsesByUri[$uri] === []) {
return new Response(404, [], json_encode(['data' => []], JSON_THROW_ON_ERROR));
}
return array_shift($this->responsesByUri[$uri]);
}
public function firstCallFor(string $method, string $uri): array
{
foreach ($this->calls as $call) {
if ($call['method'] === $method && $call['uri'] === $uri) {
return $call;
}
}
throw new RuntimeException("No call recorded for {$method} {$uri}");
}
}