From 4abcba8de54a6ccdab92a45182f2b7a0004b87cf Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sun, 18 Jan 2026 20:22:07 -0500 Subject: [PATCH] Refine for-you tag preference runtime --- js/app.js | 7 +- .../tag-preference-filter.test.mjs | 86 +++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/feed-engine/tag-preference-filter.test.mjs diff --git a/js/app.js b/js/app.js index 4c1b40cf..ef0270f6 100644 --- a/js/app.js +++ b/js/app.js @@ -5513,7 +5513,12 @@ class Application { : new Set(); const preferenceSource = - typeof this.getHashtagPreferences === "function" + this.hashtagPreferencesSnapshot && + typeof this.hashtagPreferencesSnapshot === "object" + ? this.hashtagPreferencesSnapshot + : typeof this.createHashtagPreferencesSnapshot === "function" + ? this.createHashtagPreferencesSnapshot() + : typeof this.getHashtagPreferences === "function" ? this.getHashtagPreferences() : {}; const { interests = [], disinterests = [] } = preferenceSource || {}; diff --git a/tests/feed-engine/tag-preference-filter.test.mjs b/tests/feed-engine/tag-preference-filter.test.mjs new file mode 100644 index 00000000..f689b8ef --- /dev/null +++ b/tests/feed-engine/tag-preference-filter.test.mjs @@ -0,0 +1,86 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +import { createTagPreferenceFilterStage } from "../../js/feedEngine/stages.js"; + +test("tag preference stage filters by interests and excludes disinterests", async () => { + const stage = createTagPreferenceFilterStage(); + + const items = [ + { + video: { + id: "keep", + pubkey: "a".repeat(64), + tags: [["t", "Cats"]], + }, + metadata: {}, + }, + { + video: { + id: "exclude-disinterest", + pubkey: "b".repeat(64), + tags: [["t", "Dogs"]], + }, + metadata: {}, + }, + { + video: { + id: "exclude-no-interest", + pubkey: "c".repeat(64), + tags: [["t", "Birds"]], + }, + metadata: {}, + }, + { + video: { + id: "exclude-mixed", + pubkey: "d".repeat(64), + tags: [["t", "Cats"], ["t", "Dogs"]], + }, + metadata: {}, + }, + ]; + + const result = await stage(items, { + runtime: { + tagPreferences: { + interests: ["cats"], + disinterests: ["dogs"], + }, + }, + addWhy() {}, + }); + + assert.equal(result.length, 1); + assert.equal(result[0].video.id, "keep"); + assert.deepEqual(result[0].metadata.matchedInterests, ["cats"]); +}); + +test("tag preference stage accepts interests from nip71 hashtags", async () => { + const stage = createTagPreferenceFilterStage(); + + const items = [ + { + video: { + id: "nip71", + pubkey: "e".repeat(64), + nip71: { hashtags: ["Space"] }, + }, + metadata: {}, + }, + ]; + + const result = await stage(items, { + runtime: { + tagPreferences: { + interests: ["space"], + disinterests: [], + }, + }, + addWhy() {}, + }); + + assert.equal(result.length, 1); + assert.equal(result[0].video.id, "nip71"); + assert.deepEqual(result[0].metadata.matchedInterests, ["space"]); +});