Buchungskalender: Aufbewahrung – Sperre wie Ablauf, Restpunkte
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c019d3c3b0
commit
827ee54875
5 files changed
+102
-17
No files matched your search
@@ -20,6 +20,7 @@ const { anonymisiere, loescheAbgeschaltete, loescheUkDaten, schliesseUkVonKunde
|
||||
const jobs = await import('../server/services/unterkunft/jobs.js')
|
||||
const mails = await import('../server/services/unterkunft/mails.js')
|
||||
const { deleteCustomerWithPortalAccess } = await import('../server/services/customerAdmin.js')
|
||||
const { withLocks } = await import('../server/services/keyedLock.js')
|
||||
const { raeumeAuf } = await import('../server/services/termine/outbox.js')
|
||||
|
||||
const TAG = 24 * 3600 * 1000
|
||||
@@ -149,6 +150,7 @@ test('Logs ohne Personendaten: ein Fehler wird gezaehlt, der Lauf macht weiter',
|
||||
assert.equal(r.ipHashes, 1)
|
||||
assert.deepEqual([holen(a).ipHash, holen(b).ipHash].sort(), ['', 'abcd'])
|
||||
assert.ok(log.mock.calls.length >= 1)
|
||||
assert.ok(!JSON.stringify(log.mock.calls.map((c) => c.arguments)).includes('eva@example.com'), 'keine Personendaten im Log')
|
||||
})
|
||||
|
||||
const funktion = (over = {}) => aw.seed('portalFeatures', { $id: 'f1', customerId: 'c1', projectId: 'p1', featureKey: 'unterkunft', siteKey: 'abcdefghijklmnop', state: 'active', enabled: true, ...over })
|
||||
@@ -236,3 +238,69 @@ test('Kundenloeschung schaltet die Funktion ab, schliesst die Unterkuenfte, Date
|
||||
assert.equal(anzahl('f1'), 0)
|
||||
assert.equal(await schliesseUkVonKunde('c1'), 0)
|
||||
})
|
||||
|
||||
test('Sperre wie ablauf.js: ein Wechsel auf freigegeben unter der Unterkunfts-Sperre wird nicht ueberschrieben', async () => {
|
||||
const id = anfrage({ $createdAt: vor(61), unterkunftId: 'u1' })
|
||||
let lauf
|
||||
await withLocks(['unterkunft:u1'], async () => {
|
||||
// der Job laeuft an und wartet auf die Sperre; waehrenddessen gibt der Vermieter frei
|
||||
lauf = anonymisiere(JETZT)
|
||||
await new Promise((r) => setTimeout(r, 150))
|
||||
await (await import('../server/services/appwriteAdmin.js')).updateDocument(config.collections.ukAnfragen, id, { status: 'freigegeben' })
|
||||
})
|
||||
const r = await lauf
|
||||
assert.equal(r.abgelaufen, 0)
|
||||
assert.equal(holen(id).status, 'freigegeben')
|
||||
})
|
||||
|
||||
test('Gebucht ohne jede Rechnung: Rechnungsadresse geht mit den Gastdaten', async () => {
|
||||
const a = anfrage({ status: 'gebucht', bis: '2022-06-01', rechnungsadresse: JSON.stringify(ADRESSE) })
|
||||
const r = await anonymisiere(new Date('2026-01-02T10:00:00Z'))
|
||||
assert.equal(r.gaeste, 1)
|
||||
assert.deepEqual(gast(a), {})
|
||||
assert.equal(holen(a).rechnungsadresse, null)
|
||||
})
|
||||
|
||||
test('adminNote: bisheriger Text bleibt vor dem Marker; Wiedereinschalten bricht ab; erneutes Abschalten loescht nach neuen 90 Tagen; aktive Funktion mit altem Marker unberuehrt', async () => {
|
||||
const sp = await import('../server/services/appwriteAdmin.js')
|
||||
funktion({ state: 'disabled', enabled: false, disabledAt: vor(100), adminNote: 'Kunde gelöscht' })
|
||||
datenFuer('f1')
|
||||
assert.equal((await loescheAbgeschaltete(JETZT)).funktionen, 1)
|
||||
assert.equal(aw.docs('portalFeatures').get('f1').adminNote, 'Kunde gelöscht – Buchungsdaten gelöscht am 2026-10-07')
|
||||
// wieder eingeschaltet: nichts wird geloescht
|
||||
funktion({ $id: 'f4', state: 'disabled', enabled: false, disabledAt: vor(91) })
|
||||
datenFuer('f4')
|
||||
await sp.updateDocument(config.collections.portalFeatures, 'f4', { state: 'active', enabled: true })
|
||||
assert.equal((await loescheAbgeschaltete(JETZT)).funktionen, 0)
|
||||
assert.equal(anzahl('f4'), 6)
|
||||
// erneut abgeschaltet (alter Marker steht noch): erst nach neuen 90 Tagen
|
||||
await sp.updateDocument(config.collections.portalFeatures, 'f4', { adminNote: 'Buchungsdaten gelöscht am 2026-01-01', state: 'disabled', enabled: false, disabledAt: vor(10) })
|
||||
assert.equal((await loescheAbgeschaltete(JETZT)).funktionen, 0)
|
||||
assert.equal(anzahl('f4'), 6)
|
||||
assert.equal((await loescheAbgeschaltete(new Date(JETZT.getTime() + 81 * TAG))).funktionen, 1)
|
||||
assert.equal(anzahl('f4'), 0)
|
||||
// aktive Funktion mit altem Marker: unberuehrt
|
||||
funktion({ $id: 'f5', state: 'active', adminNote: 'Buchungsdaten gelöscht am 2026-01-01' })
|
||||
datenFuer('f5')
|
||||
await loescheAbgeschaltete(new Date(JETZT.getTime() + 500 * TAG))
|
||||
assert.equal(anzahl('f5'), 6)
|
||||
})
|
||||
|
||||
test('Gemeinsamer Deckel: der Tagesjob gibt der Loeschung nur den Rest', async () => {
|
||||
const modus = config.unterkunft.mode
|
||||
const alt = config.unterkunft.aufbewahrungDeckel
|
||||
try {
|
||||
config.unterkunft.mode = 'on'
|
||||
config.unterkunft.aufbewahrungDeckel = 3
|
||||
for (let i = 0; i < 3; i++) anfrage({ $createdAt: vor(40) })
|
||||
funktion({ state: 'disabled', enabled: false, disabledAt: vor(120) })
|
||||
datenFuer('f1')
|
||||
const r = await jobs.taeglicherJob(JETZT)
|
||||
assert.equal(r.aufbewahrung.verbraucht, 3)
|
||||
assert.equal(r.abgeschaltet.dokumente, 0)
|
||||
assert.equal(r.abgeschaltet.gedeckelt, true)
|
||||
} finally {
|
||||
config.unterkunft.mode = modus
|
||||
config.unterkunft.aufbewahrungDeckel = alt
|
||||
}
|
||||
})
|
||||
@@ -227,9 +227,11 @@ test('Jobs: im Modus off {aus:true}; Minutenjob ruft die Fristen ab, die anderen
|
||||
config.unterkunft.mode = 'off'
|
||||
assert.deepEqual(await jobs.minutenJob(T0), { aus: true })
|
||||
assert.deepEqual(await jobs.viertelstundenJob(T0), { aus: true })
|
||||
// Tagesjob: die Fristen gelten auch bei off, solange es Buchungsdaten gibt (dann laeuft er, sonst {aus:true})
|
||||
// Tagesjob: die Fristen gelten auch bei off; ohne Buchungsdaten {aus:true}, mit Daten laeuft er
|
||||
const tagAus = await jobs.taeglicherJob(T0)
|
||||
assert.ok(tagAus.aus === true || tagAus.aufbewahrung?.fehler === 0, JSON.stringify(tagAus))
|
||||
const hatDaten = aw.docs('ukEinstellungen').size > 0 || aw.docs('ukAnfragen').size > 0
|
||||
if (hatDaten) assert.equal(tagAus.aufbewahrung?.fehler, 0, JSON.stringify(tagAus))
|
||||
else assert.deepEqual(tagAus, { aus: true })
|
||||
await leere()
|
||||
config.unterkunft.mode = 'on'
|
||||
const r = await jobs.minutenJob(T0)
|
||||
|
||||
Reference in new issue
Block a user