Files
Webklar-Kundenbereich/test/auftraegeKundenportalDashboard.test.js

64 lines
4.0 KiB
JavaScript

import { test } from 'node:test'
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import vm from 'node:vm'
const lies = (pfad) => readFileSync(new URL(`../${pfad}`, import.meta.url), 'utf8')
const html = lies('public/dashboard.html')
const app = lies('public/app.js')
const css = lies('public/auftrag.css')
test('dashboard.html: auftrag.css nach zeiten.css; Abschnitt „Aufträge“ vor der Rechnungsliste, zunächst versteckt', () => {
assert.match(html, /<link rel="stylesheet" href="\/zeiten\.css">\s*<link rel="stylesheet" href="\/auftrag\.css">/)
const start = html.indexOf('id="view-invoices"')
const ende = html.indexOf('</section>', html.indexOf('id="invoices-abo-note"'))
const ansicht = html.slice(start, ende)
assert.match(ansicht, /<section class="ab-portal hidden" id="orders-section" aria-labelledby="orders-title">\s*<h2 id="orders-title">Aufträge<\/h2>[\s\S]*<div id="orders-body"><\/div>\s*<\/section>\s*<h2 class="ab-rechnungen-titel hidden" id="invoices-title">Rechnungen<\/h2>\s*<div class="kb-panel" id="invoices-body">/)
assert.match(ansicht, /<p class="kb-note">Deine Auftragsbestätigungen\. Offene Aufträge bestätigst du hier mit einem Klick\.<\/p>/, 'Portal: Du-Form')
assert.ok(ansicht.indexOf('id="orders-section"') < ansicht.indexOf('id="invoices-body"'))
assert.equal([...html.matchAll(/id="orders-section"/g)].length, 1)
assert.match(ansicht, /<h1>Rechnungen<\/h1>/, 'Kopf und Hinweis des Reiters bleiben')
})
test('app.js: loadCustomerOrders lädt auftrag-portal.js nach der Rechnungsliste, mit api und Ansichtsmodus; Fehler bleiben still', () => {
const funktion = app.slice(app.indexOf('function loadCustomerOrders()'), app.indexOf('/* ---', app.indexOf('function loadCustomerOrders()')))
assert.ok(funktion.length > 40, 'Funktion gefunden')
assert.match(funktion, /import\('\/auftrag-portal\.js'\)/)
assert.match(funktion, /m\.initAuftraege\(/)
for (const teil of ["section: document.getElementById('orders-section')", "body: document.getElementById('orders-body')", "invoicesTitle: document.getElementById('invoices-title')", 'request: api', 'viewAs: chatState.viewAs']) {
assert.ok(funktion.includes(teil), teil)
}
assert.match(funktion, /\.catch\(\(\) => \{\}\)/)
const dashboard = app.slice(app.indexOf('async function initDashboardPage'))
const aufruf = (name) => dashboard.search(new RegExp(`^\\s*${name}\\(\\)\\s*$`, 'm'))
assert.ok(aufruf('loadCustomerInvoices') > 0 && aufruf('loadCustomerOrders') > aufruf('loadCustomerInvoices'), 'ein eigener Aufruf, nach der Rechnungsliste')
assert.equal([...app.matchAll(/function loadCustomerOrders\(\)/g)].length, 1)
})
test('invoiceNumberHtml: Projekt unter der Rechnungsnummer, alles maskiert', () => {
const ausschnitt = (muster) => {
const treffer = app.match(muster)
assert.ok(treffer, `${muster} nicht in app.js`)
return treffer[0]
}
const code = [
ausschnitt(/function escapeHtml\(str\) \{[\s\S]*?\n\}/),
ausschnitt(/\/\/ @rechnungsnummer-anfang[\s\S]*?\/\/ @rechnungsnummer-ende/),
].join('\n')
const { invoiceNumberHtml } = vm.runInNewContext(`${code}\n({ invoiceNumberHtml })`)
assert.equal(invoiceNumberHtml({ number: 'WEBKLAR-0009', projekt: 'Website Anelia Wolf' }), 'WEBKLAR-0009<span class="inv-project">Website Anelia Wolf</span>')
assert.equal(invoiceNumberHtml({ number: 'WEBKLAR-0009', projekt: '' }), 'WEBKLAR-0009')
assert.equal(invoiceNumberHtml({ number: 'H96T-0004' }), 'H96T-0004')
assert.equal(
invoiceNumberHtml({ number: 'X', projekt: '<img src=x onerror=alert(1)> & "Bäckerei"' }),
'X<span class="inv-project">&lt;img src=x onerror=alert(1)&gt; &amp; &quot;Bäckerei&quot;</span>',
)
assert.match(app, /<td class="inv-no">\$\{invoiceNumberHtml\(i\)\}<\/td>/)
assert.doesNotMatch(app, /\$\{i\.projekt\}/, 'der Projektname geht nie unmaskiert in eine Vorlage')
})
test('auftrag.css: Projektname unter der Rechnungsnummer (Tabelle und Handy-Karte)', () => {
assert.match(css, /\.inv-project\s*\{[^}]*display:\s*block/)
assert.match(css, /\.inv-project\s*\{[^}]*overflow-wrap:\s*anywhere/)
})