152 lines
5.2 KiB
JavaScript
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); });
|