const assert = require('node:assert/strict');
const http = require('node:http');
const test = require('node:test');
const { AgrarmonitorConnector, MemoryCookieStore } = require('../dist');
const loginPage = `
Anmeldung - AGRARMONITOR
`;
const taetigkeitHead = `
| # | Bezeichnung | Maschinen zuordnen |
Abwesenheit | Als Urlaub werten | Notiz erzwingen |
Wartungsplan | Erweiterte Effizienz |
Aktiv |
|
`;
// Gekuerzte Antwort von /module/arbeitszeit/taetigkeiten-livesearch.php?taetigkeiten_aktiv=1
const taetigkeitenLivesearch = `
100 Werkstatt (Mobil sichtbar)
${taetigkeitHead}
| 100 | Reparatur / Wartung / Waschen etc. von Maschinen |
Ja | Nein | Nein | Ja | Ja | Nein |
|
|
| 110 | Wartung |
Ja | Nein | Nein | Nein | Ja | Nein |
|
|
900 Abwesenheit (Mobil nicht sichtbar)
${taetigkeitHead}
| 950 | Feiertag |
Nein | Ja | Nein | Nein | Nein | Nein |
|
|
`;
function maschinenTabelle(gruppenId, gruppe, rows) {
return `
${gruppe}
`;
}
function maschinenZeile(id, nummer, name, kennzeichen, aktiv) {
return `
| ${nummer} | ${name} | ${kennzeichen} | - |
|
|
`;
}
const pagination = seiten => ``;
// Seite 1: eine Maschine steht in zwei Kategorien, Seite 2: weitere Maschine.
const maschinenSeite1 =
maschinenTabelle(
7,
'Schlepper',
maschinenZeile(5033, '12', 'Testschlepper 724', 'XX-AB 724', true) +
maschinenZeile(3696, '-', 'Einrichtung', '-', false)
) +
maschinenTabelle(893, 'Zugmaschinen GmbH', maschinenZeile(5033, '12', 'Testschlepper 724', 'XX-AB 724', true));
const maschinenSeite2 = maschinenTabelle(13, 'LKWs', maschinenZeile(7087, '40', 'Test-LKW', 'XX-CD 40', true));
function createServer({ maschinenSeiten }) {
const requests = [];
let loggedIn = false;
const server = http.createServer((req, res) => {
const url = new URL(req.url, 'http://localhost');
requests.push({ method: req.method, path: url.pathname, params: Object.fromEntries(url.searchParams) });
if (req.method === 'POST' && url.pathname === '/login/api/login.php') {
req.resume();
req.on('end', () => {
loggedIn = true;
res.writeHead(200, { 'Content-Type': 'application/json', 'Set-Cookie': 'agrar_session=test; Path=/' });
res.end(JSON.stringify({ success: true }));
});
return;
}
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
if (!loggedIn) {
res.end(loginPage);
return;
}
if (url.pathname === '/') {
res.end('Mein AM');
return;
}
if (url.pathname === '/module/arbeitszeit/taetigkeiten-livesearch.php') {
// Agrarmonitor ignoriert "seite" hier und liefert immer alles.
res.end(taetigkeitenLivesearch);
return;
}
if (url.pathname === '/module/maschinen/livesearch.php') {
const seite = Number(url.searchParams.get('seite'));
res.end(maschinenSeiten(seite));
return;
}
res.writeHead(404);
res.end('not found');
});
return {
server,
requests,
expireSession() {
loggedIn = false;
},
};
}
async function startConnector(t, serverOptions = { maschinenSeiten: () => maschinenSeite1 + pagination(0) }) {
const { server, requests, expireSession } = createServer(serverOptions);
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, expireSession };
}
const livesearchRequests = (requests, path) => requests.filter(request => request.path === path);
test('getTaetigkeiten liest aktive und inaktive Taetigkeiten mit Bereich', async t => {
const { connector, requests } = await startConnector(t);
const taetigkeiten = await connector.getTaetigkeiten();
assert.deepEqual(taetigkeiten, [
{
id: 869,
uuid: '0191763e-2f7d-7c53-838d-f60b3c7bd0a6',
nummer: '100',
name: 'Reparatur / Wartung / Waschen etc. von Maschinen',
aktiv: true,
bereichId: 17,
bereich: '100 Werkstatt (Mobil sichtbar)',
maschineZuordnen: true,
abwesenheit: false,
notizErzwingen: true,
},
{
id: 15,
uuid: '0191763e-2cae-7d34-98d6-ec160935ae42',
nummer: '110',
name: 'Wartung',
aktiv: false,
bereichId: 17,
bereich: '100 Werkstatt (Mobil sichtbar)',
maschineZuordnen: true,
abwesenheit: false,
notizErzwingen: false,
},
{
id: 819,
uuid: '0191763e-2f3c-7766-be96-4bf6933e5677',
nummer: '950',
name: 'Feiertag',
aktiv: true,
bereichId: 19,
bereich: '900 Abwesenheit (Mobil nicht sichtbar)',
maschineZuordnen: false,
abwesenheit: true,
notizErzwingen: false,
},
]);
const calls = livesearchRequests(requests, '/module/arbeitszeit/taetigkeiten-livesearch.php');
assert.equal(calls.length, 1, 'ohne Pagination nur eine Seite laden');
assert.deepEqual(calls[0].params, { taetigkeiten_aktiv: '1', seite: '1' });
});
test('getAlleMaschinen laedt alle Seiten und fasst Maschinen aus mehreren Kategorien zusammen', async t => {
const { connector, requests } = await startConnector(t, {
maschinenSeiten: seite => (seite === 1 ? maschinenSeite1 : maschinenSeite2) + pagination(2),
});
const maschinen = await connector.getAlleMaschinen();
assert.deepEqual(maschinen, [
{
id: 5033,
nummer: '12',
name: 'Testschlepper 724',
kennzeichen: 'XX-AB 724',
aktiv: true,
gruppenId: 7,
gruppe: 'Schlepper',
gruppenIds: [7, 893],
},
{
id: 3696,
nummer: '',
name: 'Einrichtung',
kennzeichen: '',
aktiv: false,
gruppenId: 7,
gruppe: 'Schlepper',
gruppenIds: [7],
},
{
id: 7087,
nummer: '40',
name: 'Test-LKW',
kennzeichen: 'XX-CD 40',
aktiv: true,
gruppenId: 13,
gruppe: 'LKWs',
gruppenIds: [13],
},
]);
const calls = livesearchRequests(requests, '/module/maschinen/livesearch.php');
assert.deepEqual(
calls.map(call => call.params),
[
{ suchstring: '', maschinen_aktiv: '1', maschinengruppe: '0', seite: '1' },
{ suchstring: '', maschinen_aktiv: '1', maschinengruppe: '0', seite: '2' },
]
);
});
test('getAlleMaschinen bricht ab, wenn eine Seite keine neuen Zeilen bringt', async t => {
// data-pages behauptet 5 Seiten, ab Seite 2 kommt immer dasselbe.
const { connector, requests } = await startConnector(t, {
maschinenSeiten: seite => (seite === 1 ? maschinenSeite1 : maschinenSeite2) + pagination(5),
});
const maschinen = await connector.getAlleMaschinen();
assert.deepEqual(
maschinen.map(maschine => maschine.id),
[5033, 3696, 7087]
);
assert.equal(livesearchRequests(requests, '/module/maschinen/livesearch.php').length, 3);
});
test('getTaetigkeiten meldet sich bei abgelaufener Session neu an', async t => {
const { connector, requests, expireSession } = await startConnector(t);
const logins = () => requests.filter(request => request.path === '/login/api/login.php').length;
assert.equal(logins(), 1, 'init soll genau einmal einloggen');
expireSession();
const taetigkeiten = await connector.getTaetigkeiten();
assert.equal(taetigkeiten.length, 3);
assert.equal(logins(), 2, 'abgelaufene Session soll genau einen erneuten Login ausloesen');
assert.equal(livesearchRequests(requests, '/module/arbeitszeit/taetigkeiten-livesearch.php').length, 2);
});