Terminplaner TP2: Entwuerfe nach 90 Tagen und bei Kundenloeschung entfernen
Neu: server/services/termine/entwuerfe.js. Ein Terminplaner im Zustand off ist ein Entwurf (Fragebogen, Einstellung). loescheEntwuerfe(now) im Tagesjob (nach den abgeschalteten Funktionen, nur im vollen Lauf): letzte Aenderung = juengerer Zeitpunkt aus $updatedAt des Funktionsdokuments und termineConfig.updatedAt, aelter als 90 Tage => Einstellung weg, das Funktionsdokument nur, wenn es nie in Betrieb oder bezahlt war (sonst bleibt es wegen des siteKeys; ein von E8 zurueckgesetztes Dokument nie). Vor jedem Loeschen unter feature-order, feature-admin und termine-cfg frisch lesen (noch off, Frist, keine Buchung). Seiten zu 100 per cursorAfter, hoechstens 2000 geprueft und 100 geloescht je Lauf, der Rest folgt an Folgetagen; Einzelfehler zaehlen in fehler. Tagesbericht: Segment "Entwuerfe n geloescht (m offen)". loescheEntwuerfeVonKunde: Kundenloeschung entfernt alle off-Entwuerfe vollstaendig, Fehler werden nur protokolliert. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
29a38a9592
commit
91b1a3bcd8
6 files changed
+827
-24
No files matched your search
+111
-13
@@ -1410,7 +1410,7 @@ test('taeglicherJob: gedeckelt zählt je Schritt; der Tagesbericht nennt „Lös
|
||||
assert.deepEqual(erg.gedeckelt, { loeschfristen: 2, abgeschaltet: 0, zellen: 0 })
|
||||
let zeile = tagesbericht(erg)
|
||||
assert.match(zeile, /^\[termine\] Tagesjob: 4 Buchungen gelöscht \(/)
|
||||
assert.match(zeile, /, 0 Mails nicht zugestellt, Löschläufe am Deckel: 2, Rest folgt an den nächsten Tagen, Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 1 ausgenommen, 0 Fehler, 1 aktive Betriebe$/)
|
||||
assert.match(zeile, /, 0 Mails nicht zugestellt, Löschläufe am Deckel: 2, Rest folgt an den nächsten Tagen, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 1 ausgenommen, 0 Fehler, 1 aktive Betriebe$/)
|
||||
assert.doesNotMatch(zeile, /\bb_|\bf_|@|Mustermann|Salon/)
|
||||
|
||||
config.termine.loeschDeckel = DECKEL_VORHER
|
||||
@@ -1418,7 +1418,7 @@ test('taeglicherJob: gedeckelt zählt je Schritt; der Tagesbericht nennt „Lös
|
||||
assert.deepEqual(erg.gedeckelt, { loeschfristen: 0, abgeschaltet: 0, zellen: 0 })
|
||||
zeile = tagesbericht(erg)
|
||||
assert.doesNotMatch(zeile, /Deckel/, 'ohne Deckel bleibt die Zeile unverändert')
|
||||
assert.match(zeile, /, 0 Mails nicht zugestellt, Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 1 ausgenommen, 0 Fehler, 1 aktive Betriebe$/)
|
||||
assert.match(zeile, /, 0 Mails nicht zugestellt, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 1 ausgenommen, 0 Fehler, 1 aktive Betriebe$/)
|
||||
})
|
||||
|
||||
test('tagesbericht: das Segment zählt die Schritte aller Bereiche und fehlt bei gedeckelt 0', () => {
|
||||
@@ -2105,6 +2105,7 @@ test('Zurücksetzen: nach dem Zurücksetzen steht das Dokument auf off und ist w
|
||||
test('taeglicherJob: Löschfristen, Warteschlange, festgefahrene Mails, verwaiste Zellen und abgeschaltete Funktionen in einem Lauf', async () => {
|
||||
await richteFunktionEin(F1)
|
||||
await richteFunktionEin(F2, { state: 'disabled', disabledAt: iso(plus(JETZT, -45 * TAG)) })
|
||||
await legeEntwurf(F3, 91) // Entwurf: Terminplaner im Zustand off, seit 91 Tagen unverändert
|
||||
await legeBuchung('b_verfallen', { status: 'verfallen', heldUntil: iso(plus(JETZT, -3 * TAG)) })
|
||||
await legeBuchung('b_erledigt', { status: 'erledigt', ende: plus(JETZT, -100 * TAG) })
|
||||
await legeBuchung('b_zukunft', { start: plus(JETZT, 5 * TAG) })
|
||||
@@ -2125,6 +2126,11 @@ test('taeglicherJob: Löschfristen, Warteschlange, festgefahrene Mails, verwaist
|
||||
assert.equal(erg.geloescht, 3, 'verfallen 1 + erledigt 1 + abgeschaltete Funktion 1')
|
||||
assert.equal(erg.aktiveBetriebe, 1, 'F1 ist aktiv, F2 abgeschaltet')
|
||||
assert.deepEqual(erg.aboAbgleich, { geprueft: 0, abgeschaltet: 0, wiederEin: 0, mails: 0, ausgenommen: 1, fehler: 0 }, 'F1 ist aktiv ohne Kauf (ausgenommen), F2 abgeschaltet ohne Grund (bleibt unberührt)')
|
||||
// geprüft werden auch F2 (die Löschung hat es eben auf off zurückgesetzt: purchaseStatus zurueckgesetzt, bleibt) und F3 (Entwurf, weg)
|
||||
assert.deepEqual(erg.entwuerfe, { geprueft: 2, geloescht: 1, uebrig: 0, fehler: 0 }, 'der Entwurf F3 ist nach 90 Tagen weg')
|
||||
assert.equal(aw.docs('portalFeatures').get(F2).purchaseStatus, 'zurueckgesetzt', 'das zurückgesetzte Dokument F2 bleibt samt siteKey')
|
||||
assert.equal(aw.docs('portalFeatures').get(F3), undefined)
|
||||
assert.equal(aw.docs('termineConfig').get(F3), undefined)
|
||||
assert.equal(erg.aufgeraeumt, 1)
|
||||
assert.ok(erg.zellen >= 1)
|
||||
|
||||
@@ -2143,7 +2149,7 @@ test('taeglicherJob: Löschfristen, Warteschlange, festgefahrene Mails, verwaist
|
||||
const zeile = tagesbericht(erg)
|
||||
assert.equal(
|
||||
zeile,
|
||||
`[termine] Tagesjob: 3 Buchungen gelöscht (verfallen 1, abgesagt 0, abgelehnt 0, erledigt 1, nichterschienen 0, abgeschaltete Funktionen 1), 1 Funktionen bereinigt, ${erg.zellen} Zellen, 1 Outbox, 1 Mails nicht zugestellt, Abo-Abgleich 0 geprüft / 0 abgeschaltet / 0 wieder ein / 0 Mails / 1 ausgenommen, 0 Fehler, 1 aktive Betriebe`,
|
||||
`[termine] Tagesjob: 3 Buchungen gelöscht (verfallen 1, abgesagt 0, abgelehnt 0, erledigt 1, nichterschienen 0, abgeschaltete Funktionen 1), 1 Funktionen bereinigt, ${erg.zellen} Zellen, 1 Outbox, 1 Mails nicht zugestellt, Entwürfe 1 gelöscht (0 offen), Abo-Abgleich 0 geprüft / 0 abgeschaltet / 0 wieder ein / 0 Mails / 1 ausgenommen, 0 Fehler, 1 aktive Betriebe`,
|
||||
)
|
||||
assert.doesNotMatch(zeile, /\bb_|\bf_|@|Mustermann|Salon/)
|
||||
})
|
||||
@@ -2158,7 +2164,7 @@ test('taeglicherJob: abgeschaltete Funktion am Deckel ⇒ gedeckelt.abgeschaltet
|
||||
assert.equal(erg.fehler, 0)
|
||||
let zeile = tagesbericht(erg)
|
||||
assert.match(zeile, /^\[termine\] Tagesjob: 2 Buchungen gelöscht \(.*abgeschaltete Funktionen 2\), 1 Funktionen bereinigt, /)
|
||||
assert.match(zeile, /, 0 Mails nicht zugestellt, Löschläufe am Deckel: 1, Rest folgt an den nächsten Tagen, Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 0 Fehler, \d+ aktive Betriebe$/)
|
||||
assert.match(zeile, /, 0 Mails nicht zugestellt, Löschläufe am Deckel: 1, Rest folgt an den nächsten Tagen, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 0 Fehler, \d+ aktive Betriebe$/)
|
||||
assert.doesNotMatch(zeile, /\bb_|\bf_|@|Mustermann|Salon/)
|
||||
|
||||
erg = await taeglicherJob(JETZT)
|
||||
@@ -2199,7 +2205,7 @@ test('taeglicherJob: Zellen-Sweep am Deckel ⇒ gedeckelt.zellen zählt, zellen
|
||||
assert.doesNotMatch(warnLog().join('\n'), /\bb_|\bf_|\br_|\bc_/, 'die Warnung nennt keine Kennungen')
|
||||
const zeile = tagesbericht(erg)
|
||||
assert.match(zeile, /, 250 Zellen, /)
|
||||
assert.match(zeile, /Löschläufe am Deckel: 1, Rest folgt an den nächsten Tagen, Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 0 Fehler, 0 aktive Betriebe$/)
|
||||
assert.match(zeile, /Löschläufe am Deckel: 1, Rest folgt an den nächsten Tagen, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 0 Fehler, 0 aktive Betriebe$/)
|
||||
|
||||
erg = await taeglicherJob(JETZT)
|
||||
assert.equal(erg.zellen, 250)
|
||||
@@ -2242,7 +2248,7 @@ test('taeglicherJob: ist die Liste der abgeschalteten Funktionen nicht lesbar, z
|
||||
assert.deepEqual(erg.gedeckelt, { loeschfristen: 0, abgeschaltet: 0, zellen: 0 })
|
||||
assert.equal(erg.fehler, 1)
|
||||
assert.equal(buchungen().length, 3)
|
||||
assert.match(tagesbericht(erg), /, 0 Mails nicht zugestellt, Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 1 Fehler, \d+ aktive Betriebe$/)
|
||||
assert.match(tagesbericht(erg), /, 0 Mails nicht zugestellt, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 1 Fehler, \d+ aktive Betriebe$/)
|
||||
})
|
||||
|
||||
test('tagesbericht: keine Zeile, wenn der Job nicht gelaufen ist', () => {
|
||||
@@ -2285,7 +2291,7 @@ test('taeglicherJob: aktiveBetriebe zählt nur aktive Termine-Dokumente (kein ab
|
||||
|
||||
test('taeglicherJob: ist die Zahl der aktiven Betriebe nicht lesbar, ist aktiveBetriebe null, der Fehler gezählt, der Rest des Laufs fertig und die Zeile ohne Segment', async () => {
|
||||
await legeLoeschFall('b_ver000', 'verfallen', 1)
|
||||
aw.failNext({ collection: 'portalFeatures', method: 'GET', status: 500, message: 'Nachbau kaputt', after: 3 }) // 1. GET = Funktionen der Löschfristen, 2. = Abo-Abgleich, 3. = abgeschaltete, 4. = Zählung
|
||||
aw.failNext({ collection: 'portalFeatures', method: 'GET', status: 500, message: 'Nachbau kaputt', after: 4 }) // 1. GET = Funktionen der Löschfristen, 2. = Abo-Abgleich, 3. = abgeschaltete, 4. = Entwürfe, 5. = Zählung
|
||||
const erg = await taeglicherJob(JETZT)
|
||||
assert.equal(erg.aktiveBetriebe, null)
|
||||
assert.equal(erg.fehler, 1)
|
||||
@@ -2302,7 +2308,7 @@ const team20 = () => sink.sent.filter((mail) => /^\[Terminplaner\]/.test(mail.su
|
||||
test('taeglicherJob meldet am Ende: Fehler im Lauf ⇒ Team-Mail „Tagesjob mit Fehlern“, letzterTagesjob trägt nur Zählungen; ein sauberer Lauf meldet nichts', async () => {
|
||||
assert.equal(letzterTagesjob(), null)
|
||||
await legeLoeschFall('b_ver000', 'verfallen', 1)
|
||||
aw.failNext({ collection: 'portalFeatures', method: 'GET', status: 500, message: 'Nachbau kaputt', after: 3 }) // die Zählung der aktiven Betriebe
|
||||
aw.failNext({ collection: 'portalFeatures', method: 'GET', status: 500, message: 'Nachbau kaputt', after: 4 }) // die Zählung der aktiven Betriebe (5. GET: nach Löschfristen, Abo-Abgleich, abgeschaltete Funktionen, Entwürfe)
|
||||
const erg = await taeglicherJob(JETZT)
|
||||
assert.equal(erg.fehler, 1)
|
||||
assert.equal(team20().length, 1)
|
||||
@@ -2432,7 +2438,7 @@ test('taeglicherJob: der Abo-Abgleich steht im Ergebnis mit seinen Zählern; ein
|
||||
assert.equal(aw.docs('portalFeatures').get(F1).disabledReason, 'abo_ende')
|
||||
assert.equal(aw.docs('portalFeatures').get(F2).state, 'active', 'das Pilot-Dokument bleibt')
|
||||
assert.equal(kundenMails(K22_BETREFF).length, 1)
|
||||
assert.match(tagesbericht(erg), /, 0 Mails nicht zugestellt, Abo-Abgleich 1 geprüft \/ 1 abgeschaltet \/ 0 wieder ein \/ 1 Mails \/ 1 ausgenommen, 0 Fehler, 1 aktive Betriebe$/)
|
||||
assert.match(tagesbericht(erg), /, 0 Mails nicht zugestellt, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich 1 geprüft \/ 1 abgeschaltet \/ 0 wieder ein \/ 1 Mails \/ 1 ausgenommen, 0 Fehler, 1 aktive Betriebe$/)
|
||||
})
|
||||
|
||||
test('taeglicherJob: der Abgleich läuft vor der Löschung – ein Terminplaner, dessen Abo heute zurückkehrt, wird nicht gelöscht', async () => {
|
||||
@@ -2477,7 +2483,7 @@ test('taeglicherJob: ist die Funktionsliste des Abgleichs nicht lesbar, läuft d
|
||||
assert.ok(fehlerLog().some((zeile) => /\[termine-abo\] Funktionen nicht lesbar/.test(zeile) && /Nachbau kaputt/.test(zeile)))
|
||||
assert.equal(team20().length, 1)
|
||||
assert.equal(team20()[0].subject, '[Terminplaner] Tagesjob mit Fehlern')
|
||||
assert.match(tagesbericht(erg), /, 0 Mails nicht zugestellt, Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 1 Fehler, \d+ aktive Betriebe$/)
|
||||
assert.match(tagesbericht(erg), /, 0 Mails nicht zugestellt, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich 0 geprüft \/ 0 abgeschaltet \/ 0 wieder ein \/ 0 Mails \/ 0 ausgenommen, 1 Fehler, \d+ aktive Betriebe$/)
|
||||
})
|
||||
|
||||
test('tagesbericht: die vollständige Zeile gleicht gegen das Literal (Abo-Abgleich vor den Fehlern, aktive Betriebe zuletzt), ohne Kennungen und Adressen', async () => {
|
||||
@@ -2485,7 +2491,7 @@ test('tagesbericht: die vollständige Zeile gleicht gegen das Literal (Abo-Abgle
|
||||
const zeile = tagesbericht(erg)
|
||||
assert.equal(
|
||||
zeile,
|
||||
'[termine] Tagesjob: 0 Buchungen gelöscht (verfallen 0, abgesagt 0, abgelehnt 0, erledigt 0, nichterschienen 0, abgeschaltete Funktionen 0), 0 Funktionen bereinigt, 0 Zellen, 0 Outbox, 0 Mails nicht zugestellt, Abo-Abgleich 0 geprüft / 0 abgeschaltet / 0 wieder ein / 0 Mails / 0 ausgenommen, 0 Fehler, 0 aktive Betriebe',
|
||||
'[termine] Tagesjob: 0 Buchungen gelöscht (verfallen 0, abgesagt 0, abgelehnt 0, erledigt 0, nichterschienen 0, abgeschaltete Funktionen 0), 0 Funktionen bereinigt, 0 Zellen, 0 Outbox, 0 Mails nicht zugestellt, Entwürfe 0 gelöscht (0 offen), Abo-Abgleich 0 geprüft / 0 abgeschaltet / 0 wieder ein / 0 Mails / 0 ausgenommen, 0 Fehler, 0 aktive Betriebe',
|
||||
)
|
||||
assert.doesNotMatch(zeile, /\bb_|\bf_|@/)
|
||||
})
|
||||
@@ -2498,20 +2504,93 @@ test('tagesbericht: mit Löschdeckel steht dessen Segment zwischen „Mails nich
|
||||
aufgeraeumt: 7,
|
||||
zellen: 8,
|
||||
aboAbgleich: { geprueft: 5, abgeschaltet: 1, wiederEin: 2, mails: 3, ausgenommen: 4, fehler: 0 },
|
||||
entwuerfe: { geprueft: 12, geloescht: 3, uebrig: 2, fehler: 0 },
|
||||
fehler: 9,
|
||||
aktiveBetriebe: 12,
|
||||
}
|
||||
const ohne = tagesbericht({ ...basis, gedeckelt: { loeschfristen: 0, abgeschaltet: 0, zellen: 0 } })
|
||||
assert.equal(
|
||||
ohne,
|
||||
'[termine] Tagesjob: 21 Buchungen gelöscht (verfallen 1, abgesagt 2, abgelehnt 3, erledigt 4, nichterschienen 5, abgeschaltete Funktionen 6), 1 Funktionen bereinigt, 8 Zellen, 7 Outbox, 3 Mails nicht zugestellt, Abo-Abgleich 5 geprüft / 1 abgeschaltet / 2 wieder ein / 3 Mails / 4 ausgenommen, 9 Fehler, 12 aktive Betriebe',
|
||||
'[termine] Tagesjob: 21 Buchungen gelöscht (verfallen 1, abgesagt 2, abgelehnt 3, erledigt 4, nichterschienen 5, abgeschaltete Funktionen 6), 1 Funktionen bereinigt, 8 Zellen, 7 Outbox, 3 Mails nicht zugestellt, Entwürfe 3 gelöscht (2 offen), Abo-Abgleich 5 geprüft / 1 abgeschaltet / 2 wieder ein / 3 Mails / 4 ausgenommen, 9 Fehler, 12 aktive Betriebe',
|
||||
)
|
||||
const mit = tagesbericht({ ...basis, gedeckelt: { loeschfristen: 2, abgeschaltet: 1, zellen: 1 } })
|
||||
assert.equal(
|
||||
mit,
|
||||
'[termine] Tagesjob: 21 Buchungen gelöscht (verfallen 1, abgesagt 2, abgelehnt 3, erledigt 4, nichterschienen 5, abgeschaltete Funktionen 6), 1 Funktionen bereinigt, 8 Zellen, 7 Outbox, 3 Mails nicht zugestellt, Löschläufe am Deckel: 4, Rest folgt an den nächsten Tagen, Abo-Abgleich 5 geprüft / 1 abgeschaltet / 2 wieder ein / 3 Mails / 4 ausgenommen, 9 Fehler, 12 aktive Betriebe',
|
||||
'[termine] Tagesjob: 21 Buchungen gelöscht (verfallen 1, abgesagt 2, abgelehnt 3, erledigt 4, nichterschienen 5, abgeschaltete Funktionen 6), 1 Funktionen bereinigt, 8 Zellen, 7 Outbox, 3 Mails nicht zugestellt, Löschläufe am Deckel: 4, Rest folgt an den nächsten Tagen, Entwürfe 3 gelöscht (2 offen), Abo-Abgleich 5 geprüft / 1 abgeschaltet / 2 wieder ein / 3 Mails / 4 ausgenommen, 9 Fehler, 12 aktive Betriebe',
|
||||
)
|
||||
assert.doesNotMatch(mit, /\bb_|\bf_|@/)
|
||||
// ohne Zähler der Entwürfe (ein Ergebnis aus einem früheren Lauf) fehlt das Segment, die übrige Zeile bleibt gleich
|
||||
assert.equal(tagesbericht({ ...basis, entwuerfe: undefined, gedeckelt: { loeschfristen: 0, abgeschaltet: 0, zellen: 0 } }), ohne.replace('Entwürfe 3 gelöscht (2 offen), ', ''))
|
||||
// unbrauchbare Zähler zählen als 0
|
||||
assert.match(tagesbericht({ ...basis, entwuerfe: { geloescht: 'x', uebrig: -1 }, gedeckelt: { loeschfristen: 0, abgeschaltet: 0, zellen: 0 } }), /Mails nicht zugestellt, Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich/)
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------- Tagesjob: Entwürfe (C6)
|
||||
|
||||
/** Entwurf: Terminplaner im Zustand off und seine Einstellung, beide seit `tage` Tagen unverändert. */
|
||||
async function legeEntwurf(id, tage, over = {}) {
|
||||
const seit = iso(plus(JETZT, -tage * TAG))
|
||||
aw.seed('portalFeatures', { ...feature(id, { state: 'off', enabled: false, siteKey: 'entwurfsitekey23', ...over }), $updatedAt: seit })
|
||||
aw.seed('termineConfig', { $id: id, customerId: KUNDE, projectId: id === F1 ? PROJEKT : `p_${id}`, einstellung: '{}', version: 1, updatedAt: seit, updatedBy: 'kunde' })
|
||||
}
|
||||
|
||||
test('taeglicherJob: Entwürfe nach 90 Tagen gelöscht (nach den abgeschalteten Funktionen), jüngere bleiben; Ergebnis und Berichtszeile tragen nur Zahlen', async () => {
|
||||
await richteFunktionEin(F1)
|
||||
await legeEntwurf(F2, 91)
|
||||
await legeEntwurf(F3, 89)
|
||||
const erg = await taeglicherJob(JETZT)
|
||||
assert.deepEqual(erg.entwuerfe, { geprueft: 2, geloescht: 1, uebrig: 0, fehler: 0 })
|
||||
assert.equal(erg.fehler, 0)
|
||||
assert.equal(aw.docs('portalFeatures').get(F2), undefined)
|
||||
assert.equal(aw.docs('termineConfig').get(F2), undefined)
|
||||
assert.ok(aw.docs('portalFeatures').get(F3))
|
||||
assert.ok(aw.docs('termineConfig').get(F3))
|
||||
assert.ok(aw.docs('portalFeatures').get(F1), 'die aktive Funktion bleibt')
|
||||
assert.equal(erg.geloescht, 0, 'geloescht zählt Buchungen, keine Entwürfe')
|
||||
const zeile = tagesbericht(erg)
|
||||
assert.match(zeile, /, 0 Mails nicht zugestellt, Entwürfe 1 gelöscht \(0 offen\), Abo-Abgleich /)
|
||||
assert.doesNotMatch(zeile, /\bb_|\bf_|\bp_|\bc_|@|Mustermann|Salon|Müller|entwurfsitekey/)
|
||||
})
|
||||
|
||||
test('taeglicherJob: Entwürfe am Deckel – 100 je Lauf, der Rest zählt als offen und folgt am nächsten Tag', async () => {
|
||||
for (let i = 0; i < 130; i += 1) await legeEntwurf(`f_p_entwurf${String(100 + i)}_termine`, 120)
|
||||
let erg = await taeglicherJob(JETZT)
|
||||
assert.deepEqual(erg.entwuerfe, { geprueft: 130, geloescht: 100, uebrig: 30, fehler: 0 })
|
||||
assert.match(tagesbericht(erg), /Entwürfe 100 gelöscht \(30 offen\), Abo-Abgleich /)
|
||||
erg = await taeglicherJob(plus(JETZT, TAG))
|
||||
assert.deepEqual(erg.entwuerfe, { geprueft: 30, geloescht: 30, uebrig: 0, fehler: 0 })
|
||||
assert.equal(aw.docs('portalFeatures').size, 0)
|
||||
assert.equal(aw.docs('termineConfig').size, 0)
|
||||
})
|
||||
|
||||
test('taeglicherJob: Fehler beim Löschen eines Entwurfs zählen in fehler und in der Berichtszeile, die übrigen Schritte laufen weiter', async () => {
|
||||
await legeEntwurf(F2, 120)
|
||||
await legeBuchung('b_verfallen', { status: 'verfallen', heldUntil: iso(plus(JETZT, -3 * TAG)) })
|
||||
aw.failNext({ collection: 'termineConfig', method: 'DELETE', status: 500, message: 'Nachbau kaputt' })
|
||||
const erg = await taeglicherJob(JETZT)
|
||||
assert.deepEqual(erg.entwuerfe, { geprueft: 1, geloescht: 0, uebrig: 0, fehler: 1 })
|
||||
assert.equal(erg.fehler, 1, 'der Fehler steht im Ergebnis des Tagesjobs')
|
||||
assert.equal(erg.loeschfristen.verfallen, 1, 'die Löschfristen liefen')
|
||||
assert.ok(aw.docs('portalFeatures').get(F2), 'der Entwurf bleibt und folgt am nächsten Tag')
|
||||
assert.match(tagesbericht(erg), /Entwürfe 0 gelöscht \(0 offen\), Abo-Abgleich .*, 1 Fehler, /)
|
||||
assert.ok(fehlerLog().some((zeile) => /\[termine-entwuerfe\]/.test(zeile) && /Nachbau kaputt/.test(zeile)))
|
||||
assert.equal(team20().length, 1, 'das Team erfährt von den Fehlern')
|
||||
|
||||
const folgetag = await taeglicherJob(plus(JETZT, TAG))
|
||||
assert.deepEqual(folgetag.entwuerfe, { geprueft: 1, geloescht: 1, uebrig: 0, fehler: 0 })
|
||||
assert.equal(aw.docs('portalFeatures').get(F2), undefined)
|
||||
})
|
||||
|
||||
test('Ist die Liste der Entwürfe nicht lesbar, zählt der Schritt einen Fehler und die übrigen Schritte laufen', async () => {
|
||||
await legeEntwurf(F2, 120)
|
||||
await legeBuchung('b_verfallen', { status: 'verfallen', heldUntil: iso(plus(JETZT, -3 * TAG)) })
|
||||
// GET auf portalFeatures: 1. Funktionen der Löschfristen, 2. Abo-Abgleich, 3. abgeschaltete Funktionen, 4. Entwürfe
|
||||
aw.failNext({ collection: 'portalFeatures', method: 'GET', status: 500, message: 'Nachbau kaputt', after: 3 })
|
||||
const erg = await taeglicherJob(JETZT)
|
||||
assert.deepEqual(erg.entwuerfe, { geprueft: 0, geloescht: 0, uebrig: 0, fehler: 1 })
|
||||
assert.equal(erg.fehler, 1)
|
||||
assert.equal(erg.loeschfristen.verfallen, 1)
|
||||
assert.ok(aw.docs('portalFeatures').get(F2))
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------- Tagesjob bei TERMINE_ENABLED=off mit bezahlten Terminplanern (eingeschränkter Lauf)
|
||||
@@ -2552,6 +2631,25 @@ test('Modus off, bezahlter Terminplaner abgeschaltet seit 31 Tagen: Buchungen, Z
|
||||
assert.doesNotMatch(zeile, /\bb_|\bf_|\bp_|\bc_|@|aktive Betriebe/)
|
||||
})
|
||||
|
||||
test('Modus off: der Entwurfs-Schritt gehört zum stillstehenden Teil – ein alter Entwurf bleibt, das Ergebnis trägt kein entwuerfe, die Zeile kein Entwürfe-Segment', async () => {
|
||||
await richteFunktionEin(F1, abgeschaltetBezahlt(31)) // ein bezahlter Terminplaner hält den eingeschränkten Lauf am Laufen
|
||||
await legeEntwurf(F2, 400)
|
||||
config.termine.mode = 'off'
|
||||
|
||||
const erg = await taeglicherJob(JETZT)
|
||||
assert.equal(erg.eingeschraenkt, true)
|
||||
assert.equal('entwuerfe' in erg, false)
|
||||
assert.ok(aw.docs('portalFeatures').get(F2), 'der Entwurf bleibt')
|
||||
assert.ok(aw.docs('termineConfig').get(F2))
|
||||
assert.doesNotMatch(tagesbericht(erg), /Entwürfe/)
|
||||
// dieselbe Lage im Modus pilot: der Entwurf geht
|
||||
config.termine.mode = 'pilot'
|
||||
const pilot = await taeglicherJob(plus(JETZT, TAG))
|
||||
assert.deepEqual(pilot.entwuerfe, { geprueft: 2, geloescht: 1, uebrig: 0, fehler: 0 }, 'F1 (vom eingeschränkten Lauf zurückgesetzt, bleibt) und F2 (Entwurf, weg)')
|
||||
assert.equal(aw.docs('portalFeatures').get(F1).purchaseStatus, 'zurueckgesetzt')
|
||||
assert.equal(aw.docs('portalFeatures').get(F2), undefined)
|
||||
})
|
||||
|
||||
test('Modus off: am Löschdeckel zählt gedeckelt.abgeschaltet, letzterTagesjob und die Zeile nennen den Deckel (vor dem Abo-Abgleich), der Rest folgt am nächsten Tag', async () => {
|
||||
config.termine.loeschDeckel = 2
|
||||
await abgeschaltetMitBuchungen(5, { zellen: false })
|
||||
|
||||
Reference in new issue
Block a user