Files
sternwarte/sternwarte/tests/integration_api.test.js
rxf 3e8b1f9691 DB4js als _all zusammengefasst
Beoanswer ist nun OK
2025-11-17 14:22:52 +01:00

152 lines
5.2 KiB
JavaScript

#!/usr/bin/env node
/*
Integration smoke tests for DB4js_all.php
- Uses HTTPS POST JSON to remote API (or custom API_URL)
- No external deps (Node core only)
Env:
- API_URL (default: https://sternwarte-welzheim.de/DB4js_all.php)
- API_USER / API_PASS (optional Basic Auth)
*/
const https = require('https');
const http = require('http');
const { URL } = require('url');
const API_URL = process.env.API_URL || 'https://sternwarte-welzheim.de/DB4js_all.php';
const API_USER = process.env.API_USER || '';
const API_PASS = process.env.API_PASS || '';
function postJSON(urlStr, bodyObj) {
return new Promise((resolve, reject) => {
const url = new URL(urlStr);
const body = JSON.stringify(bodyObj || {});
const isHttps = url.protocol === 'https:';
const lib = isHttps ? https : http;
const headers = {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body)
};
if (API_USER && API_PASS) {
const token = Buffer.from(`${API_USER}:${API_PASS}`).toString('base64');
headers['Authorization'] = `Basic ${token}`;
}
const req = lib.request({
method: 'POST',
hostname: url.hostname,
port: url.port || (isHttps ? 443 : 80),
path: url.pathname + url.search,
headers,
rejectUnauthorized: false, // allow self-signed (if any)
timeout: 15000,
}, (res) => {
let data = '';
res.setEncoding('utf8');
res.on('data', c => data += c);
res.on('end', () => {
let json = null;
try { json = JSON.parse(data); } catch (e) {}
if (res.statusCode >= 400) {
return reject(new Error(`HTTP ${res.statusCode}: ${data}`));
}
if (!json) return reject(new Error(`Non-JSON response: ${data}`));
resolve(json);
});
});
req.on('error', reject);
req.on('timeout', () => { req.destroy(new Error('Request timeout')); });
req.write(body);
req.end();
});
}
function assert(cond, msg) {
if (!cond) throw new Error(msg);
}
(async () => {
const failures = [];
let step = 0;
function record(name, fn) {
return Promise.resolve()
.then(fn)
.then(() => console.log(`${++step}. ${name}`))
.catch((err) => { failures.push({ name, err }); console.error(`${++step}. ${name} ->`, err.message); });
}
console.log(`API_URL=${API_URL}`);
await record('PING returns pong + timestamp', async () => {
const r = await postJSON(API_URL, { cmd: 'PING' });
assert(r && r.pong === true, 'pong !== true');
assert(typeof r.timestamp === 'string' && r.timestamp.length > 0, 'timestamp missing');
});
await record('LIST_COMMANDS returns command map', async () => {
const r = await postJSON(API_URL, { cmd: 'LIST_COMMANDS' });
assert(r && r.commands && typeof r.count === 'number', 'invalid LIST_COMMANDS payload');
});
await record('GET_BEOS with alias email works', async () => {
const r = await postJSON(API_URL, { cmd: 'GET_BEOS', onlyguides: true, what: 'id,name,email' });
assert(Array.isArray(r), 'GET_BEOS did not return array');
if (r.length > 0) {
const it = r[0];
assert('id' in it, 'beo item missing id');
assert('name' in it, 'beo item missing name');
assert(('email' in it) || ('email_1' in it), 'beo item missing email/email_1');
}
});
await record('GET_BEOS with non-existing field falls back', async () => {
const r = await postJSON(API_URL, { cmd: 'GET_BEOS', onlyguides: 'true', what: 'id,name,doesnotexist' });
assert(Array.isArray(r), 'GET_BEOS did not return array on fallback');
});
let sampleDate = null;
await record('GET_TERMINE returns array', async () => {
const r = await postJSON(API_URL, { cmd: 'GET_TERMINE' });
assert(Array.isArray(r), 'GET_TERMINE did not return array');
if (r.length > 0) {
// pick first with possible datum field
const d = r.find(x => typeof x.datum === 'string');
if (d) sampleDate = d.datum;
}
});
if (sampleDate) {
await record('GET_TIME for sample date', async () => {
const r = await postJSON(API_URL, { cmd: 'GET_TIME', date: sampleDate });
assert(r && typeof r.time === 'string', 'GET_TIME missing time');
});
let sampleFid = null;
await record('GET_FID for sample date', async () => {
const r = await postJSON(API_URL, { cmd: 'GET_FID', datum: sampleDate });
assert(r && ('fid' in r), 'GET_FID missing fid');
sampleFid = r.fid;
});
await record('GET_COUNTS_DATE for sample date', async () => {
const r = await postJSON(API_URL, { cmd: 'GET_COUNTS_DATE', date: sampleDate });
assert(r && typeof r.count === 'number', 'GET_COUNTS_DATE invalid');
});
if (sampleFid) {
await record('GET_COUNTS for sample fid', async () => {
const r = await postJSON(API_URL, { cmd: 'GET_COUNTS', fid: sampleFid });
assert(r && typeof r.count === 'number', 'GET_COUNTS invalid');
});
}
}
if (failures.length) {
console.error(`\n${failures.length} test(s) failed:`);
failures.forEach((f, i) => console.error(` ${i + 1}) ${f.name}: ${f.err && f.err.stack || f.err}`));
process.exit(1);
} else {
console.log('\nAll integration tests passed.');
}
})().catch((e) => { console.error('Fatal error:', e); process.exit(1); });