Rechtsrunde: Wechsel erst mit Zahlung, Zusatzspeicher teilweise kündbar, Aufbewahrung nach dem letzten Abo

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-09-28 08:19:29 +00:00
1 parent 91d9360dd2
commit 478fbae3aa
5 files changed
+63 -16

No files matched your search

+50 -3
View File
@@ -151,7 +151,7 @@ test('Wechsel, Plus und Minus im Portal nur ohne Kündigung und ohne offene Zahl
assert.ok(speicher[0].includes('nicht gekündigt'), '§ 10 Abs. 1 (Bestellen und Ändern im Portal)')
assert.ok(speicher[4].includes('nicht gekündigt'), '§ 10 Abs. 5 (Verringern mit „Speichern“)')
assert.ok(speicher[4].includes('„Nur den E-Mail-Zusatzspeicher“'))
assert.ok(speicher[4].includes('kann der Kunde die Zahl der Pakete nur noch in Textform verringern'))
assert.ok(speicher[4].includes('kann der Kunde die Zahl der Pakete nur noch über „Verträge hier kündigen“ oder in Textform verringern'))
assert.ok(!speicher[4].includes('auch eine Verringerung'))
// Übersicht: dieselben Bedingungen wie § 9 Abs. 1 und § 10 Abs. 1, kein unbedingtes "jederzeit"
for (const name of ['E-Mail-Zusatzspeicher', 'Wechsel']) {
@@ -323,12 +323,59 @@ test('Datenschutz Abschnitt 7: Nachweisdaten je Bestellung, Vertragsereignisse,
assert.ok(abos.includes('nur Zeitpunkt und Status, keine IP-Adresse und Browserkennung'))
assert.ok(abos.includes('Den Stand Ihrer Bestellungen, etwa laufende Widerrufsfristen und die Einrichtung von Zusatzspeicher, sehen Sie im Kundenportal unter „Verträge“.'))
assert.ok(abos.includes('Aufgabenliste, um Änderungen am Zusatzspeicher umzusetzen'))
assert.ok(sentence(abos, 'Diese Angaben löschen wir').includes('drei Jahre nach Vertragsende'))
assert.ok(sentence(abos, 'Diese Angaben löschen wir').includes('drei Jahre nach dem Ende Ihres letzten Abos'))
// Öffentliche Kündigungs- und Widerrufsseite (§§ 312k, 356a BGB): Daten, Zweck, Rechtsgrundlage, IP nur zur Begrenzung
const formulare = between(abos, 'kuendigen.html', 'Abschnitt 9')
for (const s of ['widerrufen.html', 'ohne Anmeldung', 'Namen', 'E-Mail-Adresse', 'Kundennummer', 'Eingang', 'Bestätigung', 'Team',
'Art. 6 Abs. 1 lit. c DSGVO', '§§ 312k, 356a BGB', 'lit. b', 'IP-Adresse', 'Arbeitsspeicher', 'zehn',
'drei Jahre nach Vertragsende']) assert.ok(formulare.includes(s), `Formulare: ${s}`)
'drei Jahre nach dem Ende Ihres letzten Abos', 'Zahl der Pakete']) assert.ok(formulare.includes(s), `Formulare: ${s}`)
})
// --- Rechtsrunde 28.09.2026 (Spec § 14: Wechsel erst mit Zahlung, Zusatzspeicher teilweise kündbar, Aufbewahrung) ---
test('Rechtsrunde: Wechsel steht unter der Bedingung der Zahlung (§ 9 Abs. 3, § 2 Abs. 5, § 7 Abs. 4, Übersicht)', () => {
const wechsel = absaetzeVon('wechsel', 'zusatzspeicher')
assert.equal(wechsel.length, 5)
for (const s of ['Der Wechsel steht unter der Bedingung, dass die Wechselrechnung bezahlt wird.',
'Bei Zahlung per Kreditkarte wird er erst mit der erfolgreichen Zahlung wirksam',
'Bei SEPA-Lastschrift beginnt das Wartungs-Abo schon mit der Bestellung; wird die Lastschrift nicht eingelöst, gilt der Wechsel als nicht erfolgt.',
'läuft das Hosting-Abo mit Preis und Mindestlaufzeit wie vor dem Wechsel weiter; wir informieren den Kunden per E-Mail.',
'Das Wartungs-Abo beginnt, sobald der Wechsel wirksam ist',
'Wechseltag ist der Tag der Bestellung']) assert.ok(wechsel[2].includes(s), `§ 9 Abs. 3: ${s}`)
assert.ok(!v4Section('wechsel', 'zusatzspeicher').includes('beginnt sofort mit dem Wechsel'))
assert.ok(wechsel[1].includes('Wird der Wechsel wirksam, endet das Hosting-Abo im gegenseitigen Einvernehmen.'))
assert.ok(absaetzeVon('p2', 'p3')[4].includes('beim Wechsel steht er unter der Bedingung des § 9 Abs. 3 (Zahlung der Wechselrechnung)'))
assert.ok(absaetzeVon('p7', 'p8')[3].includes('Wird die Wechselrechnung nicht bezahlt, gilt § 9 Abs. 3.'))
assert.ok(absaetzeVon('p4', 'p5')[0].includes('mit der Zahlung der Wechselrechnung (§ 9 Abs. 3)'))
assert.ok(uebersichtZeile('Wechsel').includes('unter der Bedingung, dass die Wechselrechnung bezahlt wird'))
})
test('Rechtsrunde: Zusatzspeicher ganz oder teilweise kündbar, auch über „Verträge hier kündigen“ (§ 8 Abs. 7 und 8, § 10 Abs. 5, Übersicht)', () => {
const p8 = absaetzeVon('p8', 'wechsel')
assert.equal(p8.length, 8)
assert.ok(p8[6].includes('ganz oder teilweise (mit einer geringeren Zahl von Paketen) kündigen'))
assert.ok(p8[7].includes('ganz oder mit der Zahl der Pakete, die er kündigt'))
assert.ok(p8[7].includes('auch, wenn das Abo schon gekündigt ist'))
const abs5 = absaetzeVon('zusatzspeicher', 'p11')[4]
assert.ok(abs5.includes('Den Zusatzspeicher ganz oder teilweise kündigen kann er jederzeit über „Verträge hier kündigen“ mit der Auswahl „Nur den E-Mail-Zusatzspeicher“ und der Zahl der Pakete oder in Textform (§ 8 Abs. 8)'))
assert.ok(abs5.includes('nach einer Kündigung des Abos kann der Kunde die Zahl der Pakete nur noch über „Verträge hier kündigen“ oder in Textform verringern'))
assert.ok(uebersichtZeile('Kündigen').includes('ganz oder mit der Zahl der Pakete'))
assert.ok(uebersichtZeile('E-Mail-Zusatzspeicher').includes('ganz oder teilweise kündbar'))
})
test('Rechtsrunde Datenschutz: Aufbewahrung nach dem Ende des letzten Abos, Zahl der Pakete, kurzer UptimeRobot-Eintrag', () => {
const html = read(DS), ds = strip(html)
assert.equal(ds.split('drei Jahre nach dem Ende Ihres letzten Abos').length - 1, 2, 'Abschnitt 7 und Kündigungs-/Widerrufsseite')
assert.ok(!ds.includes('drei Jahre nach Vertragsende'))
// Übernahmegutschrift und Abschnitt 9 behalten ihre eigenen Fristen
assert.ok(ds.includes('sechs Monate nach der Entscheidung'))
assert.ok(ds.includes('acht Jahre auf (§ 147 AO, § 14b UStG), Handels- und Geschäftsbriefe sechs Jahre'))
assert.ok(between(ds, 'kuendigen.html', 'Abschnitt 9').includes('beim E-Mail-Zusatzspeicher die Zahl der Pakete, die Sie kündigen'))
// Abschnitt 12: der UptimeRobot-Eintrag etwa so lang wie seine Nachbarn, mit Drittland und Rolle
const empfaenger = [...html.slice(html.indexOf('12. Empfänger'), html.indexOf('13. Ihre Rechte')).matchAll(/<li>([\s\S]*?)<\/li>/g)].map((m) => strip(m[1]))
const robot = empfaenger.find((e) => e.startsWith('UptimeRobot'))
assert.ok(robot.includes('(insbesondere USA)') && robot.includes('Auftragsverarbeiter') && robot.includes('Abschnitt 3'), robot)
assert.ok(robot.length <= 135, `UptimeRobot-Eintrag zu lang: ${robot.length} Zeichen`)
})
// --- Übernahmegutschrift, Prüftexte, Leitfaden (Plan 2, Task 3) ---