Die Skript-API kennt jetzt reply, approve-preview, start-build und paste mit den Prüfreihenfolgen und Sätzen des Dienstes (pultMail.js, paste.js) und einen eigenen Datensatz (?p4=1: Mail-Antwort, zwei Vorschau-Freigaben, unsicher, Kollegen-Eintrag, zwei gesendete Plattform-Antworten desselben Interessenten). Schalter für 400/409/413, Verbindungsabbruch (status 0) und eine Wartezeit je Aktion. Sechs neue Szenarien in shot.cjs: antworten, vorschau, einfuegen, bauen, fokus, handy-p4 (109 Prüfpunkte, Bilder je Zustand). Drei veraltete P3-Prüfpunkte angepasst (seit P4 bietet eine Plattform-Zeile auch „Antwort des Kunden einfügen“). Bricht ein Szenario ab, hält abbruch-<Szenario>.png den Zustand fest. Der Lauf deckt Fehler der App auf (Fokus nach Aktionen, kein Esc/Abbrechen an den Feldern, 32-px-Schließen am Handy); die Prüfpunkte dazu bleiben rot, an der App ist nichts geändert. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
55 lines
3.7 KiB
JavaScript
55 lines
3.7 KiB
JavaScript
// Fetch-Weiche des Prüfstands: nimmt die Anfragen des echten API-Clients (createWorkersApi, URLs unter /api/workers) entgegen und
|
||
// beantwortet sie mit der Skript-API. Damit läuft im Prüfstand dieselbe Kette wie im Betrieb (API-Client, Feed, Board), und die
|
||
// Ausfälle lassen sich schalten: control.fault = null (gesund) | 'down' (503 ohne JSON wie eine Fehlerseite des Proxys) |
|
||
// 'session' (401) | 'hang' (die Antwort kommt nie, wie auf einer toten Verbindung). Kein Netz, kein Appwrite.
|
||
// Seit P3 auch Pult (GET /pult, POST /pult/:id/<Aktion>) und Interessent (GET /prospect/:id): Fehler der Skript-API (status + deutscher
|
||
// Satz) kommen als { error } mit diesem Status an, wie vom Dienst (auch 413 „Anfrage zu groß.“). Seit P4 laufen reply, approve-preview,
|
||
// start-build und paste über dieselbe Route POST /pult/:id/<Aktion>. Ein Fehler mit status 0 aus der Skript-API bricht die Verbindung ab
|
||
// (fetch wirft), damit die Meldung „Kann gesendet sein – Pult neu laden.“ (Zeitüberschreitung, D14) sichtbar wird.
|
||
// control.calls sammelt jede Anfrage ({ method, path, jwt }), damit der Prüfstand zählen kann.
|
||
|
||
const reply = (status, body) => ({
|
||
ok: status >= 200 && status < 300,
|
||
status,
|
||
json: async () => {
|
||
if (body === undefined) throw new SyntaxError('kein JSON')
|
||
return body
|
||
},
|
||
})
|
||
|
||
export function createScriptedFetch(api, control) {
|
||
return async function scriptedFetch(url, init = {}) {
|
||
const method = init.method || 'GET'
|
||
const parsed = new URL(url, 'http://harness.invalid')
|
||
const path = parsed.pathname.replace(/^\/api\/workers/, '')
|
||
control.calls.push({ method, path, jwt: init.headers ? init.headers['X-Appwrite-JWT'] : undefined })
|
||
if (control.fault === 'hang') return new Promise(() => {})
|
||
if (control.fault === 'down') return reply(503, undefined)
|
||
if (control.fault === 'session') return reply(401, {})
|
||
try {
|
||
const body = init.body === undefined ? undefined : JSON.parse(init.body)
|
||
if (method === 'GET' && path === '/state') return reply(200, await api.state())
|
||
if (method === 'GET' && path === '/events') {
|
||
const limit = parsed.searchParams.get('limit')
|
||
return reply(200, await api.events(parsed.searchParams.get('after'), limit === null ? undefined : Number(limit)))
|
||
}
|
||
const trace = /^\/worker\/([^/]+)\/trace$/.exec(path)
|
||
if (method === 'GET' && trace) return reply(200, await api.trace(decodeURIComponent(trace[1])))
|
||
if (method === 'POST' && path === '/pause') return reply(200, await api.pause(body.paused))
|
||
if (method === 'GET' && path === '/settings') return reply(200, await api.settings())
|
||
if (method === 'PUT' && path === '/settings') return reply(200, await api.saveSettings(body))
|
||
// Freigabe-Pult und Interessent (P3); ohne ?status= gilt wie im Dienst offen,in_arbeit
|
||
if (method === 'GET' && path === '/pult') return reply(200, await api.pult(parsed.searchParams.get('status') ?? undefined))
|
||
const action = /^\/pult\/([^/]+)\/([^/]+)$/.exec(path)
|
||
if (method === 'POST' && action) return reply(200, await api.pultAction(decodeURIComponent(action[1]), action[2], body))
|
||
const prospect = /^\/prospect\/([^/]+)$/.exec(path)
|
||
if (method === 'GET' && prospect) return reply(200, await api.prospect(decodeURIComponent(prospect[1])))
|
||
return reply(404, { error: 'Unbekannter Pfad im Prüfstand.' })
|
||
} catch (err) {
|
||
// Status 0 aus der Skript-API = die Verbindung bricht ab, bevor eine Antwort da ist (fetch wirft wie bei einem Netzfehler)
|
||
if (err && err.status === 0) throw new TypeError('Failed to fetch')
|
||
return reply(err && err.status ? err.status : 500, { error: err && err.message ? err.message : 'Fehler im Prüfstand.' })
|
||
}
|
||
}
|
||
}
|