Files
Webklar-Kundenbereich/test/knEinschaltenSeite.test.js
T

97 lines
6.3 KiB
JavaScript

import { test } from 'node:test'
import assert from 'node:assert/strict'
import { installFakeDom } from './support/fakeDom.js'
import { renderEinschalten } from '../public/neu/funktion-einschalten.js'
import { daten, projekt } from './support/knFunktionenDaten.js'
const JETZT = () => new Date('2026-10-20T10:00:00Z')
const FRIST = '2026-10-30T22:59:59.999Z'
const OK = { feature: { state: 'setup' }, ticketWoid: '100301' }
const mit = (fn) => async () => { const fx = installFakeDom(); try { await fn(fx) } finally { fx.restore() } }
function seite(fx, { antwort = () => OK, ...opt } = {}) {
const b = fx.document.createElement('div'); fx.document.body.append(b)
const aufrufe = []; const rueck = []
const api = async (pfad, o = {}) => { const a = { pfad, method: o.method ?? 'GET', body: o.body }; aufrufe.push(a); return antwort(a) }
const bei = { fertig: (a) => rueck.push(['fertig', a]), weiter: (w) => rueck.push(['weiter', w]), abbrechen: () => rueck.push(['abbrechen']) }
const el = renderEinschalten(b, { key: 'news', projectId: 'p1', daten: daten(), kundenartWirksam: 'unternehmen', jetzt: JETZT, api, bei, ...opt })
return { b, el, aufrufe, rueck }
}
const knopf = (fx, b) => fx.finde(b, '[data-aktion="einschalten"]')
const haken = (fx, b) => fx.alle(b, 'input[type="checkbox"]')
test('Betrieb: Fakten, Stundenkonto-Satz, Linkzeile, Knopf, kein Häkchen, kein Preis', mit((fx) => {
const { b } = seite(fx)
const t = fx.text(b)
assert.match(t, /News-Pinnwand einschalten/)
assert.match(t, /Leistung.*Einrichtung durch WEBklar/)
assert.match(t, /Dauer.*meist in wenigen Tagen/)
assert.match(t, /Laufzeit.*läuft, solange dein Wartungs-Abo läuft/)
assert.match(t, /Die Einrichtung geht von deinem Stundenkonto ab, auch wenn das Guthaben noch nicht reicht\. Extrakosten entstehen keine\./)
assert.match(t, /Es gelten Leistungsbeschreibung und Auftragsverarbeitung \(Fassung 2026-10-05\)\./)
assert.deepEqual(fx.alle(b, 'a').map((a) => a.getAttribute('href')), ['/rechtliches/leistungsbeschreibung-news-2026-10-05.html', '/rechtliches/avv-news-2026-10-05.html'])
assert.deepEqual(fx.alle(b, 'a').map((a) => [a.getAttribute('target'), a.getAttribute('rel')]), [['_blank', 'noopener noreferrer'], ['_blank', 'noopener noreferrer']])
assert.equal(haken(fx, b).length, 0)
assert.equal(knopf(fx, b).textContent, 'Einschalten')
assert.ok(fx.finde(b, '[data-aktion="abbrechen"]'))
assert.doesNotMatch(t, /€|Euro/)
}))
test('Privatkunde in der Frist: Häkchen sichtbar, Knopf nennt das Datum und bleibt gesperrt, bis das Häkchen sitzt', mit(async (fx) => {
const { b } = seite(fx, { kundenartWirksam: 'privat', daten: daten({ abo: { widerrufsfristBis: FRIST } }) })
const h1 = fx.finde(b, 'input[data-haken="beginn"]')
assert.equal(h1.checked, false)
assert.match(fx.text(b), /Bitte beginnt sofort mit der Einrichtung\./)
assert.deepEqual([knopf(fx, b).textContent, knopf(fx, b).disabled], ['Einschalten ab 31.10.', true])
await fx.klick(h1)
assert.deepEqual([knopf(fx, b).textContent, knopf(fx, b).disabled], ['Einschalten', false])
await fx.klick(h1)
assert.equal(knopf(fx, b).disabled, true)
}))
test('Häkchen nie für Betrieb, nie nach Fristende; leere Kundenart zählt als privat', mit((fx) => {
const d = daten({ abo: { widerrufsfristBis: FRIST } })
assert.equal(haken(fx, seite(fx, { daten: d, kundenartWirksam: 'unternehmen' }).b).length, 0)
assert.equal(haken(fx, seite(fx, { daten: d, kundenartWirksam: 'privat', jetzt: () => new Date('2026-10-31T09:00:00Z') }).b).length, 0)
assert.equal(haken(fx, seite(fx, { daten: d, kundenartWirksam: '' }).b).length, 1)
}))
test('Register fehlt: kein Absenden, freundlicher Text', mit((fx) => {
const { b } = seite(fx, { daten: daten({ katalogEdit: { news: { consent: null } } }) })
assert.match(fx.text(b), /Einschalten ist gerade nicht möglich\. Schreib uns im Chat\./)
assert.equal(knopf(fx, b), null)
}))
test('Kundenansicht (viewAs): Knopf gesperrt mit Hinweis', mit((fx) => {
const { b } = seite(fx, { viewAs: true })
assert.equal(knopf(fx, b).disabled, true)
assert.match(fx.text(b), /In der Kundenansicht kann nichts eingeschaltet werden\./)
}))
test('Fremdtext: HTML in Funktions- und Websitenamen nur als Text; Websitezeile erst ab zwei Websites', mit((fx) => {
const d = daten({ katalogEdit: { news: { name: '<img src=x onerror=alert(1)>' } }, projekte: [projekt('p1', '<b>Café</b>'), projekt('p2', 'Kiosk')] })
const { b } = seite(fx, { daten: d })
assert.equal(fx.alle(b, 'img').length + fx.alle(b, 'b').length, 0)
assert.match(fx.text(b), /<img src=x onerror=alert\(1\)> einschalten/)
assert.match(fx.text(b), /Website.*<b>Café<\/b>/)
assert.doesNotMatch(fx.text(seite(fx).b), /Website/)
}))
test('Hinweis ohne Haken (N17): über dem Knopf, nach der Linkzeile; Register ohne beginn-Item sperrt nur, wenn das Häkchen nötig ist', mit((fx) => {
const { b } = seite(fx, { key: 'shop' })
const hinweis = fx.finde(b, 'p.kn-fn-hinweis')
assert.match(fx.text(hinweis), /^Du verkaufst in eigenem Namen/)
const reihe = fx.alle(b, '*').map((el) => el.className)
assert.ok(reihe.indexOf('kn-fn-recht') < reihe.indexOf('kn-fn-hinweis') && reihe.indexOf('kn-fn-hinweis') < reihe.findIndex((c) => c.includes('kn-fn-knopf')))
assert.equal(fx.finde(seite(fx).b, 'p.kn-fn-hinweis'), null)
const ohneBeginn = daten({ katalogEdit: { news: { consent: { version: '2026-10-20', knopf: 'Einschalten', items: [{ id: 'einschalten-zeile', text: 'Es gilt die Leistungsbeschreibung (Fassung 2026-10-05).', haken: false }] } } } })
assert.ok(knopf(fx, seite(fx, { daten: ohneBeginn }).b)) // Betrieb braucht das Item nicht
const privat = seite(fx, { daten: { ...ohneBeginn, abo: { ...ohneBeginn.abo, widerrufsfristBis: FRIST } }, kundenartWirksam: 'privat' })
assert.equal(knopf(fx, privat.b), null) // Privatkunde in der Frist braucht es
assert.match(fx.text(privat.b), /Einschalten ist gerade nicht möglich/)
}))
test('Abo: Laufzeit nennt das Abo; Hosting-Abo bei einer Funktion des Hosting-Abos', mit((fx) => {
const d = daten({ abo: { produkt: 'hosting' }, katalogEdit: { news: { enthaltenIn: 'hosting' } } })
assert.match(fx.text(seite(fx, { daten: d }).b), /Laufzeit.*läuft, solange dein Hosting-Abo läuft/)
}))