Terminplaner: Staff-Aktivierung nur mit Zustimmung in Textform (Modus on), WOMS
Im Dialog "Terminplaner ohne Zahlung aktivieren?" erscheinen, wenn das Portal termine.textformNoetig meldet, der Haken (Leistungsbeschreibung und AVV in der Fassung, Ausschluss Gesundheitsbereich), das Datum der Zustimmung und der Weg (Chat | E-Mail) sowie die Textvorlage fuer den Chat mit Kopierknopf (versionierte Adressen aus dem Portal). "Ja" bleibt gesperrt, bis alles stimmt (canSubmitTextform mit minDate = Fassung); der Rumpf traegt textformDate und textformChannel. News und Abschalten bleiben unveraendert. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
857e001911
commit
45e5dc30dc
4 files changed
+256
-9
No files matched your search
@@ -17,6 +17,12 @@ const {
|
||||
anleitungPfad,
|
||||
panelModell,
|
||||
anleitungOffen,
|
||||
textformNoetig,
|
||||
termineTextformLabel,
|
||||
termineChatTemplate,
|
||||
textformAnsicht,
|
||||
textformBereit,
|
||||
featureBody,
|
||||
} = await loadModule('src/lib/funktionenView.js')
|
||||
|
||||
test('FUNKTIONEN: News und Terminplaner mit den Bestätigungstexten', () => {
|
||||
@@ -329,3 +335,118 @@ test('abgeschaltetText: außerhalb von "disabled" leer, auch mit Grund und Datum
|
||||
}
|
||||
for (const feature of [{}, null, undefined]) assert.equal(abgeschaltetText(feature), '', JSON.stringify(feature))
|
||||
})
|
||||
|
||||
// --- Staff-Aktivierung des Terminplaners nur mit Zustimmung in Textform (F13b; Portal F13a: GET ... => termine) ---
|
||||
|
||||
// Feld "termine" der Portal-Antwort GET /funktionen/:customerId
|
||||
const termine = (extra = {}) => ({
|
||||
textformNoetig: true,
|
||||
avvVersion: '2026-10-05',
|
||||
links: {
|
||||
lb: 'https://project.webklar.com/rechtliches/leistungsbeschreibung-terminplaner-2026-10-05.html',
|
||||
avv: 'https://project.webklar.com/rechtliches/avv-terminplaner-2026-10-05.html',
|
||||
},
|
||||
...extra,
|
||||
})
|
||||
|
||||
test('textformNoetig: nur "Aktivieren (ohne Zahlung)" des Terminplaners und nur, wenn das Portal es verlangt', () => {
|
||||
assert.equal(textformNoetig('termine', 'activate', termine()), true)
|
||||
assert.equal(textformNoetig('termine', 'activate', termine({ textformNoetig: false })), false)
|
||||
assert.equal(textformNoetig('termine', 'activate', undefined), false, 'altes Portal ohne Feld: wie bisher')
|
||||
assert.equal(textformNoetig('termine', 'activate', null), false)
|
||||
assert.equal(textformNoetig('termine', 'activate', termine({ textformNoetig: 'true' })), false, 'nur echtes true')
|
||||
for (const action of ['disable', 'abnahme', 'ticket']) assert.equal(textformNoetig('termine', action, termine()), false, action)
|
||||
for (const action of ['activate', 'disable']) assert.equal(textformNoetig('news', action, termine()), false, `News ${action}`)
|
||||
assert.equal(textformNoetig(undefined, 'activate', termine()), false)
|
||||
})
|
||||
|
||||
test('termineChatTemplate: wörtlich, mit Fassung und den beiden versionierten Adressen', () => {
|
||||
const { lb, avv } = termine().links
|
||||
assert.equal(
|
||||
termineChatTemplate('2026-10-05', { lb, avv }),
|
||||
'Damit wir den Terminplaner für Dich einschalten können, brauchen wir Deine Zustimmung in Textform. ' +
|
||||
'Es gelten die Leistungsbeschreibung Terminplaner und der Auftragsverarbeitungsvertrag Terminplaner in der Fassung 2026-10-05: ' +
|
||||
`${lb} · ${avv}. ` +
|
||||
'Bitte antworte hier mit „Ich stimme zu“ und bestätige, dass Dein Angebot nicht im Gesundheitsbereich liegt.',
|
||||
)
|
||||
const text = termineChatTemplate('2026-10-05', { lb, avv })
|
||||
assert.match(text, /leistungsbeschreibung-terminplaner-2026-10-05\.html/)
|
||||
assert.match(text, /avv-terminplaner-2026-10-05\.html/)
|
||||
assert.ok(!text.includes('undefined') && !text.includes('{'))
|
||||
})
|
||||
|
||||
test('termineTextformLabel: Dialogtext des Kästchens nennt beide Unterlagen, die Fassung und den Ausschluss des Gesundheitsbereichs', () => {
|
||||
const l = termineTextformLabel('2026-10-05')
|
||||
assert.equal(l.lb, 'Leistungsbeschreibung Terminplaner')
|
||||
assert.equal(l.avv, 'Auftragsverarbeitungsvertrag Terminplaner')
|
||||
assert.equal(
|
||||
l.before + l.lb + l.between + l.avv + l.after,
|
||||
'Der Kunde hat der Leistungsbeschreibung Terminplaner und dem Auftragsverarbeitungsvertrag Terminplaner (Fassung 2026-10-05) ' +
|
||||
'in Textform zugestimmt und bestätigt, dass sein Angebot nicht im Gesundheitsbereich liegt.',
|
||||
)
|
||||
})
|
||||
|
||||
test('textformAnsicht: Fassung, geprüfte https-Adressen, Label und Vorlage aus dem Portal-Feld', () => {
|
||||
const a = textformAnsicht(termine())
|
||||
assert.equal(a.version, '2026-10-05')
|
||||
assert.deepEqual(a.links, termine().links)
|
||||
assert.deepEqual(a.label, termineTextformLabel('2026-10-05'))
|
||||
assert.equal(a.vorlage, termineChatTemplate('2026-10-05', termine().links))
|
||||
})
|
||||
|
||||
test('textformAnsicht: Adressen ohne https werden nie Link, ohne beide Adressen keine Vorlage', () => {
|
||||
const schlecht = textformAnsicht(termine({ links: { lb: 'javascript:alert(1)', avv: 'http://project.webklar.com/x.html' } }))
|
||||
assert.deepEqual(schlecht.links, { lb: '', avv: '' })
|
||||
assert.equal(schlecht.vorlage, '', 'eine Vorlage mit leeren Adressen geht nie an den Kunden')
|
||||
const halb = textformAnsicht(termine({ links: { lb: termine().links.lb } }))
|
||||
assert.equal(halb.links.avv, '')
|
||||
assert.equal(halb.vorlage, '')
|
||||
for (const leer of [undefined, null, {}, { links: null }]) {
|
||||
const a = textformAnsicht(leer)
|
||||
assert.equal(a.version, '')
|
||||
assert.deepEqual(a.links, { lb: '', avv: '' })
|
||||
assert.equal(a.vorlage, '')
|
||||
}
|
||||
})
|
||||
|
||||
test('textformBereit: canSubmitTextform mit minDate = Fassung (Grenzen eingeschlossen), today = heute in Berlin', () => {
|
||||
const t = termine()
|
||||
const ok = { confirmed: true, date: '2026-10-06', channel: 'chat', today: '2026-10-07' }
|
||||
assert.equal(textformBereit(ok, t), true)
|
||||
assert.equal(textformBereit({ ...ok, date: '2026-10-05' }, t), true, 'Tag der Fassung selbst')
|
||||
assert.equal(textformBereit({ ...ok, date: '2026-10-07' }, t), true, 'heute')
|
||||
assert.equal(textformBereit({ ...ok, channel: 'email' }, t), true)
|
||||
assert.equal(textformBereit({ ...ok, date: '2026-10-04' }, t), false, 'vor der Fassung')
|
||||
assert.equal(textformBereit({ ...ok, date: '2026-10-08' }, t), false, 'Zukunft')
|
||||
assert.equal(textformBereit({ ...ok, confirmed: false }, t), false)
|
||||
assert.equal(textformBereit({ ...ok, date: '' }, t), false)
|
||||
assert.equal(textformBereit({ ...ok, date: 'morgen' }, t), false)
|
||||
assert.equal(textformBereit({ ...ok, channel: '' }, t), false)
|
||||
assert.equal(textformBereit({ ...ok, channel: 'telefon' }, t), false)
|
||||
})
|
||||
|
||||
test('textformBereit: ohne Fassung im Portal-Feld nie bereit (fail closed)', () => {
|
||||
const ok = { confirmed: true, date: '2026-10-06', channel: 'chat', today: '2026-10-07' }
|
||||
assert.equal(textformBereit(ok, termine({ avvVersion: '' })), false)
|
||||
assert.equal(textformBereit(ok, undefined), false)
|
||||
assert.equal(textformBereit(ok, null), false)
|
||||
})
|
||||
|
||||
test('featureBody: Aktivieren mit Textform trägt Datum und Weg, sonst bleibt der Rumpf wie bisher', () => {
|
||||
assert.deepEqual(
|
||||
featureBody({ projectId: 'p1', action: 'activate', note: 'Pilot', textformDate: '2026-10-06', textformChannel: 'chat' }),
|
||||
{ projectId: 'p1', action: 'activate', note: 'Pilot', textformDate: '2026-10-06', textformChannel: 'chat' },
|
||||
)
|
||||
assert.deepEqual(featureBody({ projectId: 'p1', action: 'activate', note: '' }), { projectId: 'p1', action: 'activate', note: '' })
|
||||
assert.deepEqual(featureBody({ projectId: 'p1', action: 'disable', note: 'x' }), { projectId: 'p1', action: 'disable', note: 'x' })
|
||||
assert.deepEqual(
|
||||
featureBody({ projectId: 'p1', action: 'disable', note: 'x', textformDate: '2026-10-06', textformChannel: 'chat' }),
|
||||
{ projectId: 'p1', action: 'disable', note: 'x' },
|
||||
'Abschalten sendet nie Textform-Angaben',
|
||||
)
|
||||
assert.deepEqual(
|
||||
featureBody({ projectId: 'p1', action: 'activate', note: '', textformDate: '2026-10-06', textformChannel: '' }),
|
||||
{ projectId: 'p1', action: 'activate', note: '' },
|
||||
'halbe Angaben gehen nicht mit',
|
||||
)
|
||||
})
|
||||
Reference in new issue
Block a user