Rollen wechseln: auch Spicy Media -- und DogFather ist nicht mehr vergebbar
Filipe: "ich will dass die rolle spicy und dogfather, auch die rollen
wechseln koennen wenn die personen schon drin sind. von alle
kategorien, creator, scouts, manager spicy. dogfather soll man nicht
auswaehlen koennen. das ist die einzige die man nicht auswaehlen kann
bitte."
ZWEI AENDERUNGEN, BEIDE IN EINER LISTE (ANLEGBAR):
admin: alles AUSSER der eigenen Rolle
spicy: spicy, manager, scout, creator (vorher ohne spicy)
Weil die Oberflaeche ihre Knoepfe aus derselben Auskunft baut
(`darf_anlegen` in /api/ich), verschwindet DogFather damit von selbst
aus JEDER Auswahl -- beim Anlegen wie beim Wechseln, bei Spicy Media
wie bei DogFather. Eine Liste, zwei Formulare, kein Nachziehen.
WAS DAS BEDEUTET, damit es niemand spaeter sucht: Es laesst sich kein
zweiter DogFather-Zugang mehr anlegen und niemand mehr zu einem
befoerdern. Der bestehende ist durch Sicherung 3 geschuetzt (nie den
letzten herabstufen) und kann nicht versehentlich verschwinden.
Zurueckdrehen laesst sich das nur in ANLEGBAR.
DIE TUER: /verwaltung haengt an nurAdmin, und dort steht jetzt eine
DRITTE enge Ausnahme -- PUT auf genau /personen/<Ziffern>/rolle, fuer
genau die Rollen aus darfRollenWechseln(). Gleiche Bauweise wie die
beiden davor (Liste fuer Spicy Media, Liste fuer die rechte Hand). Was
NICHT mitgeht: Codes, Sperren, Loeschen, Zuteilung, Protokoll.
EINE NEUE SICHERUNG, weil sich die Tuer geoeffnet hat: An einer
DogFather-Zeile aendert nur DogFather. Die bestehenden Pruefungen sehen
auf die ZIEL-Rolle ("darfst du 'manager' vergeben?") -- dass die
BETROFFENE Person DogFather ist, kam darin bis heute nicht vor.
Sicherung 3 haette es heute zufaellig abgefangen, weil es genau einen
gibt; eine Sperre, die nur wegen einer Zahl im Bestand haelt, ist
keine.
DIE OBERFLAECHE: "Rolle aendern" und "Loeschen" hingen an EINER Zeile
(`ich.rolle === 'admin'`). Sie gehoeren nicht zusammen -- Loeschen
bleibt bei DogFather. Und die CSS-Regel, die fuer Spicy Media die ganze
Knopfreihe ausblendete, ist weg: Welche Knoepfe es gibt, entscheidet
jetzt personen.js, und was nicht entsteht, muss man nicht verstecken.
pruef-spicy 62 -> 83. Gemessen wird jede der vier Kategorien EINZELN
(waere nur eine offen, saehe "geht" genauso aus), dazu: admin weder von
Spicy Media noch von DogFather vergebbar, an DogFathers Zeile aendert
sie nichts (und er ist danach nachweislich noch admin), ein Manager
kommt an den Weg nicht, loeschen bleibt zu -- und im Browser, dass der
KNOPF da ist, nicht nur das Recht. Genau daran war heute frueh im Chat
eine Stunde draufgegangen.
Dabei zwei eigene Messfehler gefunden: Die Knoepfe entstehen erst in
einer AUFGEKLAPPTEN Kategorie (vorher zu frueh gemessen), und /api/ich
wird jetzt als Vorbedingung geprueft.
DREI PRUEFUNGEN GEDREHT, KEINE GELOESCHT:
- pruef-personen-formular: 7 Karten, `admin` fehlt (eigene Aussage).
Die Zeichenpruefung verglich die rechte Hand gegen die Admin-KARTE --
die es nicht mehr gibt; sie lief gegen `undefined`. Ersatz ist das
Zeichen selbst, und der Kommentar sagt, dass das schwaecher ist.
- pruef-haus-trennung: Der zweite DogFather entsteht jetzt im Bestand
statt ueber die Schnittstelle, und DASS die Schnittstelle ihn
ablehnt, ist der erste Prueffall geworden. Sonst waere "nie den
letzten DogFather" ab heute ungeprueft -- weil ihre Voraussetzung
schwerer herzustellen ist.
- pruef-creator-anlegen: aus einer Aussage zwei (die vier sind da UND
admin fehlt).
Gruen: personen-liste, personen-kachel, verborgen, manager-sicht,
creator-anlegen, haus-trennung, personen-formular, spicy, rollen.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -319,6 +319,78 @@ const ruf = async (art, weg, keks, koerper) => {
|
||||
ok(m.status === 201 && m.daten?.rolle === "manager",
|
||||
`und einen Manager (HTTP ${m.status}, ${m.daten?.rolle})`);
|
||||
}
|
||||
{
|
||||
/* ---- ROLLEN WECHSELN (11.09.2026) -------------------------------
|
||||
Filipe: "ich will dass die rolle spicy und dogfather, auch die
|
||||
rollen wechseln koennen wenn die personen schon drin sind. von
|
||||
alle kategorien, creator, scouts, manager spicy. dogfather soll
|
||||
man nicht auswaehlen koennen."
|
||||
|
||||
AN EINEM EIGENEN MENSCHEN, nicht an Luna: Wer hier Luna umstellt,
|
||||
aendert stillschweigend die Listen, die weiter unten verglichen
|
||||
werden -- und der Fehlschlag stuende dann an einer Stelle, die
|
||||
nichts damit zu tun hat. */
|
||||
/* VORBEDINGUNG: Die Oberflaeche baut den Knopf aus `/api/ich`. Fehlt
|
||||
die Angabe dort, ist jede Aussage ueber den Knopf weiter unten
|
||||
eine Aussage ueber etwas anderes. */
|
||||
const ichSpicy = await ruf("GET", "/workspace/api/ich", keksSpicy);
|
||||
ok(ichSpicy.daten?.darf_rollen_wechseln === true,
|
||||
`/api/ich sagt ihr, dass sie Rollen wechseln darf (${ichSpicy.daten?.darf_rollen_wechseln})`);
|
||||
|
||||
const neu = await ruf("POST", "/workspace/api/creator-anlegen", keksSpicy,
|
||||
{ name: "Wechselkind" });
|
||||
const idWechsel = neu.daten?.id;
|
||||
ok(neu.status === 201 && Number.isInteger(idWechsel),
|
||||
`ein Mensch zum Umstellen ist da (#${idWechsel})`);
|
||||
|
||||
const zu = async (keks, rolle, id = idWechsel) =>
|
||||
ruf("PUT", `/workspace/api/verwaltung/personen/${id}/rolle`, keks, { rolle });
|
||||
|
||||
/* Die vier Kategorien, die Filipe genannt hat -- einzeln, nicht als
|
||||
"irgendeine geht". Waere nur eine davon offen, saehe ein "geht"
|
||||
genauso aus. */
|
||||
for (const r of ["scout", "manager", "spicy"]) {
|
||||
const a = await zu(keksSpicy, r);
|
||||
ok(a.status === 200 && a.daten?.rolle === r,
|
||||
`Spicy Media stellt auf "${r}" um (HTTP ${a.status})`);
|
||||
}
|
||||
const zurueck = await zu(keksSpicy, "creator");
|
||||
ok(zurueck.status === 200, `und wieder zurueck auf Creator (HTTP ${zurueck.status})`);
|
||||
|
||||
/* DIE EINZIGE, DIE NICHT GEHT. */
|
||||
const hoch = await zu(keksSpicy, "admin");
|
||||
ok(hoch.status === 403,
|
||||
`DogFather laesst sich nicht vergeben (HTTP ${hoch.status}, ${hoch.daten?.fehler || ""})`);
|
||||
|
||||
/* AUCH NICHT VON DOGFATHER SELBST. Das ist der Satz "das ist die
|
||||
einzige die man nicht auswaehlen kann" -- ohne Ausnahme. */
|
||||
const vonDogi = await zu(keksDogi, "admin");
|
||||
ok(vonDogi.status === 403,
|
||||
`auch DogFather kann sie nicht vergeben (HTTP ${vonDogi.status})`);
|
||||
|
||||
/* UND AN DOGFATHER SELBST AENDERT SIE NICHTS. Die Pruefungen oben
|
||||
sehen auf die ZIEL-Rolle; dass die BETROFFENE Person DogFather
|
||||
ist, faellt dort gar nicht auf. */
|
||||
const anDogi = await zu(keksSpicy, "manager", idDogi);
|
||||
ok(anDogi.status === 403,
|
||||
`an DogFathers Zeile aendert sie nichts (HTTP ${anDogi.status})`);
|
||||
const dogiNoch = await ruf("GET", "/workspace/api/verwaltung/personen", keksDogi);
|
||||
const istNoch = (dogiNoch.daten?.personen || [])
|
||||
.find((x) => x.id === idDogi)?.rolle;
|
||||
ok(istNoch === "admin", `und er ist immer noch DogFather (${istNoch})`);
|
||||
|
||||
/* GEGENPROBE ZUR TUER: Ein Manager kommt an diesen Weg gar nicht --
|
||||
sonst hiesse "Spicy Media darf" nur, dass jeder darf. */
|
||||
const vonMax = await zu(keksMax, "scout");
|
||||
ok(vonMax.status === 404, `ein Manager kommt an diesen Weg nicht (HTTP ${vonMax.status})`);
|
||||
|
||||
/* UND DIE UEBRIGE VERWALTUNG BLEIBT ZU. Die Tuer war eng gebaut;
|
||||
diese Zeile ist der Beweis, dass sie eng geblieben ist. */
|
||||
const wegDamit = await ruf("DELETE",
|
||||
`/workspace/api/verwaltung/personen/${idWechsel}`, keksSpicy);
|
||||
ok(wegDamit.status === 404,
|
||||
`loeschen geht fuer sie weiterhin nicht (HTTP ${wegDamit.status})`);
|
||||
}
|
||||
{
|
||||
/* GEGENPROBE: Ein Manager kann KEINEN Manager anlegen -- sonst waere
|
||||
die zweite Tuer nur Zierde. */
|
||||
@@ -549,6 +621,49 @@ console.log("\n=== Die Anmeldeseite ===");
|
||||
`bei ihr steht der Abschnitt DogFather (${alsText.slice(0, 70) || "keine Abschnitte"})`);
|
||||
ok(/Manager|Creator|Scout/.test(alsText),
|
||||
"und die uebrigen Abschnitte ebenfalls -- die Liste ist nicht leer");
|
||||
|
||||
/* ERST AUFKLAPPEN, DANN MESSEN (11.09.2026).
|
||||
|
||||
Die Kategorien stehen zugeklappt da, und `zeile(p)` -- die Funktion,
|
||||
die die Knoepfe baut -- laeuft nur fuer eine OFFENE Kategorie. Der
|
||||
erste Entwurf las sofort nach dem Laden und meldete "kein Knopf".
|
||||
Das war kein Befund, das war eine zu frueh gestellte Frage; genau
|
||||
derselbe Fehler wie heute frueh bei den Kacheln der Startseite.
|
||||
|
||||
Geoeffnet wird die Kategorie, die es bei beiden Rollen gibt. */
|
||||
for (const kopf of await seite.$$(".gruppe__kopf")) {
|
||||
const t = (await kopf.textContent()) || "";
|
||||
if (/Creator/.test(t)) { await kopf.click(); break; }
|
||||
}
|
||||
await seite.waitForTimeout(600);
|
||||
const zeilenSpicy = await seite.$$eval(".person", (z) => z.length);
|
||||
ok(zeilenSpicy > 0, `eine Kategorie ist aufgeklappt (${zeilenSpicy} Zeilen)`);
|
||||
|
||||
/* ---- DER KNOPF, NICHT NUR DAS RECHT (11.09.2026) ----------------
|
||||
Am selben Tag ist mir im Chat genau das passiert: Das Recht war
|
||||
richtig vergeben, die Oberflaeche wusste nichts davon, und der
|
||||
Knopf blieb unsichtbar. Eine Pruefung, die nur die Schnittstelle
|
||||
misst, waere dabei gruen geblieben.
|
||||
|
||||
ZWEI AUSSAGEN, NICHT EINE: Der Knopf "Rolle aendern" muss da sein,
|
||||
"Loeschen" NICHT -- das gehoert weiterhin DogFather. Vorher hingen
|
||||
beide an derselben Zeile. */
|
||||
const knoepfeSpicy = await seite.$$eval(".person__tu, .tu-knopf, button",
|
||||
(b) => b.map((x) => x.textContent.trim()));
|
||||
ok(knoepfeSpicy.some((t) => /Rolle ändern/.test(t)),
|
||||
`Spicy Media sieht "Rolle ändern" (${knoepfeSpicy.filter((t) => /Rolle|Löschen/.test(t)).join(", ") || "nichts davon"})`);
|
||||
ok(!knoepfeSpicy.some((t) => /^Löschen$/.test(t)),
|
||||
"und \"Löschen\" NICHT -- das bleibt bei DogFather");
|
||||
|
||||
/* Und in der Auswahl steht DogFather nicht. Gemessen an den
|
||||
Knoepfen, die wirklich gebaut werden -- nicht an der Liste im
|
||||
Quelltext, aus der sie entstehen. */
|
||||
const rollenKnoepfe = await seite.$$eval("#f-rolle .rollenwahl__knopf",
|
||||
(b) => b.map((x) => x.dataset.rolle));
|
||||
ok(rollenKnoepfe.length >= 3 && !rollenKnoepfe.includes("admin"),
|
||||
`zur Auswahl stehen ${rollenKnoepfe.join(", ")} -- ohne DogFather`);
|
||||
ok(rollenKnoepfe.includes("spicy"),
|
||||
"ihre eigene Rolle ist dabei -- Filipes Liste nennt sie ausdruecklich");
|
||||
await ctx.close();
|
||||
|
||||
/* GEGENPROBE BEI DOGFATHER: Bei ihm steht der Abschnitt "Spicy Media"
|
||||
@@ -568,6 +683,28 @@ console.log("\n=== Die Anmeldeseite ===");
|
||||
ok(/Spicy Media/.test(abschnitteDogi),
|
||||
`bei DogFather steht der Abschnitt "Spicy Media" (${abschnitteDogi.slice(0, 80)})`);
|
||||
ok(/DogFather/.test(abschnitteDogi), "und seiner ebenfalls");
|
||||
|
||||
for (const kopf of await seite2.$$(".gruppe__kopf")) {
|
||||
const t = (await kopf.textContent()) || "";
|
||||
if (/Creator/.test(t)) { await kopf.click(); break; }
|
||||
}
|
||||
await seite2.waitForTimeout(600);
|
||||
const zeilenDogi = await seite2.$$eval(".person", (z) => z.length);
|
||||
ok(zeilenDogi > 0, `auch bei ihm ist sie aufgeklappt (${zeilenDogi} Zeilen)`);
|
||||
|
||||
/* GEGENPROBE BEI DOGFATHER: Bei ihm steht "Loeschen" sehr wohl --
|
||||
sonst hiesse die Zeile oben nur, dass es den Knopf nirgends gibt.
|
||||
Und auch in SEINER Auswahl fehlt DogFather. */
|
||||
const knoepfeDogi = await seite2.$$eval(".person__tu, .tu-knopf, button",
|
||||
(b) => b.map((x) => x.textContent.trim()));
|
||||
ok(knoepfeDogi.some((t) => /^Löschen$/.test(t)),
|
||||
"bei DogFather steht \"Löschen\" da");
|
||||
ok(knoepfeDogi.some((t) => /Rolle ändern/.test(t)),
|
||||
"und \"Rolle ändern\" ebenfalls");
|
||||
const rollenDogi = await seite2.$$eval("#f-rolle .rollenwahl__knopf",
|
||||
(b) => b.map((x) => x.dataset.rolle));
|
||||
ok(rollenDogi.length >= 3 && !rollenDogi.includes("admin"),
|
||||
`auch bei ihm ohne DogFather (${rollenDogi.join(", ")})`);
|
||||
await ctx2.close();
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user