Auto-formatted by Laravel Pint (default Laravel preset): string concatenation spacing, anonymous class brace placement, constructor body shorthand, import ordering, and assertion indentation.
120 lines
3.6 KiB
PHP
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}");
|
|
}
|
|
}
|