Hustler-Stufe: P4-Aktionen im Pult erst ab Stufe 4 (rowModel-Parameter stufe, PultList reicht ihn durch)
Unterhalb von Stufe 4 sind canReply, canPaste, canApprovePreview und canStartBuild immer false: Antwort des Kunden einfügen, Als Mensch antworten / Jetzt senden, Freigeben & senden und Vorschau bauen verschwinden samt Feldern und Rückfragen, die Aktionsgruppe schließt sich ohne Lücke. P3-Aktionen (übernehmen, Kopieren & öffnen, als gesendet markieren, verwerfen, erledigt, E-Mail schreiben) bleiben. Bestehende P4-Tests laufen ausdrücklich auf Stufe 6; neue Tests prüfen Stufe 3 gerendert und bedient (Reihenfolge der Knöpfe, kein Feld, Esc, Verwerfen mit Rückfrage). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7cd74a23d2
commit
5e48fbf264
5 files changed
+207
-15
No files matched your search
@@ -25,7 +25,8 @@ const NOW = Date.now() // die Bauteile rechnen mit der Uhr des Rechners: Alter u
|
||||
const iso = (ms) => new Date(ms).toISOString()
|
||||
const ME = { id: 'u1', name: 'Justin' }
|
||||
const EMPLOYEES = [{ userId: 'u2', displayName: 'Kenso' }]
|
||||
const rowOf = (item) => rowModel(item, { me: ME, nowMs: NOW, employees: EMPLOYEES })
|
||||
// Stufen-Sperre (hustlerStufe.js): diese Datei prüft das volle Pult (Stufe 6, P4-Aktionen offen, Verhalten wie vor der Sperre); Stufe 3 prüfen workersPultUi.test.mjs und hustlerStufe.test.mjs
|
||||
const rowOf = (item) => rowModel(item, { me: ME, nowMs: NOW, employees: EMPLOYEES, stufe: 6 })
|
||||
const entry = (extra = {}) => ({ $id: 'a', kind: 'plattform_antwort', status: 'offen', title: 'Suche Webdesigner', draft: 'Hallo', createdAt: iso(NOW - 3 * 3600e3), sourceUrl: 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3', prospect: { $id: 'p1', name: 'Verein', city: 'Namborn', postalCode: '66640', score: 72, email: 'x@verein.example' }, ...extra })
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
@@ -209,7 +210,7 @@ async function startPult(items, { api = { pultAction: async () => ({}) }, kpis,
|
||||
globalThis.__pultEmployees = EMPLOYEES
|
||||
globalThis.__pultFeedFor = (statuses) => ({ items: feed.byStatus ? (feed.byStatus[statuses] ?? []) : items, loading: false, error: null, refresh: async () => { refreshes.push(statuses) }, ...feed.extra })
|
||||
delete globalThis.__panel
|
||||
const mounted = __mount(jsx(PultList, { api, me: ME, kpis, onBack, paused }))
|
||||
const mounted = __mount(jsx(PultList, { api, me: ME, kpis, onBack, paused, stufe: 6 }))
|
||||
const view = {
|
||||
timers, refreshes,
|
||||
tree: () => mounted.tree(),
|
||||
|
||||
@@ -5,8 +5,13 @@ import { loadModule } from './load.mjs'
|
||||
// Reine Pult-Logik des Reiters „Freigabe“: Filter, Alter, Veraltet-Anzeige, sichere Links, Zeilenmodell, Kopieren & Öffnen
|
||||
const {
|
||||
PULT_KIND_LABELS, SENDABLE_KINDS, PULT_FILTERS, REPLY_KINDS, PASTE_KINDS, REPLY_TEXT_MAX, UNCERTAIN_TEXT,
|
||||
staleView, ageLabel, safeExternalUrl, mailtoHref, employeeName, rowModel, copyAndOpen, validateReplyText, charCount, actionErrorText, pasteDoneText,
|
||||
staleView, ageLabel, safeExternalUrl, mailtoHref, employeeName, rowModel: rowModelNachStufe, copyAndOpen, validateReplyText, charCount, actionErrorText, pasteDoneText,
|
||||
} = await loadModule('src/lib/workersPult.js')
|
||||
const { HUSTLER_STUFE } = await loadModule('src/lib/hustlerStufe.js')
|
||||
|
||||
// Stufen-Sperre (hustlerStufe.js): rowModel bietet die P4-Aktionen erst ab Stufe 4 an. Die Zusicherungen dieser Datei gelten für das volle Pult und laufen deshalb auf
|
||||
// Stufe 6 (P4 und Keller offen, Verhalten wie vor der Sperre). Was unterhalb von Stufe 4 gilt, prüft hustlerStufe.test.mjs.
|
||||
const rowModel = (item, ctx) => rowModelNachStufe(item, { stufe: 6, ...ctx })
|
||||
|
||||
const NOW = Date.parse('2026-10-19T09:00:00Z')
|
||||
const MIN = 60 * 1000
|
||||
@@ -462,3 +467,73 @@ test('pasteDoneText: neu und fortgesetzt melden das Einsortieren, doppelt meldet
|
||||
assert.equal(pasteDoneText({ status: 'doppelt' }), 'Diese Antwort war schon eingefügt.')
|
||||
for (const odd of [undefined, null, {}, 'doppelt', { status: 7 }]) assert.equal(pasteDoneText(odd), 'Eingefügt. Nora sortiert die Antwort ein.', String(odd))
|
||||
})
|
||||
|
||||
// ---------- Stufen-Sperre (hustlerStufe.js): rowModel auf Stufe 3 und Stufe 6 ----------
|
||||
|
||||
const ME = { id: 'u1', name: 'Justin' }
|
||||
const PROSPEKT = { $id: 'p1', name: 'Verein', email: 'x@verein.example', status: 'neu' }
|
||||
const eintrag = (extra) => ({ $id: 'e1', kind: 'plattform_antwort', status: 'offen', title: 'Titel', draft: 'Hallo', createdAt: '2026-10-19T08:00:00Z', sourceUrl: 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3', prospectId: 'p1', prospect: PROSPEKT, ...extra })
|
||||
const zeile = (item, s) => rowModelNachStufe(item, { me: ME, nowMs: NOW, employees: [], stufe: s })
|
||||
const P4 = ['canReply', 'canPaste', 'canApprovePreview', 'canStartBuild']
|
||||
const P3 = ['canClaim', 'canSend', 'canDiscard', 'canDone']
|
||||
const VORSCHAU = 'https://entwurf.project.webklar.com/verein'
|
||||
|
||||
test('rowModel auf Stufe 1 bis 3: canReply, canPaste, canApprovePreview und canStartBuild sind für jede Art und jeden Status false', () => {
|
||||
const kinds = Object.keys(PULT_KIND_LABELS)
|
||||
const states = ['offen', 'in_arbeit', 'veraltet', 'gesendet', 'verworfen', 'erledigt']
|
||||
for (const s of [1, 2, 3]) {
|
||||
for (const kind of kinds) {
|
||||
for (const status of states) {
|
||||
for (const extra of [{}, { claimedBy: 'mensch:u1' }, { claimedBy: 'mensch:u2' }, { prospect: null }]) {
|
||||
const item = eintrag({ kind, status, sourceUrl: kind === 'vorschau_freigabe' ? VORSCHAU : undefined, ...extra })
|
||||
const m = zeile(item, s)
|
||||
for (const key of P4) assert.equal(m[key], false, `Stufe ${s} ${kind}/${status} ${JSON.stringify(extra)}: ${key}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('rowModel auf Stufe 4, 6 und 9: die P4-Aktionen erscheinen wie vor der Sperre', () => {
|
||||
for (const s of [4, 6, 9]) {
|
||||
assert.equal(zeile(eintrag({ kind: 'mail_antwort' }), s).canReply, true, `Stufe ${s}`)
|
||||
assert.equal(zeile(eintrag({ kind: 'unsicher' }), s).canReply, true)
|
||||
assert.equal(zeile(eintrag({ kind: 'plattform_antwort', status: 'gesendet' }), s).canPaste, true)
|
||||
assert.equal(zeile(eintrag({ kind: 'plattform_antwort', status: 'verworfen' }), s).canPaste, false) // die Regeln selbst bleiben
|
||||
assert.equal(zeile(eintrag({ kind: 'vorschau_freigabe', sourceUrl: VORSCHAU }), s).canApprovePreview, true)
|
||||
assert.equal(zeile(eintrag({ kind: 'unsicher' }), s).canStartBuild, true)
|
||||
assert.equal(zeile(eintrag({ kind: 'unsicher', prospect: { ...PROSPEKT, status: 'gesperrt' } }), s).canStartBuild, false)
|
||||
assert.equal(zeile(eintrag({ kind: 'mail_antwort', claimedBy: 'mensch:u2', status: 'in_arbeit' }), s).canReply, false) // von einem Kollegen übernommen
|
||||
}
|
||||
})
|
||||
|
||||
test('rowModel: die P3-Aktionen sind auf Stufe 3 und 6 gleich; die Stufe ändert nur die vier P4-Felder', () => {
|
||||
const fixtures = []
|
||||
for (const kind of Object.keys(PULT_KIND_LABELS)) {
|
||||
for (const status of ['offen', 'in_arbeit', 'veraltet', 'gesendet', 'verworfen', 'erledigt']) fixtures.push(eintrag({ kind, status, sourceUrl: kind === 'vorschau_freigabe' ? VORSCHAU : undefined }))
|
||||
}
|
||||
fixtures.push(eintrag({ status: 'in_arbeit', claimedBy: 'mensch:u1' }), eintrag({ status: 'in_arbeit', claimedBy: 'mensch:u2' }), eintrag({ kind: 'mail_antwort', sourceUrl: '' }))
|
||||
for (const item of fixtures) {
|
||||
const gesperrt = zeile(item, 3); const offen = zeile(item, 6)
|
||||
for (const key of P3) assert.equal(gesperrt[key], offen[key], `${item.kind}/${item.status}: ${key}`)
|
||||
const ohneP4 = (m) => Object.fromEntries(Object.entries(m).filter(([k]) => !P4.includes(k)))
|
||||
assert.deepEqual(ohneP4(gesperrt), ohneP4(offen), `${item.kind}/${item.status}`)
|
||||
}
|
||||
// und konkret die P3-Aktionen auf Stufe 3
|
||||
const plattform = zeile(eintrag({}), 3)
|
||||
assert.deepEqual([plattform.canClaim, plattform.canSend, plattform.canDiscard, plattform.canDone], [true, true, true, false])
|
||||
assert.equal(plattform.sourceHref, 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3'); assert.equal(plattform.copyText, 'Hallo')
|
||||
const mail = zeile(eintrag({ kind: 'mail_antwort', sourceUrl: '' }), 3)
|
||||
assert.match(mail.mailtoHref, /^mailto:x@verein\.example\?/); assert.equal(mail.canSend, true)
|
||||
const unsicher = zeile(eintrag({ kind: 'unsicher' }), 3)
|
||||
assert.deepEqual([unsicher.canDone, unsicher.canDiscard, unsicher.canClaim], [true, true, true])
|
||||
const freigabe = zeile(eintrag({ kind: 'vorschau_freigabe', sourceUrl: VORSCHAU }), 3)
|
||||
assert.deepEqual([freigabe.canClaim, freigabe.canDiscard, freigabe.canDone, freigabe.canSend], [true, true, false, false])
|
||||
})
|
||||
|
||||
test('rowModel ohne Stufe gilt HUSTLER_STUFE (die Stufe der Produktion)', () => {
|
||||
const item = eintrag({ kind: 'mail_antwort' })
|
||||
assert.equal(rowModelNachStufe(item, { me: ME, nowMs: NOW, employees: [] }).canReply, HUSTLER_STUFE >= 4)
|
||||
assert.equal(rowModelNachStufe(item, { me: ME, nowMs: NOW, employees: [], stufe: undefined }).canReply, HUSTLER_STUFE >= 4)
|
||||
assert.equal(rowModelNachStufe(item, { me: ME, nowMs: NOW, employees: [], stufe: 'x' }).canReply, HUSTLER_STUFE >= 4)
|
||||
})
|
||||
@@ -248,9 +248,11 @@ async function loadList() {
|
||||
"import PultList from './src/components/workers/PultList.jsx'",
|
||||
"import Brief from './src/components/workers/pult/Brief.jsx'",
|
||||
"import { rowModel } from './src/lib/workersPult.js'",
|
||||
'export const render = (props) => renderToStaticMarkup(createElement(PultList, props))',
|
||||
'export const renderBrief = (item, { me, nowMs, employees, text, fields } = {}) => {',
|
||||
' const row = rowModel(item, { me, nowMs, employees })',
|
||||
// Stufen-Sperre (hustlerStufe.js): die Zusicherungen dieser Datei gelten für das volle Pult (Stufe 6, P4-Aktionen offen, Verhalten wie vor der Sperre);
|
||||
// die Tests „Stufe 3“ am Ende der Datei reichen stufe: 3 durch
|
||||
'export const render = (props) => renderToStaticMarkup(createElement(PultList, { stufe: 6, ...props }))',
|
||||
'export const renderBrief = (item, { me, nowMs, employees, text, fields, stufe = 6 } = {}) => {',
|
||||
' const row = rowModel(item, { me, nowMs, employees, stufe })',
|
||||
' return renderToStaticMarkup(createElement(Brief, { api: {}, item, row, text: text ?? row.copyText, fields: fields ?? {}, onText() {}, onField() {}, refresh: async () => {}, onFinished() {}, onClose() {}, onDetails() {}, onSpaet() {} }))',
|
||||
'}',
|
||||
].join('\n'),
|
||||
@@ -571,7 +573,7 @@ async function startList(items, api, props = {}) {
|
||||
}
|
||||
globalThis.__pultEmployees = [{ userId: 'u2', displayName: 'Kenso' }]
|
||||
globalThis.__pultFeedFor = (statuses) => ({ items: statuses === 'offen,in_arbeit' ? items : [], loading: false, error: null, refresh: async () => { refreshes.push(statuses) } })
|
||||
const mounted = __mount(jsx(PultList, { api, me: { id: 'u1', name: 'Justin' }, ...props }))
|
||||
const mounted = __mount(jsx(PultList, { api, me: { id: 'u1', name: 'Justin' }, stufe: 6, ...props })) // Stufe 6 = volles Pult; Stufe 3 siehe die Tests am Ende der Datei
|
||||
let current = null // Nummer des Umschlags, dessen Brief offen ist
|
||||
const view = {
|
||||
refreshes, timers, opened,
|
||||
@@ -1269,3 +1271,111 @@ test('Pult (bedient, P4-T32): mehrere Einträge desselben Interessenten – Feld
|
||||
assert.deepEqual(api.calls[1], ['k9', 'paste', { text: 'Ja, gern' }])
|
||||
} finally { ui.end() }
|
||||
})
|
||||
|
||||
// ---- Stufen-Sperre (hustlerStufe.js): Stufe 3 = Stand der Produktion, der Dienst kann P3, aber noch nicht P4. Das Pult bietet dann keine der vier P4-Aktionen an ----
|
||||
// ---- (Antwort des Kunden einfügen, Als Mensch antworten / Jetzt senden, Vorschau freigeben, Vorschau bauen); die P3-Aktionen bleiben, ohne Loch und ohne Fokusfalle. ----
|
||||
|
||||
const P4_TEXTE = ['Antwort des Kunden einfügen', 'Als Mensch antworten', 'Jetzt senden', 'Freigeben & senden', 'Wirklich freigeben?', 'Vorschau bauen', 'Wirklich bauen?', 'Vorschau ansehen', 'Einfügen', 'Text der Antwort', 'Antwort des Kunden']
|
||||
const P4_MERKMALE = ['data-opens', 'aria-expanded', 'hk-feld-panel', 'hk-feld-antwort', 'hk-feld-einfuegen', 'hk-zaehler', 'hk-brief-hinweis-bau']
|
||||
|
||||
test('Stufe 3 (gerendert): kein Brief, keine Art und kein Status zeigt eine P4-Aktion; Stufe 6 zeigt sie weiter', async () => {
|
||||
const { renderBrief } = await loadList()
|
||||
const now = Date.now()
|
||||
const me = { id: 'u1', name: 'Justin' }
|
||||
const prospect = { $id: 'p1', name: 'Verein', city: 'Namborn', postalCode: '66640', score: 72, email: 'x@verein.example' }
|
||||
const base = { $id: 'a', status: 'offen', title: 'Eintrag', draft: 'Hallo', createdAt: new Date(now).toISOString(), sourceUrl: 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3', prospect, prospectId: 'p1' }
|
||||
const vorschau = { ...base, kind: 'vorschau_freigabe', sourceUrl: 'https://entwurf.project.webklar.com/verein' }
|
||||
const alle = [
|
||||
...['offen', 'in_arbeit', 'veraltet', 'gesendet', 'erledigt', 'verworfen'].flatMap((status) => [
|
||||
{ ...base, kind: 'plattform_antwort', status }, { ...base, kind: 'mail_antwort', status }, { ...vorschau, status },
|
||||
{ ...base, kind: 'unsicher', status }, { ...base, kind: 'preisfrage', status }, { ...base, kind: 'mensch_gewuenscht', status },
|
||||
{ ...base, kind: 'beschwerde', status }, { ...base, kind: 'bau_fehlgeschlagen', status },
|
||||
]),
|
||||
{ ...base, kind: 'plattform_antwort', status: 'in_arbeit', claimedBy: 'mensch:u2' }, // von einem Kollegen übernommen
|
||||
{ ...base, kind: 'plattform_antwort', status: 'gesendet', prospect: null },
|
||||
]
|
||||
for (const item of alle) {
|
||||
const name = `${item.kind}/${item.status}${item.claimedBy ? '/Kollege' : ''}`
|
||||
const html = renderBrief(item, { me, nowMs: now, employees: [], stufe: 3 })
|
||||
for (const t of P4_TEXTE) assert.ok(!html.includes(t), `${name}: „${t}“`)
|
||||
for (const m of P4_MERKMALE) assert.ok(!html.includes(m), `${name}: ${m}`)
|
||||
assert.ok(html.includes('hk-brief'), name) // der Brief selbst steht
|
||||
}
|
||||
// Gegenprobe Stufe 6: dieselben Einträge zeigen die P4-Aktionen (sonst prüft die Schleife oben nichts)
|
||||
const gezeigt = (item) => P4_TEXTE.filter((t) => renderBrief(item, { me, nowMs: now, employees: [], stufe: 6 }).includes(t))
|
||||
assert.ok(gezeigt({ ...base, kind: 'plattform_antwort' }).includes('Antwort des Kunden einfügen'))
|
||||
assert.ok(gezeigt({ ...base, kind: 'mail_antwort' }).includes('Als Mensch antworten'))
|
||||
assert.ok(gezeigt(vorschau).includes('Freigeben & senden'))
|
||||
assert.ok(gezeigt({ ...base, kind: 'unsicher' }).includes('Vorschau bauen'))
|
||||
})
|
||||
|
||||
test('Stufe 3 (gerendert): die P3-Aktionen je Art bleiben unverändert, Mail-Link, Anzeige öffnen und Interessent auch; abgeschlossene Einträge sagen es', async () => {
|
||||
const { renderBrief } = await loadList()
|
||||
const now = Date.now()
|
||||
const me = { id: 'u1', name: 'Justin' }
|
||||
const prospect = { $id: 'p1', name: 'Verein', email: 'x@verein.example' }
|
||||
const base = { $id: 'a', status: 'offen', title: 'Eintrag', draft: 'Hallo', createdAt: new Date(now).toISOString(), sourceUrl: 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3', prospect, prospectId: 'p1' }
|
||||
const brief = (item) => renderBrief(item, { me, nowMs: now, employees: [], stufe: 3 })
|
||||
// Plattform-Antwort: übernehmen, Kopieren & öffnen, als gesendet markieren, verwerfen
|
||||
let html = brief({ ...base, kind: 'plattform_antwort' })
|
||||
for (const t of ['Kopieren & öffnen', 'Ich kümmere mich', 'Als gesendet markieren', 'Verwerfen', 'Anzeige öffnen', 'Interessent']) assert.ok(html.includes(t), t)
|
||||
assert.ok(!stempel(html, 'Erledigt'))
|
||||
// Mail-Antwort: E-Mail schreiben (mailto) bleibt
|
||||
html = brief({ ...base, kind: 'mail_antwort', sourceUrl: '' })
|
||||
assert.match(html, /<a class="hk-stempel hk-stempel-haupt" href="mailto:x@verein\.example\?[^"]*"><span class="hk-ic hk-ic-art-mail" aria-hidden="true"><\/span>E-Mail schreiben<\/a>/)
|
||||
assert.ok(html.includes('Ich kümmere mich')); assert.ok(html.includes('Als gesendet markieren')); assert.ok(html.includes('Verwerfen'))
|
||||
// nicht sendbare Arten: Erledigt und Verwerfen; „unsicher“ bietet kein Bauen mehr
|
||||
for (const kind of ['unsicher', 'preisfrage', 'mensch_gewuenscht', 'beschwerde', 'bau_fehlgeschlagen']) {
|
||||
html = brief({ ...base, kind })
|
||||
assert.ok(stempel(html, 'Erledigt'), kind); assert.ok(html.includes('Verwerfen'), kind); assert.ok(html.includes('Ich kümmere mich'), kind); assert.ok(!html.includes('Als gesendet markieren'), kind)
|
||||
}
|
||||
// Vorschau-Freigabe ohne P4: übernehmen und verwerfen (Erledigt gibt es dort nie), mit dem Hinweis des Verwerfens
|
||||
html = brief({ ...base, kind: 'vorschau_freigabe', sourceUrl: 'https://entwurf.project.webklar.com/verein' })
|
||||
assert.ok(html.includes('Ich kümmere mich')); assert.ok(html.includes('Verwerfen')); assert.ok(!stempel(html, 'Erledigt')); assert.ok(html.includes('„Verwerfen“ sendet die Vorschau nicht.'))
|
||||
// abgeschlossen: keine Aktionsgruppe, auch nicht für „gesendet mit Interessent“ (dort stand bisher nur „Antwort des Kunden einfügen“)
|
||||
html = brief({ ...base, kind: 'plattform_antwort', status: 'gesendet' })
|
||||
assert.ok(!html.includes('hk-aktionen')); assert.ok(html.includes('Dieser Eintrag ist abgeschlossen.')); assert.ok(html.includes('<h3 class="hk-brief-h">Entwurf</h3>'))
|
||||
})
|
||||
|
||||
test('Stufe 3 (bedient): das Pult arbeitet mit den P3-Aktionen, ohne P4-Knöpfe, ohne Loch in der Aktionsgruppe und ohne Fokusfalle', async () => {
|
||||
const api = scriptedApi(Promise.resolve({}), Promise.resolve({}), Promise.resolve({}))
|
||||
const ui = await startList([{ ...unsicher, $id: 'k1', kind: 'plattform_antwort', title: 'Suche Webdesigner', draft: 'Claras Entwurf', sourceUrl: 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3', prospect: { $id: 'p1', name: 'Verein' } }], api, { stufe: 3 })
|
||||
try {
|
||||
await ui.open(0)
|
||||
const aktionen = nodes(ui.brief(), (n) => n.tag === 'div' && n.props.role === 'group' && hasClass(n, 'hk-aktionen'))[0]
|
||||
assert.ok(aktionen)
|
||||
// die Gruppe enthält genau die P3-Knöpfe, in dieser Reihenfolge, ohne leere Plätze
|
||||
const beschriftung = aktionen.children.filter((c) => c !== null && c !== false).map((c) => textOf(c).trim())
|
||||
assert.deepEqual(beschriftung, ['Kopieren & öffnen', 'Ich kümmere mich', 'Als gesendet markieren', 'Verwerfen'])
|
||||
assert.equal(aktionen.children.length, aktionen.children.filter((c) => c !== null && c !== false).length)
|
||||
// nichts im Brief öffnet ein Feld; kein Textfeld außer dem Entwurf
|
||||
assert.equal(nodes(ui.brief(), (n) => n.props && (n.props['data-opens'] !== undefined || n.props['aria-expanded'] !== undefined)).length, 0)
|
||||
assert.equal(nodes(ui.brief(), (n) => n.tag === 'textarea').length, 1)
|
||||
for (const label of ['Antwort des Kunden einfügen', 'Als Mensch antworten', 'Jetzt senden', 'Freigeben & senden', 'Vorschau bauen']) assert.equal(ui.has(label), false, label)
|
||||
// Esc schließt den Brief (es gibt kein Feld, das zuerst schließen müsste), Umschlag bleibt bedienbar
|
||||
const esc = await ui.briefKey('Escape'); assert.equal(esc.defaultPrevented, true); assert.equal(ui.brief(), null)
|
||||
// P3 läuft: erster Klick auf Verwerfen fragt, der zweite verwirft; es geht nur discard hinaus
|
||||
await ui.click('Verwerfen')
|
||||
assert.deepEqual(ui.disabled('Wirklich verwerfen?'), [false]); assert.equal(api.calls.length, 0)
|
||||
await ui.click('Wirklich verwerfen?')
|
||||
assert.deepEqual(api.calls, [['k1', 'discard', {}]])
|
||||
assert.deepEqual(ui.messages(), [{ kind: 'ok', text: '„Suche Webdesigner“ verworfen.', role: 'status' }])
|
||||
} finally { ui.end() }
|
||||
})
|
||||
|
||||
test('Stufe 3 (bedient): „unsicher“ und „Vorschau freigeben“ zeigen kein Bauen und kein Freigeben; Erledigt und Verwerfen bleiben; die Zahl der Umschläge bleibt gleich', async () => {
|
||||
const api = scriptedApi()
|
||||
const vorschau = { ...unsicher, $id: 'v1', kind: 'vorschau_freigabe', title: 'Vorschau Verein', sourceUrl: 'https://entwurf.project.webklar.com/verein' }
|
||||
const ui = await startList([unsicher, vorschau], api, { stufe: 3 })
|
||||
try {
|
||||
assert.equal(envelopes(ui.tree()).length, 2)
|
||||
await ui.open(0)
|
||||
assert.deepEqual(['Erledigt', 'Verwerfen', 'Ich kümmere mich'].map((l) => ui.has(l)), [true, true, true])
|
||||
assert.deepEqual(['Vorschau bauen', 'Als Mensch antworten', 'Antwort des Kunden einfügen'].map((l) => ui.has(l)), [false, false, false])
|
||||
await ui.close()
|
||||
await ui.open(1)
|
||||
assert.deepEqual(['Verwerfen', 'Ich kümmere mich'].map((l) => ui.has(l)), [true, true])
|
||||
assert.deepEqual(['Freigeben & senden', 'Vorschau ansehen', 'Erledigt'].map((l) => ui.has(l)), [false, false, false])
|
||||
assert.equal(api.calls.length, 0)
|
||||
} finally { ui.end() }
|
||||
})
|
||||
Reference in new issue
Block a user