From 28da4180bd38faf66cabc9e2ecc16af91616c87b Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 18:45:17 +0000 Subject: [PATCH] Webshop: im Abo-Modell Anfrage ohne Unternehmer-Haken, Privat-Hinweis, Einschalten Co-Authored-By: Claude Sonnet 5.5 --- public/shop-anfrage.js | 21 ++-- public/shop.js | 25 +++- test/kundenansichtNeuModulEinschalten.test.js | 6 +- test/kundenansichtNeuModulReiter.test.js | 4 +- test/kundenansichtNeuModulShop.test.js | 109 ++++++++++++++++++ test/kundenansichtNeuModulTermine.test.js | 2 +- test/shopWiring.test.js | 2 +- 7 files changed, 147 insertions(+), 22 deletions(-) create mode 100644 test/kundenansichtNeuModulShop.test.js diff --git a/public/shop-anfrage.js b/public/shop-anfrage.js index 8d6aea3..3e3eff1 100644 --- a/public/shop-anfrage.js +++ b/public/shop-anfrage.js @@ -31,10 +31,13 @@ export const anfrageListe = (anfrage) => h('dl', { class: 'sh-fakten' }, anfrage /** * Formular „Webshop anfragen“ in root. optionen: projectId, vorgabe (frueherer Stand der Anfrage zum Vorausfuellen), preis ('299 €'), - * ustHinweis (Satz zur Umsatzsteuer), nachSenden(anfrage) (die Anfrage ist gespeichert: die Ansicht zeichnet sich neu). + * ustHinweis (Satz zur Umsatzsteuer), nachSenden(anfrage) (die Anfrage ist gespeichert: die Ansicht zeichnet sich neu), modell ('abo': kein + * Preis und keine Umsatzsteuer, kein Feld „unternehmer“, statt des Hakens „keine ausgeschlossenen Waren“ ein Satz über dem Knopf; gesendet wird + * keineAusgeschlossenen: true, unternehmer entfällt – die Kundenart kennt der Server). * Der Server prueft alles; ein 409 (z. B. laeuft schon eine Anfrage) zeigt seinen Text und laesst die Ansicht neu laden. */ -export function renderAnfrageFormular(root, { projectId, vorgabe = null, preis = '299 €', ustHinweis = '', nachSenden } = {}) { +export function renderAnfrageFormular(root, { projectId, vorgabe = null, preis = '299 €', ustHinweis = '', nachSenden, modell } = {}) { + const abo = modell === 'abo' // Abo-Modell (strikt): ohne Preis, ohne Unternehmer-Haken, der Satz S2 statt des Hakens const v = vorgabe && typeof vorgabe === 'object' ? vorgabe : {} const auswahl = (liste, aktuell) => { const optionen = [h('option', { value: '' }, 'Bitte wählen …'), ...liste.map(([wert, name]) => h('option', { value: wert }, name))] @@ -64,10 +67,11 @@ export function renderAnfrageFormular(root, { projectId, vorgabe = null, preis = h('legend', null, 'Wie bekommen deine Kunden die Ware?'), hakenFeld('versand', versand, 'Versand'), hakenFeld('abholung', abholung, 'Abholung')), - hakenFeld('unternehmer', unternehmer, 'Ich verkaufe als Unternehmer (nicht privat).'), - hakenFeld('keineAusgeschlossenen', ausgeschlossen, `Ich verkaufe keine ausgeschlossenen Waren (${AUSGESCHLOSSEN}).`), + abo ? null : hakenFeld('unternehmer', unternehmer, 'Ich verkaufe als Unternehmer (nicht privat).'), + abo ? null : hakenFeld('keineAusgeschlossenen', ausgeschlossen, `Ich verkaufe keine ausgeschlossenen Waren (${AUSGESCHLOSSEN}).`), feld('nachricht', 'Noch etwas, das wir wissen sollten? (freiwillig)', nachricht), allgemeinerFehler(), + abo ? h('p', { class: 'sh-hinweis', 'data-satz': 'ausgeschlossen' }, `Mit „Anfrage senden“ bestätigst du, dass du keine ausgeschlossenen Waren verkaufst (${AUSGESCHLOSSEN}).`) : null, h('div', { class: 'sh-aktionen' }, absenden)) let laeuft = false @@ -88,8 +92,7 @@ export function renderAnfrageFormular(root, { projectId, vorgabe = null, preis = artikelzahl: artikelzahl.value, versand: versand.checked, abholung: abholung.checked, - unternehmer: unternehmer.checked, - keineAusgeschlossenen: ausgeschlossen.checked, + ...(abo ? { keineAusgeschlossenen: true } : { unternehmer: unternehmer.checked, keineAusgeschlossenen: ausgeschlossen.checked }), nachricht: nachricht.value.trim(), }, }, @@ -112,12 +115,12 @@ export function renderAnfrageFormular(root, { projectId, vorgabe = null, preis = h('h3', null, 'Webshop anfragen'), h('p', null, 'Mit dem Webshop verkaufst du direkt auf deiner Website: deine Kunden legen Artikel in den Warenkorb und bezahlen online.'), h('ul', null, - h('li', null, `${preis} einmalig für den Einbau in deine Website, keine laufende Gebühr von WEBklar.`), + h('li', null, abo ? 'Im Wartungs-Abo enthalten.' : `${preis} einmalig für den Einbau in deine Website, keine laufende Gebühr von WEBklar.`), h('li', null, 'Die Zahlungen gehen direkt auf dein eigenes Stripe-Konto. Die Gebühren von Stripe zahlst du direkt an Stripe.'), h('li', null, 'Deine Kunden zahlen mit Karte, Apple Pay, Google Pay, Klarna oder SEPA-Lastschrift.'), h('li', null, 'PayPal ist über Stripe leider nicht möglich.'), - h('li', null, 'Wir sehen uns deine Anfrage kurz an. Erst nach unserer Zusage kannst du bestellen.')), - ustHinweis ? h('p', { class: 'sh-hinweis' }, ustHinweis) : null) + h('li', null, abo ? 'Wir sehen uns deine Anfrage kurz an. Erst nach unserer Zusage kannst du einschalten.' : 'Wir sehen uns deine Anfrage kurz an. Erst nach unserer Zusage kannst du bestellen.')), + ustHinweis && !abo ? h('p', { class: 'sh-hinweis' }, ustHinweis) : null) const karte = h('section', { class: 'kb-panel sh-anfrage' }, erklaerung, form) root.replaceChildren(karte) diff --git a/public/shop.js b/public/shop.js index 6a3c5f5..dcac5a6 100644 --- a/public/shop.js +++ b/public/shop.js @@ -15,7 +15,7 @@ import { fehlerKarte, h, infoKarte, request } from './shop-dom.js' import { anfrageKarte, anfrageZeilen, renderAnfrageFormular } from './shop-anfrage.js' -import { renderBestellen, statusKarte } from './funktion-bestellen.js' +import { renderBestellen, renderEinschaltSeite, statusKarte } from './funktion-bestellen.js' import { meldeReiter, reiterEintraege } from './fn-reiter.js' /** Die Reiter: jeder ein Modul mit render(panel, ctx), erst beim ersten Oeffnen geladen. */ @@ -31,6 +31,8 @@ const HINWEIS_SETUP = 'Wir bauen deinen Shop gerade ein. Du kannst schon Artikel const HINWEIS_ABGESCHALTET = 'Dein Webshop ist abgeschaltet. Du kannst Bestellungen noch ansehen, bearbeiten, erstatten und exportieren.' const DANKE_SETUP = 'Danke! Die Zahlung ist bei uns angekommen.' const NICHT_VERFUEGBAR = 'Der Webshop ist noch nicht verfügbar.' +const PRIVAT_TITEL = 'Der Webshop ist für Betriebe' // Abo-Modell, Text S3 +const PRIVAT_TEXT = 'Für Privatpersonen gibt es den Webshop leider nicht. Stimmt das nicht? Schreib uns im Chat.' const SHOP_PREIS = '299 €' const DOKUMENT_TITEL = [ ['leistungsbeschreibung', 'Leistungsbeschreibung'], @@ -66,22 +68,22 @@ function leseRueckkehr() { return { bestellt: query.get('bestellt') === '1', stripe: stripe === 'zurueck' || stripe === 'neu' ? stripe : '', projekt: query.get('projekt') || '' } } -export function initShop(root, { projectId } = {}) { +export function initShop(root, { projectId, einschalten } = {}) { if (!root) return Promise.resolve() - return starte(root, projectId) + return starte(root, projectId, einschalten) } -async function starte(root, projectId) { +async function starte(root, projectId, einschalten) { const rueckkehr = leseRueckkehr() const wunsch = rueckkehr.projekt || projectId || root.dataset?.wunschProjekt || '' // die Kachel in Funktionen legt ihr Projekt hier ab if (root.dataset) delete root.dataset.wunschProjekt if (wunsch) auswahl.projectId = wunsch - const s = { root, projects: [], funktionen: null, projekt: null, status: null, lauf: 0, buehne: null, meldungEl: null, danke: false, stripe: '', neueAnfrage: false } + const s = { root, projects: [], funktionen: null, projekt: null, status: null, lauf: 0, buehne: null, meldungEl: null, danke: false, stripe: '', neueAnfrage: false, einschalten } S = s try { await ladeFunktionen(s) } catch (err) { - if (S === s) root.replaceChildren(fehlerKarte(err.message, () => starte(root, auswahl.projectId))) + if (S === s) root.replaceChildren(fehlerKarte(err.message, () => starte(root, auswahl.projectId, einschalten))) return } if (S !== s) return @@ -217,6 +219,11 @@ function zeigeAnfrage(s, { status, aktuell }) { s.buehne.replaceChildren(anfrageKarte(ansicht, { projectId, neu: () => { s.neueAnfrage = true; zeigeAnfrage(s, { status, aktuell }) } })) return } + // Abo-Modell: den Webshop gibt es nur fuer Betriebe; Privatkunden und eine leere oder fehlende Kundenart (E4) bekommen den Hinweis statt des Formulars + if (istAbo(s) && s.funktionen.kundenart !== 'unternehmen') { + s.buehne.replaceChildren(infoKarte(PRIVAT_TITEL, PRIVAT_TEXT, { chat: true })) + return + } // keine Anfrage, zurueckgezogen oder „Neue Anfrage stellen“: das Formular, mit den frueheren Angaben vorausgefuellt const wurzel = h('div', { class: 'sh-wurzel' }) s.buehne.replaceChildren(wurzel) @@ -225,6 +232,7 @@ function zeigeAnfrage(s, { status, aktuell }) { vorgabe: ansicht?.anfrage || null, preis: text(f?.priceLabel) || SHOP_PREIS, ustHinweis: text(s.funktionen?.ustHinweis), + modell: s.funktionen?.modell, nachSenden: async () => { s.neueAnfrage = false; await ladeNeu(s) }, }) } @@ -274,6 +282,11 @@ function zeigeBestellseite(s, { status, aktuell }) { }, } const daten = bestelldaten(s, status) + if (istAbo(s)) { + // Abo-Modell: die Zusage der Anfrage fuehrt zum Einschalten (kein Preis, keine Haken, kein Checkout) + renderEinschaltSeite(wurzel, { ctx, daten, key: 'shop', zusammenfassung: zusammenfassungVon(daten.anfrage), einschalten: s.einschalten, nachEinschalten: () => ladeNeu(s) }) + return + } renderBestellen(wurzel, { ctx, daten, key: 'shop', zusammenfassung: zusammenfassungVon(daten.anfrage) }) } diff --git a/test/kundenansichtNeuModulEinschalten.test.js b/test/kundenansichtNeuModulEinschalten.test.js index 1a48ec6..780e15b 100644 --- a/test/kundenansichtNeuModulEinschalten.test.js +++ b/test/kundenansichtNeuModulEinschalten.test.js @@ -23,7 +23,7 @@ test('mountet den Ablauf genau einmal in den Platz, mit key, projectId und viewA assert.deepEqual([a.aufrufe[0].key, a.aufrufe[0].projectId, a.aufrufe[0].viewAs], ['shop', 'p1', false]) assert.ok(a.aufrufe[0].wurzel === fx.finde(wurzel, '[data-einschalten="shop"]')) assert.ok(fx.finde(wurzel, '.tm-einschalten-platz')) - assert.equal(fx.finde(wurzel, 'h3'), null) + assert.ok(fx.finde(wurzel, 'h3') === null) assert.equal(fx.alle(wurzel, 'input').length, 0) assert.doesNotMatch(fx.text(wurzel), KEIN_PREIS) const hulle = fx.finde(wurzel, 'section.kb-panel.tm-bestellen.tm-einschalten') @@ -36,7 +36,7 @@ test('Zusammenfassung mit E1; offene Punkte sperren den Ablauf (E2); „Ändern const wurzel = seite({ einschalten: a.fn, zusammenfassung: GRUPPEN, zumSchritt: (k) => schritte.push(k), daten: { offen: [{ schritt: 'zeiten', text: 'Bitte wähle das Bundesland.' }], kundenansicht: false } }) assert.equal(fx.text(fx.finde(wurzel, 'h3')), 'Prüfen und einschalten') assert.equal(a.aufrufe.length, 0) - assert.equal(fx.finde(wurzel, '.tm-einschalten-platz'), null) + assert.ok(fx.finde(wurzel, '.tm-einschalten-platz') === null) assert.match(fx.text(wurzel), /Du kannst einschalten, sobald die offenen Punkte erledigt sind\./) assert.doesNotMatch(fx.text(wurzel), /bestellen/i) await fx.klick(fx.finde(wurzel, '[data-aktion="zum-schritt"][data-schritt="zeiten"]')) @@ -51,7 +51,7 @@ test('Zusammenfassung ohne offene Punkte: Gruppe, dann der Platz mit dem Ablauf' assert.equal(fx.text(fx.finde(wurzel, '.tm-bestellen-gruppe h4')), 'Deine Anfrage') assert.equal(a.aufrufe.length, 1) assert.doesNotMatch(fx.text(wurzel), /Du kannst einschalten, sobald/) - assert.equal(fx.finde(wurzel, '[data-aktion="aendern"]'), null, 'ohne zumSchritt kein „Ändern“') + assert.ok(fx.finde(wurzel, '[data-aktion="aendern"]') === null, 'ohne zumSchritt kein „Ändern“') })) test('Kundenansicht: der Ablauf bekommt viewAs true (daten und ctx)', mitDom(async () => { diff --git a/test/kundenansichtNeuModulReiter.test.js b/test/kundenansichtNeuModulReiter.test.js index 6c32259..e1c274d 100644 --- a/test/kundenansichtNeuModulReiter.test.js +++ b/test/kundenansichtNeuModulReiter.test.js @@ -87,8 +87,8 @@ for (const f of FAELLE) { test(`${f.name}, Abo: keine eigene Leiste, kn:reiter mit Kurzlabels, bei() wechselt`, mitDom(async (fx) => { const k = hoereAufKn(fx) const root = await oeffne(fx, f, 'abo') - assert.equal(fx.finde(root, '[role="tablist"]'), null) - assert.equal(fx.finde(root, '[role="tab"]'), null) + assert.ok(fx.finde(root, '[role="tablist"]') === null) + assert.ok(fx.finde(root, '[role="tab"]') === null) const panel = fx.finde(root, '[role="tabpanel"]') assert.ok(panel, 'das Panel bleibt') assert.equal(panel.hasAttribute('aria-labelledby'), false) diff --git a/test/kundenansichtNeuModulShop.test.js b/test/kundenansichtNeuModulShop.test.js new file mode 100644 index 0000000..bbf74e4 --- /dev/null +++ b/test/kundenansichtNeuModulShop.test.js @@ -0,0 +1,109 @@ +import { test } from 'node:test' +import assert from 'node:assert/strict' +import { h } from '../public/shop-dom.js' +import { initShop, vergissAuswahl } from '../public/shop.js' +import { AUSGESCHLOSSEN } from '../public/shop-anfrage.js' +import { KEIN_PREIS, einschaltenAttrappe, hoereAufKn, mitDom, routen } from './support/modulAbo.js' + +// Webshop im Abo-Modell (P4 Task 5): Anfrage ohne Unternehmer-Haken und ohne Preis, Satz über dem Knopf, Hinweis für Privatkunden, +// nach der Zusage der Ablauf des Einschaltens statt der Bestellseite. Ohne modell === 'abo' bleibt alles wie heute. + +const ANFRAGE = { warenart: 'kleidung', beschreibung: 'Handgemachte Mützen und Schals.', artikelzahl: 'bis20', versand: true, abholung: false, unternehmer: true, keineAusgeschlossenen: true, nachricht: '' } +const funk = (state, kopf = {}) => ({ + projects: [{ projectId: 'p1', projectName: 'Mein Laden', features: { shop: { state } } }], + features: { shop: { priceLabel: '299 €', consent: { version: 'v', knopf: 'Zahlungspflichtig bestellen · 299 €', items: [] } } }, + ustHinweis: 'einmalig, ohne Umsatzsteuer gemäß § 19 UStG', + legal: { shop: {} }, + shop: { verfuegbar: true }, + ...kopf, +}) +async function oeffne(fx, { kopf = {}, state = 'off', anfrage = null, einschalten } = {}) { + vergissAuswahl() + routen(fx, { + 'GET /api/funktionen': { body: funk(state, kopf) }, + 'GET /api/shop/status?projectId=p1': { body: { verfuegbar: true, state, ticketWoid: null, anfrage } }, + 'POST /api/shop/anfrage': { body: { anfrage: {} } }, + }) + const root = h('div') + document.body.append(root) + await initShop(root, { projectId: 'p1', einschalten }) + await fx.ruhe() + return root +} +const ZUGESAGT = { status: 'angenommen', anfrage: ANFRAGE, at: '2026-10-05T10:30:00.000Z' } + +test('Abo, Betrieb: Anfrage ohne Unternehmer-Haken, Satz S2 über dem Knopf, kein Preis; Körper ohne unternehmer', mitDom(async (fx) => { + const root = await oeffne(fx, { kopf: { modell: 'abo', kundenart: 'unternehmen' } }) + assert.ok(fx.finde(root, '[data-feld="unternehmer"]') === null) + assert.ok(fx.finde(root, '[data-feld="keineAusgeschlossenen"]') === null) + const satz = fx.finde(root, '[data-satz="ausgeschlossen"]') + assert.equal(fx.text(satz), `Mit „Anfrage senden“ bestätigst du, dass du keine ausgeschlossenen Waren verkaufst (${AUSGESCHLOSSEN}).`) + const knoten = fx.alle(root, '*') + assert.ok(knoten.indexOf(satz) < knoten.indexOf(fx.finde(root, '[data-aktion="anfrage-senden"]')), 'Satz steht über dem Knopf') + const erklaerung = fx.text(fx.finde(root, '.sh-erklaerung')) + assert.match(erklaerung, /Im Wartungs-Abo enthalten\./) + assert.match(erklaerung, /Wir sehen uns deine Anfrage kurz an\. Erst nach unserer Zusage kannst du einschalten\./) + assert.doesNotMatch(erklaerung, KEIN_PREIS) + assert.doesNotMatch(erklaerung, /bestellen/) + assert.doesNotMatch(fx.text(root), KEIN_PREIS) + await fx.setze(fx.finde(root, '[data-feld="warenart"]'), 'kleidung') + await fx.setze(fx.finde(root, '[data-feld="beschreibung"]'), 'Handgemachte Mützen und Schals.') + await fx.setze(fx.finde(root, '[data-feld="artikelzahl"]'), 'bis20') + await fx.klick(fx.finde(root, '[data-feld="versand"]')) + await fx.klick(fx.finde(root, '[data-aktion="anfrage-senden"]')) + assert.deepEqual(fx.fetchLog.find((a) => a.method === 'POST').body, { + projectId: 'p1', + anfrage: { warenart: 'kleidung', beschreibung: 'Handgemachte Mützen und Schals.', artikelzahl: 'bis20', versand: true, abholung: false, keineAusgeschlossenen: true, nachricht: '' }, + }) +})) + +test('Abo, privat oder Kundenart leer/fehlend: Hinweis S3 mit Chat, nie das Formular, kein POST, leere Reiterliste', mitDom(async (fx) => { + const k = hoereAufKn(fx) + for (const kundenart of ['privat', '', undefined]) { + const root = await oeffne(fx, { kopf: { modell: 'abo', kundenart } }) + assert.ok(fx.finde(root, 'form') === null, String(kundenart)) + assert.match(fx.text(root), /Der Webshop ist für Betriebe/) + assert.match(fx.text(root), /Für Privatpersonen gibt es den Webshop leider nicht\. Stimmt das nicht\? Schreib uns im Chat\./) + assert.ok(fx.finde(root, 'button[data-view="chat"]')) + } + assert.equal(fx.fetchLog.filter((a) => a.method === 'POST').length, 0) + assert.deepEqual(k.reiter.at(-1).eintraege, []) +})) + +test('Abo, privat mit bestehendem Shop (active): die fünf Reiter bleiben', mitDom(async (fx) => { + const k = hoereAufKn(fx) + await oeffne(fx, { kopf: { modell: 'abo', kundenart: 'privat' }, state: 'active' }) + assert.equal(k.reiter.at(-1).eintraege.length, 5) +})) + +test('Abo, Anfrage angenommen: Gruppe B1 und Ablauf key shop statt Bestellseite; onFertig lädt neu', mitDom(async (fx) => { + const a = einschaltenAttrappe() + const root = await oeffne(fx, { kopf: { modell: 'abo', kundenart: 'unternehmen' }, anfrage: ZUGESAGT, einschalten: a.fn }) + assert.equal(a.aufrufe[0].key, 'shop') + assert.equal(a.aufrufe[0].projectId, 'p1') + assert.equal(fx.text(fx.finde(root, '.tm-bestellen-gruppe h4')), 'Deine Anfrage') + assert.ok(fx.finde(root, '[data-aktion="bestellen"]') === null) + assert.doesNotMatch(fx.text(root), KEIN_PREIS) + a.fertig(0) + await fx.ruhe() + assert.equal(fx.fetchLog.filter((x) => x.url === '/api/shop/status?projectId=p1').length, 2) +})) + +test('Abo, Anfrage angenommen, ohne Funktion einschalten: Fehlerkarte E4', mitDom(async (fx) => { + const root = await oeffne(fx, { kopf: { modell: 'abo', kundenart: 'unternehmen' }, anfrage: ZUGESAGT }) + assert.match(fx.text(root), /Das Einschalten ist gerade nicht verfügbar\./) +})) + +test('Ohne modell (fehlt, „Abo“): Formular mit Unternehmer-Haken und 299 €, nach der Zusage die Bestellseite, der Ablauf wird nie gerufen', mitDom(async (fx) => { + for (const modell of [undefined, 'Abo']) { + const a = einschaltenAttrappe() + const kopf = modell ? { modell } : {} + const formular = await oeffne(fx, { kopf, einschalten: a.fn }) + assert.ok(fx.finde(formular, '[data-feld="unternehmer"]')) + assert.ok(fx.finde(formular, '[data-feld="keineAusgeschlossenen"]')) + assert.match(fx.text(formular), /299 € einmalig/) + const zugesagt = await oeffne(fx, { kopf, anfrage: ZUGESAGT, einschalten: a.fn }) + assert.ok(fx.finde(zugesagt, '[data-aktion="bestellen"]')) + assert.equal(a.aufrufe.length, 0) + } +})) diff --git a/test/kundenansichtNeuModulTermine.test.js b/test/kundenansichtNeuModulTermine.test.js index a5171f8..5448780 100644 --- a/test/kundenansichtNeuModulTermine.test.js +++ b/test/kundenansichtNeuModulTermine.test.js @@ -45,7 +45,7 @@ test('Abo, alles bestätigt: letzter Schritt E1 mountet den Ablauf, ohne Haken, assert.match(fx.text(fx.finde(wurzel, '.tm-schritt-stand')), /Prüfen und einschalten/) assert.deepEqual(a.aufrufe.map((x) => [x.key, x.projectId, x.viewAs]), [['termine', 'p1', false]]) assert.equal(fx.alle(wurzel, 'input[type="checkbox"]').length, 0, 'auch kein Haken „gesundheit“') - for (const sel of ['[data-aktion="bestellen"]', '.tm-bestellen-preis', '.tm-rechtstext', '.tm-bestellen-zustimmung']) assert.equal(fx.finde(wurzel, sel), null, sel) + for (const sel of ['[data-aktion="bestellen"]', '.tm-bestellen-preis', '.tm-rechtstext', '.tm-bestellen-zustimmung']) assert.ok(fx.finde(wurzel, sel) === null, sel) assert.equal(fx.fetchLog.filter((x) => x.method === 'POST').length, 0) assert.deepEqual(k.reiter.at(-1).eintraege, []) })) diff --git a/test/shopWiring.test.js b/test/shopWiring.test.js index 858823e..d587930 100644 --- a/test/shopWiring.test.js +++ b/test/shopWiring.test.js @@ -28,7 +28,7 @@ test('app.js: VIEW_HASHES, viewRefreshers, FEATURE_LABELS und APP_PARENT kennen test('shop.js und shop.css: die Hülle exportiert initShop, die Styles hängen an #view-webshop und sh-', () => { const js = lies('public/shop.js') - assert.match(js, /export function initShop\(root, \{ projectId \} = \{\}\)/) + assert.match(js, /export function initShop\(root, \{ projectId, einschalten \} = \{\}\)/) assert.doesNotMatch(js.replace(/\/\*[\s\S]*?\*\//g, ''), /innerHTML|insertAdjacentHTML|outerHTML|document\.write/, 'Text nie als HTML') const css = lies('public/shop.css') assert.match(css, /#view-webshop/)