directory cleanup for tests
This commit is contained in:
@@ -1,23 +1,85 @@
|
||||
import { readAppFile } from '../test-support/i18n.js';
|
||||
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 root = path.resolve(import.meta.dirname, '..');
|
||||
const script = path.resolve(import.meta.dirname, '../scripts/upload-presentation-route.sh');
|
||||
|
||||
async function read(relativePath) {
|
||||
return readAppFile(relativePath);
|
||||
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 example uses real GPX Streckenpunkte and the existing upload API', async () => {
|
||||
const gpx = await read('examples/presentation-route.gpx');
|
||||
const metadata = JSON.parse(await read('examples/presentation-route.json'));
|
||||
const script = await read('scripts/upload-presentation-route.sh');
|
||||
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/);
|
||||
});
|
||||
|
||||
assert.ok((gpx.match(/<trkpt\b/g) || []).length >= 8);
|
||||
assert.doesNotMatch(gpx, /<rtept\b/);
|
||||
assert.ok(metadata.pois.length >= 3);
|
||||
assert.match(script, /POST "\$BASE_URL\/routes"/);
|
||||
assert.match(script, /POST "\$BASE_URL\/routes\/\$ROUTE_ID\/pois"/);
|
||||
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'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user