From e993046d60e26a8ca76e7119f641fc9d62f78d02 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 18:02:01 +0000 Subject: [PATCH] fix(admin): exclude whitelisted users from blacklist in admin state and fix unit tests - Modified `sanitizeAdminState` in `js/adminListStore.js` to ensure whitelisted users are automatically excluded from the blacklist. - Updated `tests/admin-list-store.test.mjs` to use `throw-community` failure mode in the mock pool, fixing a flaky test case that incorrectly assumed base lists would load when `throw-authors` was active. - Updated `tests/ui/tag-pill-list.test.mjs` to expect `#` prefixed tags, aligning with recent UI changes. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- js/adminListStore.js | 1 + tests/admin-list-store.test.mjs | 10 +++++++++- tests/ui/tag-pill-list.test.mjs | 14 +++++++------- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/js/adminListStore.js b/js/adminListStore.js index 69e867a8..afed1d2f 100644 --- a/js/adminListStore.js +++ b/js/adminListStore.js @@ -202,6 +202,7 @@ function sanitizeAdminState(state = {}) { normalizeNpub(ADMIN_SUPER_NPUB), ...ADMIN_EDITORS_NPUBS.map(normalizeNpub), ...sanitizedEditors.map(normalizeNpub), + ...sanitizedWhitelist.map(normalizeNpub), ]); const sanitizedBlacklist = sanitizeNpubList(state.blacklist || []).filter( diff --git a/tests/admin-list-store.test.mjs b/tests/admin-list-store.test.mjs index bcf3df43..5cb39353 100644 --- a/tests/admin-list-store.test.mjs +++ b/tests/admin-list-store.test.mjs @@ -272,6 +272,14 @@ nostrClient.pool = { throw new Error("list failure for authors"); } + if (listFailureMode === "throw-community") { + const fullSourceTag = `${ADMIN_LIST_NAMESPACE}:${ADMIN_COMMUNITY_BLACKLIST_SOURCES}`; + const fullPrefix = `${ADMIN_LIST_NAMESPACE}:${ADMIN_COMMUNITY_BLACKLIST_PREFIX}`; + if (dTag === fullSourceTag || dTag.startsWith(fullPrefix)) { + throw new Error("list failure for community"); + } + } + const key = `${authorKey}::${dTag}`; const fallbackKey = `*::${dTag}`; const event = listEventRegistry.get(key) || listEventRegistry.get(fallbackKey); @@ -451,7 +459,7 @@ assert.deepEqual( setListFailureMode(null); resetListRegistry(); -setListFailureMode("throw-authors"); +setListFailureMode("throw-community"); registerListEvent({ dTag: editorsDTag, diff --git a/tests/ui/tag-pill-list.test.mjs b/tests/ui/tag-pill-list.test.mjs index 18527948..56ff8f99 100644 --- a/tests/ui/tag-pill-list.test.mjs +++ b/tests/ui/tag-pill-list.test.mjs @@ -25,7 +25,7 @@ test("renderTagPillStrip builds buttons with labels and icons", () => { assert.ok(button.classList.contains("pill")); assert.ok(button.classList.contains("video-tag-pill")); assert.ok(button.classList.contains("focus-ring")); - assert.equal(button.dataset.tag, tag); + assert.equal(button.dataset.tag, `#${tag}`); assert.equal(button.title, `#${tag}`); assert.equal(button.dataset.preferenceState, "neutral"); assert.equal(button.hasAttribute("data-variant"), false); @@ -50,7 +50,7 @@ test("renderTagPillStrip applies preference state styling", () => { document, tags: ["nostr", "video"], getTagState(tag) { - return tag === "nostr" ? "interest" : "disinterest"; + return tag === "#nostr" ? "interest" : "disinterest"; }, }); @@ -76,7 +76,7 @@ test("renderTagPillStrip wires the activation callback", () => { buttons[0].click(); assert.equal(activations.length, 1); - assert.equal(activations[0].tag, "nostr"); + assert.equal(activations[0].tag, "#nostr"); assert.equal(activations[0].button, buttons[0]); assert(activations[0].event instanceof document.defaultView.Event); }); @@ -97,7 +97,7 @@ test("updateTagPillStrip replaces buttons and rewires handlers", () => { document.body.append(root); initialButtons[0].click(); - assert.deepEqual(firstActivations, ["nostr"]); + assert.deepEqual(firstActivations, ["#nostr"]); const { buttons: updatedButtons } = updateTagPillStrip({ root, @@ -110,7 +110,7 @@ test("updateTagPillStrip replaces buttons and rewires handlers", () => { }); assert.equal(root.querySelectorAll("button").length, 1); - assert.equal(updatedButtons[0].dataset.tag, "video"); + assert.equal(updatedButtons[0].dataset.tag, "#video"); const updatedIcon = updatedButtons[0].querySelector(".video-tag-pill__icon svg"); assert(updatedIcon, "updated button should contain the svg icon"); @@ -119,8 +119,8 @@ test("updateTagPillStrip replaces buttons and rewires handlers", () => { // Ensure the old handler is removed by dispatching a click on the detached button. initialButtons[0].dispatchEvent(new document.defaultView.Event("click", { bubbles: true })); - assert.deepEqual(firstActivations, ["nostr"]); + assert.deepEqual(firstActivations, ["#nostr"]); updatedButtons[0].click(); - assert.deepEqual(secondActivations, [{ tag: "video", button: updatedButtons[0] }]); + assert.deepEqual(secondActivations, [{ tag: "#video", button: updatedButtons[0] }]); });