validate live API response contracts

This commit is contained in:
2026-09-06 19:23:59 +03:00
parent fa3fdf0fee
commit cc3c3ad73d
3 changed files with 34 additions and 9 deletions
+13 -6
View File
@@ -8,15 +8,22 @@ const timeoutMs = 15_000;
const requiredHeaders = ['x-content-type-options', 'referrer-policy', 'permissions-policy'];
const checks = {};
async function probe(path) {
async function probe(path, successField = null) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(base + path, { signal: controller.signal, redirect: 'manual' });
return {
const result = {
status: response.status,
contentType: response.headers.get('content-type'),
headers: Object.fromEntries(requiredHeaders.map(name => [name, response.headers.get(name)])),
};
if (successField) {
const raw = await response.text();
try { result.json = JSON.parse(raw); } catch { result.jsonError = 'JSON yanıtı ayrıştırılamadı.'; }
result.apiSuccess = result.json?.[successField] === true;
}
return result;
} catch (error) {
return { error: error.name === 'AbortError' ? `timeout after ${timeoutMs}ms` : error.message };
} finally {
@@ -25,15 +32,15 @@ async function probe(path) {
}
checks.home = await probe('/');
checks.health = await probe('/api/health');
checks.ready = await probe('/api/ready');
const missingHeaders = requiredHeaders.filter(name => checks.home?.headers?.[name] == null || checks.health?.headers?.[name] == null);
checks.health = await probe('/api/health', 'ok');
checks.ready = await probe('/api/ready', 'success');
const missingHeaders = requiredHeaders.filter(name => [checks.home, checks.health, checks.ready].some(check => check?.headers?.[name] == null));
const report = {
base,
readOnly: true,
checkedAt: new Date().toISOString(),
checks,
pass: checks.home?.status === 200 && checks.health?.status === 200 && checks.ready?.status === 200 && missingHeaders.length === 0,
pass: checks.home?.status === 200 && checks.health?.status === 200 && checks.health.apiSuccess === true && checks.ready?.status === 200 && checks.ready.apiSuccess === true && missingHeaders.length === 0,
missingHeaders,
};