Files
alrahma_sunday_school_api/tests/Feature/Api/V1/FullSurface/ApiConcurrencyAndStaleWriteContractTest.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

50 lines
2.2 KiB
PHP

<?php
namespace Tests\Feature\Api\V1\FullSurface;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;
class ApiConcurrencyAndStaleWriteContractTest extends FullSurfaceE2EContractCase
{
public function test_duplicate_update_payloads_remain_controlled_and_do_not_throw_server_errors(): void
{
foreach ($this->apiRoutesContainingAny(['profile', 'settings', 'attendance', 'inventory', 'payments', 'refunds', 'school-years', 'messages']) as $route) {
$method = $this->primaryMethod($route);
if (! in_array($method, ['PUT', 'PATCH', 'POST'], true)) {
continue;
}
$payload = $this->payloadFor($method, $route->uri()) + [
'client_request_id' => 'e2e-concurrency-'.md5($route->uri()),
'updated_at' => '2000-01-01T00:00:00Z',
];
$first = $this->requestAs($this->actorFor($route->uri()), $method, $route->uri(), $payload);
$second = $this->requestAs($this->actorFor($route->uri()), $method, $route->uri(), $payload);
$this->assertControlled($first, $method, $route->uri());
$this->assertControlled($second, $method, $route->uri());
$this->assertStringNotContainsString('deadlock', strtolower($second->getContent()));
$this->assertStringNotContainsString('duplicate entry', strtolower($second->getContent()));
}
}
public function test_stale_if_match_headers_do_not_force_successful_mutations(): void
{
foreach ($this->apiRoutesContainingAny(['students', 'parents', 'inventory', 'payments', 'attendance', 'settings']) as $route) {
$method = $this->primaryMethod($route);
if (! in_array($method, ['PUT', 'PATCH', 'DELETE'], true)) {
continue;
}
$response = $this->actingAs($this->actorFor($route->uri()), 'api')
->withHeader('If-Match', '"stale-version-that-should-not-win"')
->json($method, $this->materializePath($route->uri()), $this->payloadFor($method, $route->uri()));
$this->assertStatusIn($response, [200, 202, 204, 400, 401, 403, 404, 409, 412, 419, 422], "{$method} {$route->uri()} stale write");
}
}
}