diff --git a/server/pruef-highlights.mjs b/server/pruef-highlights.mjs index 83f62b0d..7f23b7a0 100644 --- a/server/pruef-highlights.mjs +++ b/server/pruef-highlights.mjs @@ -258,6 +258,52 @@ try { ok(zuNachher.sagt === "false", ` und sagt es auch Vorleseprogrammen (aria-expanded=${zuNachher.sagt})`); + /* ===================================================================== + DIE ABLAGE LAESST SICH WAEHLEN (22.09.2026) + --------------------------------------------------------------------- + Filipe: „ich will das wenn man da video holt das man auch aussuchen + kann in welcher account es unten angezeigt werden soll." + + Geprueft wird am BILDSCHIRM, nicht im Quelltext: dass die Wahl da + ist, dass sie genau die Kanaele anbietet (plus „aus dem Link"), und + dass sie das Eingabefeld nicht quetscht. Das Letzte ist kein + Schoenheitspunkt -- am 21.09. hat genau so ein drittes Element in + derselben Reihe das Chat-Feld auf einen Buchstaben zusammengedrueckt. + ================================================================== */ + { + const { KANAELE } = await import("./workspace.js"); + const v = await s.evaluate(() => { + const w = document.getElementById("video-kanal"); + const feld = document.getElementById("video-url"); + const knopf = document.getElementById("video-holen"); + const r = (e) => (e ? e.getBoundingClientRect() : null); + const fr = r(feld), kr = r(knopf), wr = r(w); + return { + da: !!w, + werte: w ? [...w.options].map((o) => o.value) : [], + erste: w ? w.options[0]?.textContent.trim() : "", + vorgabe: w ? w.value : null, + feldBreite: fr ? Math.round(fr.width) : 0, + /* Steht die Wahl UNTER der Zeile, nicht darin? */ + unterhalb: wr && kr ? Math.round(wr.top) >= Math.round(kr.bottom) - 2 : false, + }; + }); + ok(v.da, "die Wahl fuer den Account steht da"); + /* DIE LISTE IST ABGELEITET, NICHT ABGESCHRIEBEN: sie muss genau die + Kanaele des Hauses anbieten, plus den leeren Eintrag. */ + const soll = ["", ...KANAELE.map((k) => k.wert)]; + ok(KANAELE.length >= 3 + && JSON.stringify(v.werte) === JSON.stringify(soll), + `sie bietet genau die ${KANAELE.length} Kanaele an, plus den leeren Eintrag ` + + `(${v.werte.join(", ")})`); + ok(v.vorgabe === "" && /Link/.test(v.erste), + `und steht auf: ${v.erste} — ohne Zutun bleibt alles wie bisher`); + ok(v.feldBreite > 400, + `das Eingabefeld bleibt breit (${v.feldBreite} px)`); + ok(v.unterhalb, + "die Wahl steht unter der Zeile, nicht darin"); + } + await ctx.close(); } finally { await browser.close(); diff --git a/server/pruef-video.mjs b/server/pruef-video.mjs index 25e60693..5bfb0fcf 100644 --- a/server/pruef-video.mjs +++ b/server/pruef-video.mjs @@ -159,9 +159,10 @@ const an = await fetch(BASIS + "/workspace/api/anmelden", { const keks = (an.headers.getSetCookie?.() || []).map((z) => z.split(";")[0]).join("; "); const kopf = { "Content-Type": "application/json", cookie: keks, origin: BASIS }; -async function holen(url, bereich = "highlight") { +async function holen(url, bereich = "highlight", kanal = undefined) { const a = await fetch(`${BASIS}/workspace/api/bereich/${bereich}/video`, { - method: "POST", headers: kopf, body: JSON.stringify({ url }), + method: "POST", headers: kopf, + body: JSON.stringify(kanal === undefined ? { url } : { url, kanal }), }); return { status: a.status, daten: await a.json().catch(() => null) }; } @@ -247,6 +248,58 @@ melde("=== 3. Die drei Kanäle ==="); `drei verschiedene Kanäle in der Liste (${[...kanaele].join(", ")})`); } +/* ======================================================================= + 3b. WOHIN ES GELEGT WIRD, DARF MAN WAEHLEN (22.09.2026) + ----------------------------------------------------------------------- + Filipe: „ich will das wenn man da video holt das man auch aussuchen + kann in welcher account es unten angezeigt werden soll." + + Bis heute entschied allein der Link. Das ist gut geraten, aber es IST + geraten: Ein Ausschnitt vom Hauptkanal gehoert oft unter „Clips". + + DREI FRAGEN, und die dritte ist die wichtigste: + 1. Eine Wahl schlaegt das Erkannte. + 2. Ein erfundener Kanal wird abgelehnt. + 3. OHNE Wahl bleibt alles wie vorher -- sonst waere aus einer + Zugabe eine Verhaltensaenderung geworden, die niemand bestellt + hat. + ======================================================================= */ +melde(""); +melde("=== 3b. Die Ablage waehlen ==="); +{ + const { KANAELE } = await import("./workspace.js"); + const haupt = KANAELE.find((k) => k.wert === "dogfather"); + const anders = KANAELE.find((k) => k.wert !== "dogfather"); + + /* 1. Ein Video VOM Hauptkanal, abgelegt woanders. */ + const gewaehlt = await holen( + videoVon(haupt.handle.replace(/^@/, ""), "901"), "highlight", anders.wert); + ok(gewaehlt.status === 201 && gewaehlt.daten?.kanal === anders.wert, + `ein Video von ${haupt.handle} laesst sich unter „${anders.name}" ablegen ` + + `(${gewaehlt.status}, ${gewaehlt.daten?.kanal})`); + + /* 2. Ein erfundener Kanal. Ohne diese Zeile koennte jeder Text in + der Spalte landen -- und die Galerie zeigt ihn dann als Fach. */ + const erfunden = await holen( + videoVon(haupt.handle.replace(/^@/, ""), "902"), "highlight", "gibtsnicht"); + ok(erfunden.status === 400 && erfunden.daten?.fehler === "kanal_unbekannt", + `ein erfundener Kanal wird abgelehnt (${erfunden.status}, ${erfunden.daten?.fehler})`); + + /* 3. DIE GEGENPROBE. Ohne Wahl muss weiterhin der Link entscheiden -- + sonst waere die Zeile oben auch gruen, wenn die Erkennung + stillschweigend abgeschaltet worden waere. */ + const ohne = await holen(videoVon(haupt.handle.replace(/^@/, ""), "903")); + ok(ohne.status === 201 && ohne.daten?.kanal === "dogfather", + `ohne Wahl entscheidet weiterhin der Link (${ohne.status}, ${ohne.daten?.kanal})`); + + /* 4. UND DIE SCHRANKE BLEIBT. Eine Wahl darf kein Schluessel fuer + fremde Inhalte sein -- gewaehlt wird die Spalte, nicht, wer + hereindarf. */ + const fremd = await holen(videoVon("irgendwerfremd", "904"), "highlight", anders.wert); + ok(fremd.status === 403, + `ein fremder Absender kommt auch MIT Wahl nicht herein (${fremd.status})`); +} + /* ======================================================================= 4. WAS NICHT HINEINKOMMT ======================================================================= */ @@ -276,12 +329,21 @@ melde("=== 4. Die Gegenprobe ==="); /* DERSELBE LINK ZWEIMAL. Wer den Knopf zweimal drückt, meint nicht zwei Videos. */ + /* GEMESSEN WIRD DER UNTERSCHIED, NICHT DIE SUMME (berichtigt 22.09.2026). + Hier stand `coverAbrufe === 3` -- eine Rechnung von dem Tag, an dem + die Prüfung drei Videos anlegte. Am 22.09. kam ein Abschnitt dazu, + und die Zeile wurde rot, ohne dass irgendetwas kaputt war. + + Die Frage lautet nicht "wie viele Cover insgesamt", sondern + "holt derselbe Link ein zweites Mal?" -- das ist eine Differenz + und bleibt richtig, egal wie viele Videos davor liefen. */ + const coverVorher = coverAbrufe; const wieder = await holen(videoVon("dogfather0804")); ok(wieder.status === 200 && wieder.daten?.schon === true, `derselbe Link gibt denselben Eintrag zurück (${wieder.status}, schon=${wieder.daten?.schon})`); ok(wieder.daten?.id === eintragId, `und zwar wirklich denselben (${wieder.daten?.id})`); - ok(coverAbrufe === 3, - `und holt das Cover kein zweites Mal (${coverAbrufe} Abrufe für 3 Videos)`); + ok(coverAbrufe === coverVorher, + `und holt das Cover kein zweites Mal (${coverVorher} vor, ${coverAbrufe} nach dem zweiten Versuch)`); const nachher = (await liste()).length; ok(nachher === vorher, `kein Eintrag ist dazugekommen (${nachher} von ${vorher})`); diff --git a/server/workspace-video.js b/server/workspace-video.js index 9447b9f5..20cc3835 100644 --- a/server/workspace-video.js +++ b/server/workspace-video.js @@ -237,6 +237,30 @@ videoRouter.post("/workspace/api/bereich/:bereich/video", async (req, res) => { }); } + /* WOHIN ES GELEGT WIRD, DARF MAN WAEHLEN (22.09.2026). + =================================================================== + Filipe: „ich will das wenn man da video holt das man auch + aussuchen kann in welcher account es unten angezeigt werden soll." + + Bis heute entschied das allein der Link: `kanalVonHandle` liest + den Account aus der TikTok-Adresse, und dort landete das Video. + Das ist richtig geraten, aber es IST geraten -- ein Ausschnitt + vom Hauptkanal gehoert oft unter „Clips", und ein Video, das + jemand anders hochgeladen hat, steht dann in der falschen Spalte. + + Die Schranke darueber bleibt unangetastet: Der ABSENDER muss + weiterhin einer der drei eigenen Kanaele sein. Gewaehlt wird nur + die SPALTE, nicht, ob fremde Inhalte hereinduerfen -- sonst waere + aus einer Ablagehilfe ein Loch geworden. + + Ohne Angabe bleibt alles wie bisher. Das ist der haeufigste Fall + und soll keinen zusaetzlichen Handgriff kosten. */ + const gewaehlt = String(req.body?.kanal ?? "").trim(); + if (gewaehlt && !KANAELE.some((k) => k.wert === gewaehlt)) { + return res.status(400).json({ fehler: "kanal_unbekannt" }); + } + const ablage = gewaehlt || auskunft.kanal; + abgelegt = await coverAblegen(auskunft.cover); const jetzt = new Date().toISOString(); @@ -250,7 +274,7 @@ videoRouter.post("/workspace/api/bereich/:bereich/video", async (req, res) => { db().prepare(`UPDATE eintraege SET quelle_url = ?, quelle_kanal = ?, quelle_geholt_am = ?, geaendert = ? WHERE id = ?`) - .run(url, auskunft.kanal, jetzt, jetzt, anhaengenAn); + .run(url, ablage, jetzt, jetzt, anhaengenAn); eintragId = anhaengenAn; } else { const { lastInsertRowid } = db().prepare(` @@ -259,7 +283,7 @@ videoRouter.post("/workspace/api/bereich/:bereich/video", async (req, res) => { quelle_url, quelle_kanal, quelle_geholt_am, aus_eintrag_id) VALUES (?,?,?,?, 'offen', ?,?,?,?,?,?)`) .run(bereich, arten[bereich] || "clip", auskunft.titel, jetzt.slice(0, 10), - jetzt, req.person.id, url, auskunft.kanal, jetzt, ausQuelle ? aus : null); + jetzt, req.person.id, url, ablage, jetzt, ausQuelle ? aus : null); eintragId = Number(lastInsertRowid); } @@ -278,7 +302,13 @@ videoRouter.post("/workspace/api/bereich/:bereich/video", async (req, res) => { detail: `${auskunft.kanal} ${url}${ausQuelle ? ` (aus #${aus})` : ""}`.slice(0, 120), }); res.status(201).json({ - id: eintragId, schon: false, kanal: auskunft.kanal, + /* GEMELDET WIRD DIE ABLAGE, NICHT DAS ERKANNTE (22.09.2026). + Hier stand `auskunft.kanal` -- also das, was aus dem Link + gelesen wurde. Seit die Spalte waehlbar ist, sind das zwei + verschiedene Dinge, und die Antwort muss sagen, wo der Eintrag + wirklich gelandet ist. Sonst meldet die Seite "DogFather", + waehrend das Video unter "Clips" steht. */ + id: eintragId, schon: false, kanal: ablage, titel: auskunft.titel, cover: !!abgelegt || undefined, ...(ausQuelle ? { aus: aus, angehaengt: !!anhaengenAn } : {}), }); diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html index d4a7e12b..dfba0cec 100644 --- a/workspace/anruf-probe.html +++ b/workspace/anruf-probe.html @@ -16,15 +16,15 @@ verdeckt. Gefunden hat es pruef-struktur. Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. --> - - + + - +