News: Aufbewahrung, Datenschutz-Abschnitt und Leistungsbeschreibung (Entwurf)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0e0776b406
commit
0dc57fe5e8
6 files changed
+220
-4
No files matched your search
@@ -462,3 +462,23 @@ test('Fassung 5: Widerrufsbelehrung und Formular wortgleich mit Fassung 4', () =
|
||||
const muster = (belehrung) => between(belehrung, 'Widerrufsrecht Sie haben das Recht', 'Ende der Widerrufsbelehrung')
|
||||
assert.equal(muster(section(cur, 'widerruf', 'formular')), muster(section(v4, 'widerruf', 'formular')))
|
||||
})
|
||||
|
||||
test('legal_datenschutz_news: Abschnitt 6a und Leistungsbeschreibung (Entwurf)', () => {
|
||||
const html = read('public/datenschutz.html')
|
||||
const a = html.indexOf('id="news"')
|
||||
assert.ok(a > html.indexOf('6. Kundenportal'), 'Abschnitt 6a steht nach Abschnitt 6')
|
||||
const b = html.indexOf('<h2>7. ', a)
|
||||
assert.ok(b > a)
|
||||
const news = strip(html.slice(a, b))
|
||||
for (const s of ['News-Beiträge und Fotos', 'Metadaten', 'GPS', 'Falkenstein', 'Art. 6 Abs. 1 lit. b DSGVO']) assert.ok(news.includes(s), s)
|
||||
assert.ok(html.slice(Math.max(0, a - 120), a).includes('ENTWURF, Freigabe Nutzer ausstehend'))
|
||||
assert.ok(html.includes('<h2>7. Abos und Zahlung über Stripe</h2>'), 'keine Umnummerierung')
|
||||
|
||||
const lb = read('public/vertragsunterlagen/funktionen-leistungsbeschreibung.html')
|
||||
assert.ok(lb.includes('ENTWURF, Freigabe Nutzer ausstehend'))
|
||||
const text = strip(lb)
|
||||
for (const s of ['30,00 €', '§ 356 Abs. 4 BGB', '1–2 Wochen', 'keine laufenden Kosten']) assert.ok(text.includes(s), s)
|
||||
|
||||
const muster = read('docs/funktionen/website-datenschutz-absatz.md')
|
||||
assert.ok(!/[–—]/.test(muster.slice(muster.indexOf('## Variante A'))), 'Kundentext ohne Gedankenstriche')
|
||||
})
|
||||
@@ -15,11 +15,14 @@ const aw = await startAppwriteMock({
|
||||
subscriptions: schemaKeys('subscriptions'),
|
||||
contractEvents: schemaKeys('contractEvents'),
|
||||
takeoverCredits: schemaKeys('takeoverCredits'),
|
||||
newsPosts: schemaKeys('newsPosts'),
|
||||
portalFeatures: schemaKeys('portalFeatures'),
|
||||
},
|
||||
})
|
||||
const st = await startFakeStripe()
|
||||
const uploadDir = mkdtempSync(path.join(os.tmpdir(), 'loeschfristen-'))
|
||||
process.env.TAKEOVER_UPLOAD_DIR = uploadDir
|
||||
process.env.NEWS_UPLOAD_DIR = path.join(uploadDir, 'news')
|
||||
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
|
||||
const { findDueDeletions, applyDeletions, formatReport, CONSENT_METADATA_KEYS } = await import('../server/services/retention.js')
|
||||
const { run } = await import('../scripts/loeschfristen.mjs')
|
||||
@@ -264,3 +267,42 @@ test('genehmigter Antrag ohne decidedAt: übersprungen und gemeldet, kein Rückg
|
||||
assert.ok(plan.skipped.some((t) => t.id === 'nd_tk'))
|
||||
assert.match(formatReport(plan), /Übersprungen[\s\S]*nd_tk/)
|
||||
})
|
||||
|
||||
test('retention_loescht_news: Beiträge, Fotos und Funktionen fälliger Kunden', async () => {
|
||||
const { storeNewsImage, newsImagePath } = await import('../server/services/newsImages.js')
|
||||
const sharp = (await import('sharp')).default
|
||||
const png = () => sharp({ create: { width: 40, height: 30, channels: 3, background: '#c33' } }).png().toBuffer()
|
||||
sub('rn_sub', 'rn', { status: 'canceled', endedAt: '2022-03-15T10:00:00.000Z' })
|
||||
sub('rn2_sub', 'rn2', { status: 'active' }) // laufendes Abo: nichts davon wird angefasst
|
||||
stripeSub('rn_sub', 'rn')
|
||||
const { imageId } = await storeNewsImage({ customerId: 'rn', projectId: 'rnp', buffer: await png() })
|
||||
const other = await storeNewsImage({ customerId: 'rn2', projectId: 'rntwop', buffer: await png() })
|
||||
aw.seed('newsPosts', { $id: 'rn_post1', customerId: 'rn', projectId: 'rnp', type: 'photo', imageId, title: '', text: '' })
|
||||
aw.seed('newsPosts', { $id: 'rn_post2', customerId: 'rn', projectId: 'rnp', type: 'note', imageId: null, title: 'Hi', text: 'Hallo' })
|
||||
aw.seed('newsPosts', { $id: 'rn2_post', customerId: 'rn2', projectId: 'rntwop', type: 'photo', imageId: other.imageId, title: '', text: '' })
|
||||
aw.seed('portalFeatures', { $id: 'rn_feat', customerId: 'rn', projectId: 'rnp', featureKey: 'news', state: 'active', enabled: true })
|
||||
aw.seed('portalFeatures', { $id: 'rn2_feat', customerId: 'rn2', projectId: 'rntwop', featureKey: 'news', state: 'active', enabled: true })
|
||||
|
||||
const plan = await findDueDeletions(JAN_2026)
|
||||
const entry = plan.news.find((n) => n.customerId === 'rn')
|
||||
assert.deepEqual(entry.posts.map((p) => p.id).sort(), ['rn_post1', 'rn_post2'])
|
||||
assert.deepEqual(entry.posts.find((p) => p.id === 'rn_post1'), { id: 'rn_post1', projectId: 'rnp', imageId })
|
||||
assert.deepEqual(entry.featureIds, ['rn_feat'])
|
||||
assert.ok(!plan.news.some((n) => n.customerId === 'rn2'))
|
||||
assert.match(formatReport(plan), /Kunde rn: 2 News-Beitrag\/-Beiträge mit 1 Foto\(s\) zu löschen, 1 Funktion\(en\) abzuschalten/)
|
||||
|
||||
const result = await applyDeletions(plan)
|
||||
assert.deepEqual(result.failed, [])
|
||||
assert.equal(result.deleted.newsPosts, 2)
|
||||
assert.equal(result.deleted.newsImages, 1)
|
||||
assert.equal(result.deleted.features, 1)
|
||||
assert.match(formatReport(plan, result), /News: 2 Beitrag\/Beiträge und 1 Foto\(s\) gelöscht, 1 Funktion\(en\) abgeschaltet/)
|
||||
assert.equal([...aw.docs('newsPosts').values()].filter((d) => d.customerId === 'rn').length, 0)
|
||||
assert.equal([...aw.docs('newsPosts').values()].filter((d) => d.customerId === 'rn2').length, 1)
|
||||
assert.equal(existsSync(newsImagePath('rnp', imageId, 'l')), false)
|
||||
assert.equal(existsSync(newsImagePath('rntwop', other.imageId, 'l')), true)
|
||||
const feat = [...aw.docs('portalFeatures').values()].find((d) => d.$id === 'rn_feat')
|
||||
assert.equal(feat.state, 'disabled')
|
||||
assert.equal(feat.enabled, false)
|
||||
assert.equal([...aw.docs('portalFeatures').values()].find((d) => d.$id === 'rn2_feat').state, 'active')
|
||||
})
|
||||
Reference in new issue
Block a user