diff --git a/server-internal/test-vorrang.mjs b/server-internal/test-vorrang.mjs new file mode 100644 index 00000000..5215f191 --- /dev/null +++ b/server-internal/test-vorrang.mjs @@ -0,0 +1,85 @@ +/* Prüft, welche Quelle sich durchsetzt — Verwaltung oder Serverdatei. + + Anlass (23.08.2026): In der .env stand PAYPAL_ENV=sandbox. Filipe + stellte im Formular auf "Echtbetrieb", und nichts geschah, weil der + Serverwert damals Vorrang hatte. Seine echten Zugangsdaten wurden + gegen den TESTSERVER von PayPal geprüft, der sie zwangsläufig ablehnte + — und die Meldung zeigte auf die Zugangsdaten statt auf die + Betriebsart. + + Der Vorrang ist deshalb umgedreht: Was in der Verwaltung steht, gilt. + Dieser Test hält das fest. +*/ +import { mkdtempSync, rmSync, appendFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { randomBytes } from "node:crypto"; + +const tmp = mkdtempSync(join(tmpdir(), "wd-vorrang-")); +process.env.DB_PATH = join(tmp, "t.db"); +process.env.ENCRYPTION_KEY = randomBytes(32).toString("base64"); +process.env.PAYPAL_ENV = "sandbox"; // genau wie in Filipes .env + +const LOG = "/tmp/wd-vorrang.log"; +const L = (...a) => { try { appendFileSync(LOG, a.join(" ") + "\n"); } catch (e) {} console.log(...a); }; + +const { initDb } = await import("./db.js"); +initDb(); +const geheim = await import("./lib/webdesign-geheimnisse.js"); +const paypal = await import("./lib/webdesign-paypal.js"); +await geheim.geheimnisseLaden(); + +let ok = 0, fehler = 0; +const pruefe = (n, b, z) => { + if (b) { ok++; L(" ok " + n); } + else { fehler++; L(" FEHL " + n + (z ? " -> " + z : "")); } +}; + +L("\n1. AUSGANGSLAGE — Serverdatei sagt sandbox"); +pruefe("der Serverwert greift, solange nichts eingetragen ist", + geheim.einstellung("PAYPAL_ENV") === "sandbox"); +pruefe("istLive() ist falsch", paypal.istLive() === false); +pruefe("die Anzeige nennt den Server als Quelle", + geheim.stand().PAYPAL_ENV.quelle === "server"); + +L("\n2. IM FORMULAR AUF ECHTBETRIEB STELLEN"); +await geheim.einstellungSetzen("PAYPAL_ENV", "live"); +pruefe("die Verwaltung setzt sich durch", + geheim.einstellung("PAYPAL_ENV") === "live", geheim.einstellung("PAYPAL_ENV")); +pruefe("istLive() ist jetzt WAHR — das war der ganze Fehler", + paypal.istLive() === true); + +const st = geheim.stand(); +pruefe("die Anzeige nennt die Verwaltung als Quelle", st.PAYPAL_ENV.quelle === "verwaltung", st.PAYPAL_ENV.quelle); +pruefe("und weist auf den überstimmten Serverwert hin", st.PAYPAL_ENV.auchAufServer === true); +pruefe("der angezeigte Wert ist der WIRKSAME, nicht der aus der Datei", + st.PAYPAL_ENV.wert === "live", String(st.PAYPAL_ENV.wert)); + +L("\n3. WIEDER LEEREN — der Serverwert greift zurück"); +await geheim.einstellungSetzen("PAYPAL_ENV", ""); +pruefe("zurück auf sandbox", geheim.einstellung("PAYPAL_ENV") === "sandbox"); +pruefe("Quelle wieder server", geheim.stand().PAYPAL_ENV.quelle === "server"); +pruefe("kein Hinweis mehr auf einen überstimmten Wert", + geheim.stand().PAYPAL_ENV.auchAufServer === false); + +L("\n4. ZUGANGSDATEN VERHALTEN SICH GENAUSO"); +process.env.PAYPAL_CLIENT_ID = "AUS-DER-SERVERDATEI"; +pruefe("ohne Eintrag gilt die Serverdatei", + geheim.einstellung("PAYPAL_CLIENT_ID") === "AUS-DER-SERVERDATEI"); +await geheim.einstellungSetzen("PAYPAL_CLIENT_ID", "IM-FORMULAR-EINGETRAGEN"); +pruefe("mit Eintrag gilt das Formular", + geheim.einstellung("PAYPAL_CLIENT_ID") === "IM-FORMULAR-EINGETRAGEN"); +pruefe("und die Anzeige sagt, dass der Serverwert nicht benutzt wird", + geheim.stand().PAYPAL_CLIENT_ID.auchAufServer === true); + +L("\n5. DAS SUPPORTER-ABO BLEIBT UNBERUEHRT"); +/* Es liest über ein eigenes Modul direkt aus der Umgebung. Ein Eintrag + im Webdesign-Formular darf dort nichts verändern — sonst könnte man + mit einem Tippfehler das laufende DogiCrew-Abo abschalten. */ +pruefe("die Umgebungsvariable selbst wurde nicht verändert", + process.env.PAYPAL_CLIENT_ID === "AUS-DER-SERVERDATEI", + String(process.env.PAYPAL_CLIENT_ID)); + +L(`\n===== ${ok} bestanden, ${fehler} fehlgeschlagen =====`); +process.on("exit", () => rmSync(tmp, { recursive: true, force: true })); +process.exitCode = fehler ? 1 : 0;