Add tests for modal similar content filtering

This commit is contained in:
thePR0M3TH3AN committed 2025-10-23 17:02:40 -04:00
1 parent 2016c01183
commit d09002e0dd
3 files changed
+223

No files matched your search

+3
View File
@@ -1879,6 +1879,9 @@ class Application {
if (candidate.isPrivate === true) {
continue;
}
if (candidate.isNsfw === true && ALLOW_NSFW_CONTENT !== true) {
continue;
}
const candidatePubkey = typeof candidate.pubkey === "string" ? candidate.pubkey : "";
if (candidatePubkey && this.isAuthorBlocked(candidatePubkey)) {
+200
View File
@@ -0,0 +1,200 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import Application from "../../js/app.js";
const computeSimilarContent = Application.prototype.computeSimilarContentCandidates;
function createAppStub({ videos = [] } = {}) {
const videosMap = new Map();
for (const video of videos) {
if (video && typeof video.id === "string") {
videosMap.set(video.id, video);
}
}
return {
videoListView: { currentVideos: videos },
videosMap,
getKnownVideoPostedAt(video) {
if (Number.isFinite(video?.rootCreatedAt)) {
return Math.floor(video.rootCreatedAt);
}
if (Number.isFinite(video?.created_at)) {
return Math.floor(video.created_at);
}
return null;
},
buildShareUrlFromEventId(id) {
return id ? `https://bitvid.invalid/${id}` : "";
},
formatTimeAgo(timestamp) {
return Number.isFinite(timestamp) ? `${timestamp}s` : "";
},
deriveVideoPointerInfo(video) {
if (video?.pointerInfo) {
return video.pointerInfo;
}
if (typeof video?.pointerKey === "string" && video.pointerKey.trim()) {
return { key: video.pointerKey.trim() };
}
return null;
},
isAuthorBlocked() {
return false;
},
};
}
function createVideo({
id,
pubkey = "author",
displayTags,
tags,
rootCreatedAt,
created_at,
pointerKey,
pointerInfo,
shareUrl,
isPrivate = false,
isNsfw = false,
} = {}) {
const video = {
id,
pubkey,
isPrivate,
isNsfw,
};
if (Array.isArray(displayTags)) {
video.displayTags = displayTags.slice();
}
if (Array.isArray(tags)) {
video.tags = tags.slice();
}
if (Number.isFinite(rootCreatedAt)) {
video.rootCreatedAt = Math.floor(rootCreatedAt);
}
if (Number.isFinite(created_at)) {
video.created_at = Math.floor(created_at);
}
if (typeof pointerKey === "string") {
video.pointerKey = pointerKey;
}
if (pointerInfo) {
video.pointerInfo = pointerInfo;
}
if (typeof shareUrl === "string") {
video.shareUrl = shareUrl;
}
return video;
}
test("orders similar videos by shared tags then timestamp", () => {
const activeVideo = createVideo({
id: "root-video",
displayTags: ["Art", "Music", "News"],
});
const candidateA = createVideo({
id: "video-a",
displayTags: ["art", "music"],
rootCreatedAt: 100,
});
const candidateB = createVideo({
id: "video-b",
displayTags: ["art"],
rootCreatedAt: 200,
});
const candidateC = createVideo({
id: "video-c",
displayTags: ["art", "music"],
rootCreatedAt: 50,
});
const app = createAppStub({
videos: [candidateA, candidateB, candidateC],
});
const matches = computeSimilarContent.call(app, { activeVideo, maxItems: 5 });
assert.equal(matches.length, 3);
assert.deepEqual(
matches.map((entry) => entry.video.id),
["video-a", "video-c", "video-b"],
);
assert.deepEqual(
matches.map((entry) => entry.sharedTagCount),
[2, 2, 1],
);
});
test("returns no matches when the active video lacks tags", () => {
const activeVideo = createVideo({
id: "root-video",
});
const candidate = createVideo({
id: "video-a",
displayTags: ["art"],
});
const app = createAppStub({ videos: [candidate] });
const matches = computeSimilarContent.call(app, { activeVideo, maxItems: 5 });
assert.deepEqual(matches, []);
});
test("skips candidates without tag metadata", () => {
const activeVideo = createVideo({
id: "root-video",
displayTags: ["art"],
});
const candidateWithTags = createVideo({
id: "video-a",
displayTags: ["art"],
});
const candidateWithoutTags = createVideo({
id: "video-b",
});
const app = createAppStub({
videos: [candidateWithTags, candidateWithoutTags],
});
const matches = computeSimilarContent.call(app, { activeVideo, maxItems: 5 });
assert.equal(matches.length, 1);
assert.equal(matches[0].video.id, "video-a");
});
test("filters NSFW and private videos when NSFW content is disabled", () => {
const activeVideo = createVideo({
id: "root-video",
displayTags: ["art"],
});
const publicVideo = createVideo({
id: "video-public",
displayTags: ["art"],
});
const nsfwVideo = createVideo({
id: "video-nsfw",
displayTags: ["art"],
isNsfw: true,
});
const privateVideo = createVideo({
id: "video-private",
displayTags: ["art"],
isPrivate: true,
});
const app = createAppStub({
videos: [publicVideo, nsfwVideo, privateVideo],
});
const matches = computeSimilarContent.call(app, { activeVideo, maxItems: 5 });
assert.deepEqual(
matches.map((entry) => entry.video.id),
["video-public"],
);
});
+20
View File
@@ -2,6 +2,26 @@ if (typeof globalThis.window === "undefined") {
globalThis.window = {};
}
if (typeof globalThis.self === "undefined") {
globalThis.self = globalThis;
}
if (typeof globalThis.WebSocket === "undefined") {
globalThis.WebSocket = class WebSocket {};
}
if (typeof globalThis.navigator === "undefined") {
globalThis.navigator = { userAgent: "node" };
}
if (typeof globalThis.window.WebSocket === "undefined") {
globalThis.window.WebSocket = globalThis.WebSocket;
}
if (typeof globalThis.window.navigator === "undefined") {
globalThis.window.navigator = globalThis.navigator;
}
if (typeof globalThis.localStorage === "undefined") {
const store = new Map();
globalThis.localStorage = {