Stammdaten: getTaetigkeiten und getAlleMaschinen
getTaetigkeiten liest alle Taetigkeiten (aktiv und inaktiv) mit Bereich und den Flags Maschinen zuordnen, Abwesenheit und Notiz erzwingen. getAlleMaschinen liest alle Kategorien und Seiten und fasst Maschinen, die in mehreren Kategorien stehen, zu einem Eintrag zusammen. Paging ueber .pagination[data-pages], Abbruch sobald eine Seite keine neuen Zeilen bringt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d2c5db7e22
commit
6db6c5b278
10 files changed
+612
-4
No files matched your search
@@ -0,0 +1,303 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const http = require('node:http');
|
||||
const test = require('node:test');
|
||||
|
||||
const { AgrarmonitorConnector, MemoryCookieStore } = require('../dist');
|
||||
|
||||
const loginPage = `
|
||||
<html>
|
||||
<head><title>Anmeldung - AGRARMONITOR</title></head>
|
||||
<body>
|
||||
<form>
|
||||
<input name="nonce" value="test-nonce" />
|
||||
<button>Einloggen</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const taetigkeitHead = `
|
||||
<thead><tr>
|
||||
<td class="breite-einheit">#</td><td width="24%">Bezeichnung</td><td width="13%">Maschinen zuordnen</td>
|
||||
<td width="12%">Abwesenheit</td><td width="12%">Als Urlaub werten</td><td width="13%">Notiz erzwingen</td>
|
||||
<td width="13%">Wartungsplan</td><td width="13%">Erweiterte Effizienz</td>
|
||||
<td class="breite-icon" data-sort-method="none" align="center">Aktiv</td>
|
||||
<td class="breite-icon" data-sort-method="none" align="center"> </td>
|
||||
</tr></thead>
|
||||
`;
|
||||
|
||||
// Gekuerzte Antwort von /module/arbeitszeit/taetigkeiten-livesearch.php?taetigkeiten_aktiv=1
|
||||
const taetigkeitenLivesearch = `
|
||||
<h2><b class="bereich" data-id="17">100 Werkstatt (Mobil sichtbar) </b></h2>
|
||||
<table width="100%" class="alternate sortable taetigkeit_table table-fixed">
|
||||
${taetigkeitHead}
|
||||
<tbody>
|
||||
<tr data-id="869" data-activityUUID="0191763e-2f7d-7c53-838d-f60b3c7bd0a6">
|
||||
<td>100</td><td>Reparatur / Wartung / Waschen etc. von Maschinen</td>
|
||||
<td>Ja</td><td>Nein</td><td>Nein</td><td>Ja</td><td>Ja</td><td>Nein</td>
|
||||
<td align="center" class="block toggle"><i class="fa fa-check text-green fa-lg"></i></td>
|
||||
<td align="center" class="block"></td>
|
||||
</tr>
|
||||
<tr data-id="15" data-activityUUID="0191763e-2cae-7d34-98d6-ec160935ae42">
|
||||
<td>110</td><td>Wartung</td>
|
||||
<td>Ja</td><td>Nein</td><td>Nein</td><td>Nein</td><td>Ja</td><td>Nein</td>
|
||||
<td align="center" class="block toggle"><i class="fa fa-close text-red fa-lg"></i></td>
|
||||
<td align="center" class="block"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<h2><b class="bereich" data-id="19">900 Abwesenheit (Mobil nicht sichtbar) </b></h2>
|
||||
<table width="100%" class="alternate sortable taetigkeit_table table-fixed">
|
||||
${taetigkeitHead}
|
||||
<tbody>
|
||||
<tr data-id="819" data-activityUUID="0191763e-2f3c-7766-be96-4bf6933e5677">
|
||||
<td>950</td><td>Feiertag</td>
|
||||
<td>Nein</td><td>Ja</td><td>Nein</td><td>Nein</td><td>Nein</td><td>Nein</td>
|
||||
<td align="center" class="block toggle"><i class="fa fa-check text-green fa-lg"></i></td>
|
||||
<td align="center" class="block"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<script>admin.Arbeitszeit.Arbeitszeit.taetigkeitenLivesearch("de-DE", {"taetigkeiten":1});</script>
|
||||
`;
|
||||
|
||||
function maschinenTabelle(gruppenId, gruppe, rows) {
|
||||
return `
|
||||
<h2>${gruppe}</h2>
|
||||
<table width="100%" class="sortable clickable alternate maschinen_table table-fixed" id="maschinen_table_${gruppenId}">
|
||||
<thead><tr>
|
||||
<td width="10%">#</td><td width="50%">Bezeichnung</td><td width="15%">Kennzeichen</td><td width="25%">Zähler</td>
|
||||
<td align="center" class="breite-50" data-sort-method="none">Aktiv</td>
|
||||
<td align="center" class="block breite-icon" data-sort-method="none"><input type="checkbox" class="checkall"></td>
|
||||
</tr></thead>
|
||||
<tbody>${rows}</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
function maschinenZeile(id, nummer, name, kennzeichen, aktiv) {
|
||||
return `
|
||||
<tr id="${id}" data-id="${id}">
|
||||
<td>${nummer}</td><td> ${name} </td><td>${kennzeichen}</td><td>-</td>
|
||||
<td align="center" class="block toggle"><i class="fa ${aktiv ? 'fa-check text-green' : 'fa-close text-red'} fa-lg"></i></td>
|
||||
<td align="center" class="block"><input type="checkbox" name="maschinen[]" value="${id}"></td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
const pagination = seiten => `<div class="pagination" data-firma="" data-pages="${seiten}"></div>`;
|
||||
|
||||
// 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('<html><body>Mein AM</body></html>');
|
||||
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);
|
||||
});
|
||||
Reference in new issue
Block a user