Update über den Git-Server, Tests, Repo ohne node_modules und Sicherungen
- Admin → Update: neuere Versionen (Tags) vom Git-Server anzeigen und per Knopf einspielen; ausgeführt vom Dienst auf dem Rechner (Docker/update-einrichten.sh, Docker/update-ausfuehren.sh), nur vorwärts, Fehler bei ausbleibendem Neustart, abgebrochene Läufe sperren nicht - Tests (npm test): Zusammenführen paralleler Änderungen, Rechteprüfung beim Speichern; SESSIONS_DIR lenkt den Datenordner für Testserver um - node_modules, Sicherungen und Uploads aus dem Repo genommen - cors und requireRole() entfernt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e12936444d
commit
fd44db2213
2357 files changed
+588
-514948
No files matched your search
@@ -0,0 +1,87 @@
|
||||
// Test: Rechteprüfung beim Speichern (fehlendesBearbeitungsrecht() in
|
||||
// server.js). Startet einen echten Server mit leerer Datenbank in einem
|
||||
// Wegwerf-Ordner (SESSIONS_DIR/DB_PATH), legt eine Rolle nur mit „Kommentar
|
||||
// und Fortschritt“ an und prüft über POST /save-projects, was ein Konto mit
|
||||
// dieser Rolle ändern darf. Aufruf: npm test
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
const ordner = fs.mkdtempSync(path.join(os.tmpdir(), 'projektuebersicht-test-'));
|
||||
const PORT = 3990 + Math.floor(Math.random() * 9);
|
||||
const url = p => 'http://127.0.0.1:' + PORT + p;
|
||||
let server;
|
||||
|
||||
async function anfrage(methode, pfad, cookie, body){
|
||||
const r = await fetch(url(pfad), {
|
||||
method: methode,
|
||||
headers: Object.assign({ 'Content-Type': 'application/json' }, cookie ? { Cookie: cookie } : {}),
|
||||
body: body === undefined ? undefined : JSON.stringify(body)
|
||||
});
|
||||
return { status: r.status, daten: await r.json().catch(() => null), cookie: (r.headers.get('set-cookie') || '').split(';')[0] };
|
||||
}
|
||||
async function anmelden(username, password){
|
||||
const r = await anfrage('POST', '/login', null, { username, password });
|
||||
assert.strictEqual(r.status, 200, 'Anmeldung ' + username + ': ' + JSON.stringify(r.daten));
|
||||
return r.cookie;
|
||||
}
|
||||
|
||||
test.before(async () => {
|
||||
server = spawn(process.execPath, [path.join(__dirname, '../server.js')], {
|
||||
env: Object.assign({}, process.env, { PORT: String(PORT), SESSIONS_DIR: ordner, DB_PATH: path.join(ordner, 'test.db'),
|
||||
SPEICHER_MAX_MB: '', HAENGER_MAX_S: '' }),
|
||||
stdio: 'ignore'
|
||||
});
|
||||
for(let i = 0; i < 50; i++){
|
||||
try { if((await fetch(url('/health'))).ok) return; } catch(e){ /* startet noch */ }
|
||||
await new Promise(r => setTimeout(r, 200));
|
||||
}
|
||||
throw new Error('Testserver startet nicht');
|
||||
});
|
||||
test.after(() => { if(server) server.kill(); fs.rmSync(ordner, { recursive: true, force: true }); });
|
||||
|
||||
test('Konto nur mit Kommentar-Recht: Kommentar ja, Terminplan nein', async () => {
|
||||
const pw = /Passwort:\s+(\S+)/.exec(fs.readFileSync(path.join(ordner, 'INITIAL_ADMIN_PASSWORD.txt'), 'utf8'))[1];
|
||||
const admin = await anmelden('admin', pw);
|
||||
|
||||
// Rolle mit „Anwendung nutzen“ und „Kommentar und Fortschritt“, sonst nichts.
|
||||
const rolle = await anfrage('POST', '/rollen', admin, { name: 'Nur Kommentar' });
|
||||
assert.strictEqual(rolle.status, 200, JSON.stringify(rolle.daten));
|
||||
const key = rolle.daten.neu;
|
||||
assert.strictEqual((await anfrage('PUT', '/rollen/' + key + '/rechte', admin, { rechte: ['app', 'wb.kommentar'], an: true })).status, 200);
|
||||
const konto = await anfrage('POST', '/admin/users', admin, { username: 'leser', firstName: 'Lea', lastName: 'Leser',
|
||||
role: key, department: 'ELT', password: 'geheim-1234' });
|
||||
assert.strictEqual(konto.status, 200, JSON.stringify(konto.daten));
|
||||
|
||||
// Ein Projekt in der aktuellen Sitzung anlegen (als Administrator).
|
||||
const geladen = (await anfrage('GET', '/load-all', admin)).daten;
|
||||
const woche = geladen.weeks[geladen.weeks.length - 1];
|
||||
woche.projects.push({ id: 'p1', projectUid: 'u1', nr: '99-0001', name: 'Testprojekt', group: 'Aktive Projekte',
|
||||
gewerke: ['ELT'], plan: { todos: [] } });
|
||||
const angelegt = await anfrage('POST', '/save-week', admin, { week: woche, baseUpdatedAt: woche.updatedAt });
|
||||
assert.strictEqual(angelegt.status, 200, JSON.stringify(angelegt.daten));
|
||||
|
||||
const leser = await anmelden('leser', 'geheim-1234');
|
||||
const projekt = () => anfrage('GET', '/load-all', leser).then(r => {
|
||||
const w = r.daten.weeks[r.daten.weeks.length - 1];
|
||||
return { label: w.label, p: w.projects.find(x => x.id === 'p1') };
|
||||
});
|
||||
|
||||
// Aufgabe im Terminplan anlegen: braucht „Terminplan bearbeiten“.
|
||||
let { label, p } = await projekt();
|
||||
const base = p.updatedAt;
|
||||
p.plan.todos.push({ id: 't1', title: 'Darf nicht gespeichert werden', start: '', end: '', assignees: [], dependsOn: [] });
|
||||
const verboten = await anfrage('POST', '/save-projects', leser, { label, projects: [{ project: p, baseUpdatedAt: base }] });
|
||||
assert.strictEqual(verboten.status, 403);
|
||||
assert.strictEqual(verboten.daten.recht, 'proj.plan');
|
||||
|
||||
// Kommentar des Gewerks schreiben: erlaubt.
|
||||
({ label, p } = await projekt());
|
||||
assert.strictEqual(p.plan.todos.length, 0, 'die verbotene Aufgabe darf nicht gespeichert sein');
|
||||
p.kommentare = { ELT: { status: 'Abstimmung mit TGA steht aus', statusAuthor: 'Lea Leser', statusAt: new Date().toISOString(), besprochen: false } };
|
||||
const erlaubt = await anfrage('POST', '/save-projects', leser, { label, projects: [{ project: p, baseUpdatedAt: p.updatedAt }] });
|
||||
assert.strictEqual(erlaubt.status, 200, JSON.stringify(erlaubt.daten));
|
||||
});
|
||||
Reference in new issue
Block a user