Files
AgrarmonitorConnector/test/eingangsrechnung-edit.test.js
bjoernpoettkerandClaude Opus 5.5 e6ce1d254b Eingangsrechnungen: disabled-Felder an update.php mitschicken
Bei gebuchten Rechnungen liefert editForm.php alle Felder disabled.
serializeForm hat sie uebersprungen, update.php antwortete dann mit
HTTP 422 (typ, mengenUndPreisAnpassung, firma_id, Adressfelder
"must be present"). Die Felder werden jetzt mit ihren Werten
uebernommen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 15:55:19 +02:00

212 lines
7.5 KiB
JavaScript

const assert = require('node:assert/strict');
const http = require('node:http');
const test = require('node:test');
const { AgrarmonitorConnector, MemoryCookieStore } = require('../dist');
// Gekuerzter Formularausschnitt, wie ihn editForm.php liefert.
const editForm = `
<form id="rechnung-detail">
<select name="typ" id="typ">
<option value="0" selected>Eingangsrechnung</option>
<option value="1">Gutschrift</option>
</select>
<select name="mengenUndPreisAnpassung">
<option value="0" selected>Preise und Mengen beibehalten</option>
<option value="1">Anpassen</option>
</select>
<input type="text" name="lieferscheinnummer" value="">
<input type="text" name="rechnungsnummer" id="rechnungsnummer" value="5355771416">
<input type="text" name="rechnungsdatum" value="19.08.26">
<select name="firma_id">
<option value="1">Andere GmbH</option>
<option value="3" selected>Poettker GmbH</option>
</select>
<select name="rgempf">
<option value="34079" selected>15550519 TUEV NORD Mobilitaet</option>
</select>
<input name="addressName" value="TUEV NORD Mobilitaet GmbH &amp; Co. KG">
<input name="additionalAddressLineOne" value="">
<input name="additionalAddressLineTwo" value="">
<input name="addressStreet" value="Postfach 810551">
<input name="addressPostalcode" value="30505">
<input name="addressCity" value="Hannover">
<select name="addressCountryISO3166">
<option value="DE" selected>Deutschland</option>
</select>
<textarea name="notiz">Zeile 1</textarea>
<button type="submit" name="speichern">Speichern</button>
</form>
<script>admin.Eingangsrechnungen.editRechnung(388444);</script>
`;
// Gebuchte Rechnung: editForm.php liefert alle Felder mit disabled.
const editFormGebucht = editForm.replace(/<(input|select|textarea)(?=[\s>])/g, '<$1 disabled');
function createServer({ updateResponse = [], updateStatus = 200 } = {}) {
const requests = [];
const server = http.createServer((req, res) => {
let body = '';
req.on('data', chunk => {
body += chunk;
});
req.on('end', () => {
requests.push({ method: req.method, url: req.url, headers: req.headers, body });
if (req.method === 'POST' && req.url === '/login/api/login.php') {
res.writeHead(200, {
'Content-Type': 'application/json',
'Set-Cookie': 'agrar_session=test; Path=/',
});
res.end(JSON.stringify({ success: true }));
return;
}
if (req.method === 'GET' && req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<html><body>Mein AM</body></html>');
return;
}
if (req.method === 'GET' && req.url === '/module/eingangsrechnungen/api/editForm.php?invoiceID=388444') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(editForm);
return;
}
if (req.method === 'GET' && req.url === '/module/eingangsrechnungen/api/editForm.php?invoiceID=387644') {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(editFormGebucht);
return;
}
if (req.method === 'POST' && req.url === '/module/eingangsrechnungen/api/update.php') {
res.writeHead(updateStatus, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(updateResponse));
return;
}
res.writeHead(404);
res.end('not found');
});
});
return { server, requests };
}
async function startConnector(t, options) {
const { server, requests } = createServer(options);
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
t.after(() => new Promise(resolve => server.close(resolve)));
const connector = new AgrarmonitorConnector({
baseUrl: `http://127.0.0.1:${server.address().port}`,
username: 'demo',
password: 'secret',
cookieStore: new MemoryCookieStore(),
});
await connector.init();
return { connector, requests };
}
test('getRechnungsdaten liest das Formular aus editForm.php', async t => {
const { connector } = await startConnector(t);
const daten = await connector.getRechnungsdaten(388444);
assert.equal(daten.lieferschein, '');
assert.equal(daten.rechnung, '5355771416');
assert.equal(daten.kundenId, 34079);
assert.equal(daten.adresstext, 'TUEV NORD Mobilitaet GmbH & Co. KG');
assert.equal(daten.datum.getFullYear(), 2026);
assert.equal(daten.datum.getMonth(), 7);
assert.equal(daten.datum.getDate(), 19);
});
test('setLieferscheinNummer schickt das komplette Formular als JSON an update.php', async t => {
const { connector, requests } = await startConnector(t);
await connector.setLieferscheinNummer(388444, '2026-001107');
const update = requests.find(request => request.url === '/module/eingangsrechnungen/api/update.php');
assert.ok(update, 'update.php wurde nicht aufgerufen');
assert.equal(update.method, 'POST');
assert.match(update.headers['content-type'], /^application\/json/);
assert.deepEqual(JSON.parse(update.body), {
rechnungID: 388444,
formData: {
typ: '0',
mengenUndPreisAnpassung: '0',
lieferscheinnummer: '2026-001107',
rechnungsnummer: '5355771416',
rechnungsdatum: '19.08.26',
firma_id: '3',
rgempf: '34079',
addressName: 'TUEV NORD Mobilitaet GmbH & Co. KG',
additionalAddressLineOne: '',
additionalAddressLineTwo: '',
addressStreet: 'Postfach 810551',
addressPostalcode: '30505',
addressCity: 'Hannover',
addressCountryISO3166: 'DE',
notiz: 'Zeile 1',
},
});
});
test('setRechnungsdaten meldet die Fehlermeldung aus update.php', async t => {
const { connector } = await startConnector(t, { updateResponse: { msg: 'Rechnung ist gesperrt' } });
await assert.rejects(
connector.setLieferscheinNummer(388444, '2026-001107'),
/Rechnung ist gesperrt/
);
});
test('setRechnungsdaten gibt bei HTTP 422 den Grund aus dem Body weiter', async t => {
const { connector } = await startConnector(t, {
updateStatus: 422,
updateResponse: { msg: 'Rechnungsdatum ungueltig' },
});
await assert.rejects(
connector.setLieferscheinNummer(388444, '2026-001107'),
/HTTP 422\): Rechnungsdatum ungueltig/
);
});
test('setRechnungsdaten zeigt bei 422 ohne msg den Body', async t => {
const { connector } = await startConnector(t, {
updateStatus: 422,
updateResponse: { errors: { rgempf: 'fehlt' } },
});
await assert.rejects(
connector.setLieferscheinNummer(388444, '2026-001107'),
/HTTP 422\): \{"errors":\{"rgempf":"fehlt"\}\}/
);
});
test('setLieferscheinNummer schickt bei gebuchter Rechnung auch die disabled-Felder', async t => {
const { connector, requests } = await startConnector(t);
await connector.setLieferscheinNummer(387644, '2026-001225');
const update = requests.find(request => request.url === '/module/eingangsrechnungen/api/update.php');
assert.ok(update, 'update.php wurde nicht aufgerufen');
const { formData } = JSON.parse(update.body);
assert.equal(formData.lieferscheinnummer, '2026-001225');
assert.equal(formData.typ, '0');
assert.equal(formData.mengenUndPreisAnpassung, '0');
assert.equal(formData.firma_id, '3');
assert.equal(formData.additionalAddressLineOne, '');
assert.equal(formData.additionalAddressLineTwo, '');
assert.equal(formData.addressStreet, 'Postfach 810551');
assert.equal(formData.addressPostalcode, '30505');
assert.equal(formData.addressCity, 'Hannover');
assert.equal(formData.addressCountryISO3166, 'DE');
});