add: Kalendereinträge, Eingabeformular und Absenden-Button
This commit is contained in:
1 parent
6a9d31ca5e
commit
037ea11de5
7 files changed
+1173
-30
No files matched your search
@@ -28,6 +28,20 @@ Describe 'Perspektivwerk static route' {
|
||||
(Get-FileHash -LiteralPath $bookingStylesPath).Hash | Should Be (Get-FileHash -LiteralPath $contaoBookingStylesPath).Hash
|
||||
}
|
||||
|
||||
It 'keeps the enabled submit button visibly rendered' {
|
||||
$script = Get-Content -LiteralPath $contaoBookingScriptPath -Raw
|
||||
|
||||
$script | Should Match "submitButton\.style\.visibility = 'visible'"
|
||||
$script | Should Match "actions\.style\.position = 'sticky'"
|
||||
}
|
||||
|
||||
It 'defines colours for the booking form action buttons' {
|
||||
$styles = Get-Content -LiteralPath $contaoBookingStylesPath -Raw
|
||||
|
||||
$styles | Should Match '\.sufw-booking__form-actions button\s*\{[^}]*background-color:\s*#08752a'
|
||||
$styles | Should Match '\.sufw-booking__form-actions button\s*\{[^}]*color:\s*#fff'
|
||||
}
|
||||
|
||||
It 'routes /perspektivwerk to the static entry point before the Contao fallback' {
|
||||
$htaccess = Get-Content -LiteralPath $htaccessPath -Raw
|
||||
$staticRouteIndex = $htaccess.IndexOf('RewriteRule ^perspektivwerk/?$ perspektivwerk/index.html [L]')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { getSlotsForDate } from '../public/booking/booking.js';
|
||||
import { bookingConfirmationMessage, canSubmitBookingForm, formatDateKey, getSlotsForDate, validateBookingField, validateBookingForm } from '../public/booking/booking.js';
|
||||
|
||||
test('liefert für einen Beispieltag verfügbare und belegte Slots', () => {
|
||||
const slots = getSlotsForDate('perspektivwerk', '2026-08-25');
|
||||
@@ -14,3 +14,70 @@ test('liefert für einen Beispieltag verfügbare und belegte Slots', () => {
|
||||
test('liefert für einen Tag ohne Termin keine Slots', () => {
|
||||
assert.deepEqual(getSlotsForDate('produktionsschule', '2026-08-20'), []);
|
||||
});
|
||||
|
||||
test('verschiebt Kalendertage in der Sommerzeit nicht auf den Vortag', () => {
|
||||
process.env.TZ = 'Europe/Berlin';
|
||||
|
||||
assert.equal(formatDateKey(new Date(2026, 7, 24)), '2026-08-24');
|
||||
});
|
||||
|
||||
test('liefert Termine im aktuellen und folgenden Monat', () => {
|
||||
assert.ok(getSlotsForDate('perspektivwerk', '2026-08-24').length >= 2);
|
||||
assert.ok(getSlotsForDate('perspektivwerk', '2026-08-28').length >= 2);
|
||||
assert.ok(getSlotsForDate('perspektivwerk', '2026-09-02').length >= 2);
|
||||
assert.ok(getSlotsForDate('perspektivwerk', '2026-09-15').length >= 2);
|
||||
assert.ok(getSlotsForDate('perspektivwerk', '2026-09-29').length >= 2);
|
||||
});
|
||||
|
||||
test('validiert die Pflichtangaben der Buchungsmaske', () => {
|
||||
assert.deepEqual(
|
||||
validateBookingForm({ name: '', email: 'ungültig', privacyAccepted: false }),
|
||||
{
|
||||
name: 'Bitte geben Sie Ihren Namen ein.',
|
||||
email: 'Bitte geben Sie eine gültige E-Mail-Adresse ein.',
|
||||
privacy: 'Bitte bestätigen Sie die Datenschutzhinweise.'
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('akzeptiert die vollständigen Pflichtangaben der Buchungsmaske', () => {
|
||||
assert.deepEqual(
|
||||
validateBookingForm({ name: 'Max Mustermann', email: 'max@example.org', privacyAccepted: true }),
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
test('lehnt ein eingegebenes Alter außerhalb von 12 bis 112 ab', () => {
|
||||
assert.equal(
|
||||
validateBookingForm({ name: 'Max Mustermann', email: 'max@example.org', age: '11', privacyAccepted: true }).age,
|
||||
'Bitte geben Sie ein Alter zwischen 12 und 112 Jahren ein.'
|
||||
);
|
||||
assert.equal(
|
||||
validateBookingForm({ name: 'Max Mustermann', email: 'max@example.org', age: '113', privacyAccepted: true }).age,
|
||||
'Bitte geben Sie ein Alter zwischen 12 und 112 Jahren ein.'
|
||||
);
|
||||
});
|
||||
|
||||
test('akzeptiert ein leeres oder gültiges optionales Alter', () => {
|
||||
assert.deepEqual(validateBookingForm({ name: 'Max Mustermann', email: 'max@example.org', age: '', privacyAccepted: true }), {});
|
||||
assert.deepEqual(validateBookingForm({ name: 'Max Mustermann', email: 'max@example.org', age: '12', privacyAccepted: true }), {});
|
||||
assert.deepEqual(validateBookingForm({ name: 'Max Mustermann', email: 'max@example.org', age: '112', privacyAccepted: true }), {});
|
||||
});
|
||||
|
||||
test('validiert optionale Telefonnummern direkt am Feld', () => {
|
||||
assert.equal(validateBookingField('phone', 'abc'), 'Bitte geben Sie eine gültige Telefonnummer ein.');
|
||||
assert.equal(validateBookingField('phone', '+49 351 123456'), '');
|
||||
assert.equal(validateBookingField('phone', ''), '');
|
||||
});
|
||||
|
||||
test('gibt den Absenden-Button erst nach DSGVO-Einwilligung frei', () => {
|
||||
assert.equal(canSubmitBookingForm(false), false);
|
||||
assert.equal(canSubmitBookingForm(true), true);
|
||||
});
|
||||
|
||||
test('zeigt nach dem Absenden eine Bestätigung ohne Mockup-Hinweis', () => {
|
||||
const message = bookingConfirmationMessage('Erstgespräch');
|
||||
|
||||
assert.match(message, /erfolgreich übermittelt/);
|
||||
assert.doesNotMatch(message, /Vorschau|Mockup/i);
|
||||
});
|
||||
Reference in new issue
Block a user