/* Tests Node sans navigateur de recherche.js (logique pure). * Usage : node recherche.test.js — sortie 0 si tout passe. */ "use strict"; const assert = require("node:assert/strict"); const rp = require("../static/js/recherche.js"); let n = 0; function ok(cond, label) { assert.ok(cond, label); n += 1; } /* esc */ ok(rp.esc('&') === "<a href="x">&", "esc échappe HTML"); /* isDevHost : même règle que la barre v0.1.6 */ ok(rp.isDevHost("tiktak-dev.dracodev.net") === true, "dev reconnu"); ok(rp.isDevHost("tiktak.dracodev.net") === false, "prod non dev"); ok(rp.isDevHost("x-dev.dracodev.net.evil") === false, "hôte piège rejeté"); ok(rp.isDevHost("dev.dracodev.net") === false, "étiquette trop courte rejetée"); ok(rp.isDevHost("TIKTAK-DEV.DRACODEV.NET") === true, "insensible à la casse"); /* resolveBases : ordre explicite > barre > dev > href > prod */ let b = rp.resolveBases({ host: "tiktak-dev.dracodev.net", explicit: { obsigate: "https://og-perso.example/" }, barUrls: { flowdeck: "https://flowdeck-barre.example/" }, tabHrefs: { kanbante: "https://kanbante-href.example/" }, }); ok(b.obsigate === "https://og-perso.example/", "explicite prioritaire"); ok(b.flowdeck === "https://flowdeck-barre.example/", "barre avant dev"); ok(b.tiktak === "https://tiktak-dev.dracodev.net/", "dev pour l'hôte courant"); ok(b.kanbante === "https://kanbante-dev.dracodev.net/", "dev avant href"); b = rp.resolveBases({ host: "tiktak.dracodev.net", tabHrefs: { kanbante: "https://kanbante-href.example/" } }); ok(b.kanbante === "https://kanbante-href.example/", "href en prod"); ok(b.obsigate === "https://og.dracodev.net/", "défaut prod"); b = rp.resolveBases({}); ok(b.flowdeck === "https://flowdeck.dracodev.net/", "défaut prod sans hôte"); /* searchPath */ ok(rp.searchPath("obsigate", "café & thé") === "api/search?q=caf%C3%A9%20%26%20th%C3%A9&vault=all&limit=8", "path ObsiGate"); ok(rp.searchPath("tiktak", "a b") === "api/search?q=a%20b", "path TikTak"); /* normalize ObsiGate */ let items = rp.normalize("obsigate", { results: [{ vault: "home-bruno", path: "Notes/Idée.md", title: "Idée", snippet: "extrait" }] }, "https://og-dev.dracodev.net/", "idée"); ok(items.length === 1 && items[0].url === "https://og-dev.dracodev.net/#file=home-bruno:Notes%2FId%C3%A9e.md", "lien profond ObsiGate"); ok(items[0].context === "home-bruno · Notes/Idée.md", "contexte ObsiGate"); /* normalize Flowdeck */ items = rp.normalize("flowdeck", { pages: [{ title: "P", excerpt: "ex", subtitle: "Espace", url: "/pages/42" }], collections: [{ title: "B", subtitle: "Database · Espace", url: "/db/7" }] }, "https://flowdeck-dev.dracodev.net/", "p"); ok(items.length === 2 && items[0].url === "https://flowdeck-dev.dracodev.net/pages/42", "lien page Flowdeck"); ok(items[1].url === "https://flowdeck-dev.dracodev.net/db/7", "lien base Flowdeck"); /* normalize TikTak */ items = rp.normalize("tiktak", { tasks: [{ id: 9, title: "Faire X", description: "d", status: "active", due_at: "2026-10-30 09:00:00" }] }, "https://tiktak-dev.dracodev.net/", "faire"); ok(items[0].url === "https://tiktak-dev.dracodev.net/search?q=faire&task=9", "lien profond TikTak"); ok(items[0].context === "Tâche · Active · échéance 2026-10-30", "contexte TikTak"); /* normalize Kanbante */ items = rp.normalize("kanbante", { groups: [{ full_name: "Projets/site", rows: [{ issue: { number: 12, title: "Bug", body: "corps" }, column: "in_progress" }] }] }, "https://kanbante-dev.dracodev.net/", "bug"); ok(items[0].title === "#12 Bug" && items[0].url === "https://kanbante-dev.dracodev.net/board/Projets/site", "lien tableau Kanbante"); ok(items[0].context === "Projets/site · En cours", "contexte Kanbante"); /* nativeSearchUrl */ ok(rp.nativeSearchUrl("tiktak", "https://tiktak-dev.dracodev.net/", "q") === "https://tiktak-dev.dracodev.net/search?q=q", "repli TikTak"); ok(rp.nativeSearchUrl("obsigate", "https://og-dev.dracodev.net/", "q") === "https://og-dev.dracodev.net/", "repli ObsiGate = accueil (palette)"); console.log("recherche.test.js : " + n + " assertions OK");