Files
alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiContractSnapshotSeedTest.php
T
2026-06-11 11:46:12 -04:00

60 lines
3.3 KiB
PHP

<?php
namespace Tests\Feature\Api\V1\FullSurface;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;
class ApiContractSnapshotSeedTest extends FullSurfaceE2EContractCase
{
public function test_core_success_payloads_keep_contract_keys_when_available(): void
{
foreach ($this->contractSamples() as $label => $sample) {
$response = $this->requestAs($sample['actor'], $sample['method'], $sample['path'], $sample['payload'] ?? []);
$this->assertStatusIn($response, [200, 201, 202, 204, 302, 400, 401, 403, 404, 405, 409, 419, 422], $label);
$this->assertNoServerError($response, $label);
if (in_array($response->getStatusCode(), [200, 201, 202], true) && $response->getContent() !== '' && $this->isJsonString($response->getContent())) {
$flat = json_encode($response->json(), JSON_THROW_ON_ERROR);
foreach ($sample['expected_any'] as $key) {
if (str_contains($flat, $key)) {
$this->assertTrue(true);
continue 2;
}
}
$this->fail($label.' did not expose any expected contract key: '.implode(', ', $sample['expected_any']));
}
}
}
public function test_auth_identity_payload_never_drops_user_identity_when_successful(): void
{
$response = $this->requestAs($this->admin, 'GET', 'api/v1/auth/me');
$this->assertStatusIn($response, [200, 204, 302, 401, 403, 404, 405, 419, 422], 'GET api/v1/auth/me');
$this->assertNoServerError($response, 'GET api/v1/auth/me');
if ($response->getStatusCode() === 200 && $this->isJsonString($response->getContent())) {
$flat = json_encode($response->json(), JSON_THROW_ON_ERROR);
$this->assertStringContainsString('email', $flat, 'auth/me successful payload should expose identity email.');
$this->assertStringContainsString('id', $flat, 'auth/me successful payload should expose identity id.');
}
}
/** @return array<string,array{actor:mixed,method:string,path:string,payload?:array<string,mixed>,expected_any:list<string>}> */
private function contractSamples(): array
{
return [
'users index contract' => ['actor' => $this->admin, 'method' => 'GET', 'path' => 'api/v1/users', 'expected_any' => ['data', 'users', 'id', 'email']],
'students index contract' => ['actor' => $this->admin, 'method' => 'GET', 'path' => 'api/v1/students', 'expected_any' => ['data', 'students', 'student_id', 'firstname']],
'parent profile contract' => ['actor' => $this->parent, 'method' => 'GET', 'path' => 'api/v1/parents/profile', 'expected_any' => ['user', 'parent', 'email', 'firstname']],
'teacher classes contract' => ['actor' => $this->teacher, 'method' => 'GET', 'path' => 'api/v1/teacher/classes', 'expected_any' => ['classes', 'class_section_id', 'data']],
'finance invoices contract' => ['actor' => $this->admin, 'method' => 'GET', 'path' => 'api/v1/finance/invoices', 'expected_any' => ['invoice', 'amount', 'data', 'parent_id']],
'inventory items contract' => ['actor' => $this->admin, 'method' => 'GET', 'path' => 'api/v1/inventory/items', 'expected_any' => ['item', 'quantity', 'data', 'name']],
];
}
}