Shop G1: Verdrahtung #webshop, Webshop-Kachel, Bestellseite mit key und optionaler Zusammenfassung
Dashboard-Abschnitt view-webshop, shop.css und Platzhalter shop.js, app.js (Hash, Refresher, Label, Elternansicht), Kachel in funktionen.js nach shop.verfuegbar, GET /api/funktionen liefert shop.verfuegbar, funktion-bestellen.js nimmt key/name/zusammenfassung (Standard: Terminplaner unverändert). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0ebd2e6663
commit
809da80c9b
11 files changed
+333
-19
No files matched your search
@@ -0,0 +1,51 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
|
||||
// Task G1: der Webshop ist im Kundenbereich verdrahtet (dashboard.html, app.js, funktionen.js, shop.css, shop.js). Rein statisch, ohne DOM.
|
||||
const lies = (pfad) => readFileSync(new URL(`../${pfad}`, import.meta.url), 'utf8')
|
||||
|
||||
test('dashboard.html: shop.css nach termine.css, Abschnitt #view-webshop mit Kopf „Webshop“ und #webshop-body', () => {
|
||||
const html = lies('public/dashboard.html')
|
||||
assert.match(html, /<link rel="stylesheet" href="\/termine\.css">\s*<link rel="stylesheet" href="\/shop\.css">/)
|
||||
assert.match(html, /<section class="kb-view" id="view-webshop">[\s\S]*?<h1>Webshop<\/h1>[\s\S]*?<div id="webshop-body">[\s\S]*?<\/section>/)
|
||||
assert.equal([...html.matchAll(/id="view-webshop"/g)].length, 1)
|
||||
assert.doesNotMatch(html, /data-view="webshop"/, 'kein eigener Navigationseintrag: Unterseite von Funktionen')
|
||||
})
|
||||
|
||||
test('app.js: VIEW_HASHES, viewRefreshers, FEATURE_LABELS und APP_PARENT kennen den Webshop', () => {
|
||||
const app = lies('public/app.js')
|
||||
assert.match(app, /VIEW_HASHES = \{[^}]*webshop: 'webshop'/)
|
||||
assert.match(app, /FEATURE_LABELS = \{[^}]*shop: 'Webshop'/)
|
||||
assert.match(app, /webshop: \(\) => import\('\/shop\.js'\)\.then\(\(m\) => m\.initShop\(document\.getElementById\('webshop-body'\)\)\)/)
|
||||
// APP_PARENT: die Reihenfolge der bisherigen Einträge bleibt (termineView.test.js), webshop steht am Ende
|
||||
assert.match(app, /APP_PARENT = \{ news: 'funktionen', analyse: 'funktionen', termine: 'funktionen', /)
|
||||
assert.match(app, /APP_PARENT = \{[^}]*projekt: 'projects', webshop: 'funktionen' \}/)
|
||||
// die Ansicht ist vom Hash aus erreichbar: kein zweiter Schlüssel mit demselben Hash
|
||||
const hashes = app.match(/VIEW_HASHES = \{([^}]*)\}/)[1]
|
||||
assert.equal([...hashes.matchAll(/'webshop'/g)].length, 1)
|
||||
})
|
||||
|
||||
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.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/)
|
||||
assert.doesNotMatch(css, /(^|[}\s,])\.tm-/m, 'keine Klassen des Terminplaners neu definieren')
|
||||
})
|
||||
|
||||
test('funktionen.js: Webshop-Kachel inline, die erlaubten Importe bleiben (zwei absolute, ein relativer, kein dynamischer)', () => {
|
||||
const fn = lies('public/funktionen.js')
|
||||
assert.deepEqual(fn.match(/from '\/[^']+'/g), ["from '/fn-util.js'", "from '/analyse-view.js'"])
|
||||
assert.deepEqual(fn.match(/from '\.[^']+'/g), ["from './vertraege-link.js'"])
|
||||
assert.doesNotMatch(fn, /import\s*\(/)
|
||||
assert.match(fn, /data-fn-tile="shop"/)
|
||||
assert.match(fn, /getElementById\('webshop-body'\)/)
|
||||
})
|
||||
|
||||
test('Dateinamen: Webshop-Dateien beginnen nie mit termine (eigene Regeln der termine*.js-Tests)', async () => {
|
||||
const { readdirSync } = await import('node:fs')
|
||||
const dateien = readdirSync(new URL('../public/', import.meta.url)).filter((f) => /^shop.*\.(js|css)$/.test(f))
|
||||
assert.ok(dateien.includes('shop.js') && dateien.includes('shop.css'))
|
||||
})
|
||||
Reference in new issue
Block a user