Files
Aggregator/Tests/api_tests.mjs
Semen_Babenishev 4420c5c60a Initial: Nutshell Site Aggregator MVP Phase 1
- Backend: Express + TypeORM + PostgreSQL, JWT + OTP auth
- Frontend: React + Vite + Tailwind, 4 pages (Home/Login/Orders/404)
- Docker Compose: PostgreSQL 15 on port 5434
- Tests: 16 tests passing (API + Frontend)
- ai_state: rules.md, INSTRUCTIONS.md, session tasks
- Examples: brand book PDF, logos, page mockups
2026-07-16 11:38:08 +04:00

108 lines
4.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Tests/api_tests.mjs
// Тесты backend API — запускаются через: node Tests/api_tests.mjs
// Требует: запущенный backend (npm run dev в backend/) и PostgreSQL
const API = 'http://localhost:3001/api';
let passed = 0;
let failed = 0;
async function test(name, fn) {
try {
await fn();
console.log(` ✅ PASS: ${name}`);
passed++;
} catch (err) {
console.log(` ❌ FAIL: ${name}`);
console.log(` ${err.message}`);
failed++;
}
}
function assert(condition, message) {
if (!condition) throw new Error(message || 'Assertion failed');
}
async function fetchJSON(url, options = {}) {
const res = await fetch(url, {
headers: { 'Content-Type': 'application/json', ...options.headers },
...options,
body: options.body ? JSON.stringify(options.body) : undefined,
});
const data = await res.json();
return { status: res.status, data };
}
// ─── Группа 1: Health Check ────────────────────────────────────────────────
console.log('\n🔍 Группа 1: Health Check');
await test('GET /api/health возвращает 200', async () => {
const { status, data } = await fetchJSON(`${API}/health`);
assert(status === 200, `Ожидался 200, получен ${status}`);
assert(data.success === true, 'success !== true');
assert(data.data.status === 'ok', `status !== 'ok'`);
});
// ─── Группа 2: Auth — request-otp ──────────────────────────────────────────
console.log('\n🔍 Группа 2: Auth — request-otp');
// Уникальный номер на каждый запуск — обходим rate-limit (5 минут)
const testPhone = `+7900${Date.now().toString().slice(-7)}`;
await test('POST /api/auth/request-otp с телефоном возвращает success', async () => {
const { status, data } = await fetchJSON(`${API}/auth/request-otp`, {
method: 'POST',
body: { phone: testPhone },
});
assert(status === 200, `Ожидался 200, получен ${status}`);
assert(data.success === true, `success=false, errors: ${JSON.stringify(data.errors)}`);
});
await test('POST /api/auth/request-otp без телефона возвращает 400', async () => {
const { status, data } = await fetchJSON(`${API}/auth/request-otp`, {
method: 'POST',
body: {},
});
assert(status === 400, `Ожидался 400, получен ${status}`);
assert(data.success === false, 'success должен быть false для невалидных данных');
});
// ─── Группа 3: Auth — verify-otp ───────────────────────────────────────────
console.log('\n🔍 Группа 3: Auth — verify-otp');
await test('POST /api/auth/verify-otp с неверным кодом возвращает ошибку', async () => {
const { status, data } = await fetchJSON(`${API}/auth/verify-otp`, {
method: 'POST',
body: { phone: testPhone, otp: '000000' },
});
// Неверный код: сервер должен вернуть 400 или 200 с success=false
assert(data.success === false, `Ожидался success=false для неверного OTP`);
});
await test('POST /api/auth/verify-otp без otp возвращает 400', async () => {
const { status, data } = await fetchJSON(`${API}/auth/verify-otp`, {
method: 'POST',
body: { phone: testPhone },
});
assert(status === 400, `Ожидался 400, получен ${status}`);
});
// ─── Группа 4: Защищённые маршруты ─────────────────────────────────────────
console.log('\n🔍 Группа 4: Защищённые маршруты (без токена)');
await test('Запрос к несуществующему API маршруту возвращает 404', async () => {
const res = await fetch(`${API}/nonexistent`);
assert(res.status === 404, `Ожидался 404, получен ${res.status}`);
const data = await res.json();
assert(data.success === false, 'success должен быть false для 404');
});
// ─── Итог ──────────────────────────────────────────────────────────────────
console.log(`\n${'─'.repeat(50)}`);
console.log(`Итог: ${passed} прошло, ${failed} провалено`);
if (failed > 0) {
console.log('⚠️ Есть проваленные тесты');
process.exit(1);
} else {
console.log('✅ Все тесты прошли успешно');
}