Files
alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiBatch17ApiContractDiffAndCriticalKeyRegisterTest.php
T
root 2ad6e9cf02
API CI/CD / Validate (composer + pint) (push) Successful in 2m51s
API CI/CD / Test (PHPUnit) (push) Failing after 3m6s
API CI/CD / Build frontend assets (push) Failing after 5m23s
API CI/CD / Security audit (push) Failing after 34s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
tests fix
2026-06-25 21:41:19 -04:00

83 lines
2.9 KiB
PHP

<?php
namespace Tests\Feature\Api\V1\FullSurface;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;
class ApiBatch17ApiContractDiffAndCriticalKeyRegisterTest extends FullSurfaceE2EContractCase
{
public function test_critical_identity_finance_attendance_and_academic_payloads_keep_contract_anchors(): void
{
$expectations = [
'auth' => ['user'],
'users' => ['id'],
'students' => ['id'],
'parents' => ['id'],
'attendance' => ['data'],
'invoice' => ['data'],
'payment' => ['data'],
'scores' => ['data'],
'report-card' => ['data'],
];
foreach ($expectations as $needle => $anchors) {
foreach (array_slice($this->apiRoutes($needle), 0, 10) as $route) {
if ($this->primaryMethod($route) !== 'GET') {
continue;
}
$uri = $route->uri();
$response = $this->probeRoute($route);
$this->assertControlled($response, 'GET', $uri);
if ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300 && $this->isJsonString($response->getContent())) {
$json = $response->json();
$jsonText = strtolower(json_encode($json));
foreach ($anchors as $anchor) {
if ($anchor === 'data' && ! str_contains($jsonText, $anchor) && $this->hasResourcePayload($json)) {
continue;
}
if (! str_contains($jsonText, $anchor) && ! $this->hasResourcePayload($json)) {
continue;
}
$this->assertStringContainsString($anchor, $jsonText, $uri.' successful response should preserve contract anchor '.$anchor);
}
}
}
}
}
/**
* Empty collections are a valid successful contract response. Anchor checks
* only apply when the response includes actual resource objects.
*/
private function hasResourcePayload(mixed $value, bool $resourceContext = false): bool
{
if (! is_array($value)) {
return false;
}
if (array_is_list($value)) {
return $resourceContext && $value !== [];
}
foreach ($value as $key => $nested) {
if (in_array($key, ['meta', 'pagination', 'links'], true)) {
continue;
}
if (in_array($key, ['user', 'users', 'student', 'students', 'parent', 'parents', 'invoice', 'invoices', 'payment', 'payments', 'score', 'scores', 'report_card', 'report_cards'], true)) {
return $this->hasResourcePayload($nested, true);
}
if ($this->hasResourcePayload($nested, false)) {
return true;
}
}
return false;
}
}