// lib/bio.js — live Wikipedia "Who he is" cache. // refreshBio() pulls the article intro from the Wikipedia API and upserts the // `bio` doc; getBio() reads it (falling back to the static blurb). // Runs against a scratch Mongo. Needs network (Wikipedia) for refreshBio. // RUN: MONGODB_URI=mongodb://127.0.0.1:27099/bama node tests/bio-test.mjs import { MongoClient } from "mongodb"; // bio.js -> db.js reads BAMA_DB_NAME at module load, so set it BEFORE the // dynamic import of ../lib/bio.js. Use a dedicated scratch db for this test. process.env.BAMA_DB_NAME = process.env.BAMA_DB_NAME || "bama_bio_test"; const uri = process.env.MONGODB_URI || "mongodb://127.0.0.1:27099/bama"; const mc = new MongoClient(uri, { serverSelectionTimeoutMS: 8000 }); await mc.connect(); const db = mc.db(process.env.BAMA_DB_NAME); await db.collection("bio").deleteMany({}); let fails = 0; const check = (name, cond, detail = "") => { console.log(` ${cond ? "ok " : "FAIL"} ${name}${detail ? " — " + detail : ""}`); if (!cond) fails++; }; // 1. getBio before any refresh -> static fallback, still has a link const { getBio, refreshBio } = await import("../lib/bio.js"); let bio = await getBio(); check("getBio falls back to text when cache empty", bio.ok === true && typeof bio.text === "string" && bio.text.length > 40, JSON.stringify(bio.text).slice(0, 60)); check("fallback still carries the Wikipedia link", /wikipedia\.org\/wiki\/Bam_Aquino/.test(bio.url || ""), bio.url); check("fallback source flagged", bio.source === "fallback", bio.source); // 2. refreshBio pulls the live article (needs network) console.log("refreshing from Wikipedia..."); try { const r = await refreshBio(); check("refreshBio ok", r.ok === true); check("refreshed text mentions the senator", /Aquino/i.test(r.text || ""), JSON.stringify(r.text).slice(0, 70)); // now getBio should serve the cached live copy bio = await getBio(); check("getBio now serves cached live copy", bio.source === "Wikipedia", bio.source); check("cached copy has updated date", bio.updatedAt instanceof Date || typeof bio.updatedAt === "object", String(bio.updatedAt)); } catch (e) { // No network (e.g. offline CI) -> refresh throws; getBio must still fall back. console.log(" (network refresh failed: " + (e && e.message) + " — verifying graceful fallback)"); bio = await getBio(); check("offline: getBio still returns the fallback blurb", bio.ok === true && bio.source === "fallback", bio.source); } await db.collection("bio").deleteMany({}); await mc.close(); console.log(fails ? `\n${fails} FAILED` : "\nall passed"); process.exit(fails ? 1 : 0);