Files
Wegwichtel/test/presentation-route.test.js
Florian Zumpe 497b7b8050
Sonarqube Scanner / Prepare environment (push) Successful in 11s
Sonarqube Scanner / Build and test (push) Successful in 29s
Sonarqube Scanner / SonarQube analysis (push) Successful in 1m25s
Sonarqube Scanner / Deploy to Server (push) Successful in 7s
directory cleanup for tests
2026-10-04 08:12:08 +02:00

86 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
import test from 'node:test';
import { SAMPLE_GPX } from '../test-support/gpx-fixtures.js';
const script = path.resolve(import.meta.dirname, '../scripts/upload-presentation-route.sh');
async function uploadFixture(t) {
const runtime = await fs.mkdtemp(path.join(os.tmpdir(), 'wegwichtel-presentation-'));
t.after(() => fs.rm(runtime, { recursive: true, force: true }));
const bin = path.join(runtime, 'bin');
await fs.mkdir(bin);
const gpxPath = path.join(runtime, 'track.gpx');
const jsonPath = path.join(runtime, 'stations.json');
const logPath = path.join(runtime, 'requests.jsonl');
const metadata = {
name: 'Testweg', description: 'Synthetic upload data',
pois: [
{ title: 'Start', description: 'First station', lat: 52.5200, lon: 13.4050, triggerRadiusM: 25, sequence: 0 },
{ title: 'Ende', description: 'Last station', lat: 52.5216, lon: 13.4090, triggerRadiusM: 30, sequence: 1 }
]
};
await fs.writeFile(gpxPath, SAMPLE_GPX);
await fs.writeFile(jsonPath, JSON.stringify(metadata));
// Capture curl arguments locally. No requests are sent to a real server.
await fs.writeFile(path.join(bin, 'curl'), `#!/usr/bin/env python3
import json, os, sys
from pathlib import Path
log = Path(os.environ['TEST_REQUEST_LOG'])
count = len(log.read_text().splitlines()) if log.exists() else 0
with log.open('a') as output:
output.write(json.dumps(sys.argv[1:]) + '\\n')
if os.environ.get('TEST_FAIL_POI') == '1' and count == 1:
sys.exit(22)
print(json.dumps({'id': 101}))
`, { mode: 0o755 });
return {
gpxPath, jsonPath, logPath, metadata,
env: { ...process.env, PATH: `${bin}${path.delimiter}${process.env.PATH}`, TEST_REQUEST_LOG: logPath }
};
}
test('presentation uploader accepts explicit test files and posts route and stations through the API', async t => {
const fixture = await uploadFixture(t);
const result = spawnSync('bash', [script, 'https://example.invalid/api', fixture.gpxPath, fixture.jsonPath], {
env: fixture.env, encoding: 'utf8', timeout: 10000
});
assert.equal(result.status, 0, result.stderr);
const requests = (await fs.readFile(fixture.logPath, 'utf8')).trim().split('\n').map(line => JSON.parse(line));
assert.equal(requests.length, 3);
assert.ok(requests[0].includes('https://example.invalid/api/routes'));
assert.ok(requests[0].includes(`gpx=@${fixture.gpxPath};type=application/gpx+xml`));
for (const [index, poi] of fixture.metadata.pois.entries()) {
assert.ok(requests[index + 1].includes('https://example.invalid/api/routes/101/pois'));
assert.ok(requests[index + 1].includes(`title=${poi.title}`));
assert.ok(requests[index + 1].includes(`sequence=${poi.sequence}`));
assert.ok(requests[index + 1].includes('POST'));
}
assert.match(result.stdout, /Server-ID: 101/);
});
test('presentation uploader reports missing files before any HTTP request', async t => {
const fixture = await uploadFixture(t);
for (const args of [[], ['https://example.invalid/api', fixture.gpxPath, `${fixture.jsonPath}.missing`]]) {
const result = spawnSync('bash', [script, ...args], { env: fixture.env, encoding: 'utf8', timeout: 10000 });
assert.equal(result.status, 2);
assert.match(result.stderr, /Aufruf:/);
}
await assert.rejects(fs.access(fixture.logPath), { code: 'ENOENT' });
});
test('presentation uploader removes an incomplete route if a station upload fails', async t => {
const fixture = await uploadFixture(t);
const result = spawnSync('bash', [script, 'https://example.invalid/api', fixture.gpxPath, fixture.jsonPath], {
env: { ...fixture.env, TEST_FAIL_POI: '1' }, encoding: 'utf8', timeout: 10000
});
assert.notEqual(result.status, 0);
const requests = (await fs.readFile(fixture.logPath, 'utf8')).trim().split('\n').map(line => JSON.parse(line));
assert.equal(requests.length, 3);
assert.ok(requests[2].includes('DELETE'));
assert.ok(requests[2].includes('https://example.invalid/api/routes/101'));
});