Merge pull request #1388 from PR0M3TH3AN/ai/reproducers-repost-comments-20250222-15793865835676794725

Add reproducer for repost comment visibility bug
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-01-19 10:35:09 -05:00
commit 76566651a3
4 files changed
+102 -111

No files matched your search

-58
View File
@@ -1,58 +0,0 @@
import { __testExports } from "./js/nostr/commentEvents.js";
const { isVideoCommentEvent, normalizeCommentTarget } = __testExports;
import { devLogger, userLogger } from "./js/utils/logger.js";
// Logger mocking removed
const videoEventId = "0000000000000000000000000000000000000000000000000000000000000001";
const rootKind = "30078";
const rootAuthor = "0000000000000000000000000000000000000000000000000000000000000002";
const targetInput = {
videoEventId,
videoKind: rootKind,
videoAuthorPubkey: rootAuthor,
};
const descriptor = normalizeCommentTarget(targetInput);
console.log("Descriptor:", JSON.stringify(descriptor, null, 2));
const validEvent = {
kind: 1111,
tags: [
["e", videoEventId, "wss://relay.example.com", "root"],
["K", rootKind],
["P", rootAuthor],
],
};
const missingKTagEvent = {
kind: 1111,
tags: [
["e", videoEventId, "wss://relay.example.com", "root"],
["P", rootAuthor],
],
};
const mismatchKTagEvent = {
kind: 1111,
tags: [
["e", videoEventId, "wss://relay.example.com", "root"],
["K", "12345"], // Wrong kind
["P", rootAuthor],
],
};
const legacyEvent = {
kind: 1,
tags: [
["e", videoEventId, "wss://relay.example.com", "root"],
],
};
console.log("Testing Valid Event:", isVideoCommentEvent(validEvent, descriptor));
console.log("Testing Missing K Tag Event:", isVideoCommentEvent(missingKTagEvent, descriptor));
console.log("Testing Mismatch K Tag Event:", isVideoCommentEvent(mismatchKTagEvent, descriptor));
console.log("Testing Legacy Event:", isVideoCommentEvent(legacyEvent, descriptor));
@@ -0,0 +1,29 @@
# Repost Comment Visibility Bug
This reproducer demonstrates an issue where comments made on an original video are not visible when viewing that video via a Repost (Kind 6).
## The Bug
When viewing a repost, the application often passes the Repost event's metadata (Kind 6, Reposter Pubkey) along with the *Original Video's ID* to the comment system.
The `CommentThreadService` (via `normalizeCommentTarget`) creates a filter descriptor based on this input. It expects comments to tag the **Repost** (Kind 6) and the **Reposter**.
However, comments are almost always made on the **Original Video** (Kind 30078), tagging the **Original Author**.
Because `isVideoCommentEvent` enforces strict matching of `rootKind` and `rootAuthor` against the descriptor, it rejects the valid comments on the original video, resulting in an empty comment section.
## Running the Reproducer
```bash
node --import ./tests/test-helpers/setup-localstorage.mjs examples/reproducers/2-repost-comment-visibility-bug/reproduce_issue.js
```
## Expected Output (Failure)
```
Input Target: { ... videoKind: 6 ... }
Generated Descriptor: { ... rootKind: '6' ... }
...
Is Comment Visible? false
FAIL: Comment on original video is NOT visible when viewing repost.
```
@@ -0,0 +1,73 @@
import { __testExports } from "../../../js/nostr/commentEvents.js";
const { isVideoCommentEvent, normalizeCommentTarget } = __testExports;
/**
* REPRODUCER: Repost Comment Visibility Bug
*
* ISSUE:
* When a video is a repost (Kind 6), the UI may pass the Repost event's metadata
* (kind: 6, author: reposter) along with the Original Video's ID to the comment service.
*
* `normalizeCommentTarget` uses this metadata to build a descriptor that expects comments
* to tag the Repost event (Kind 6) and the Reposter.
*
* However, comments are typically made on the Original Video (Kind 30078), tagging the
* Original Author and Original Kind.
*
* `isVideoCommentEvent` then filters out these valid comments because they don't match
* the "expected" rootKind/rootAuthor (which are set to Repost details).
*
* EXPECTED BEHAVIOR:
* Comments on the original video should be visible even when viewing the repost.
* The descriptor should normalize to the Original Video's metadata if the ID belongs to it,
* OR `isVideoCommentEvent` should be smart enough to handle this mismatch.
*/
// Mock Data
const originalVideoId =
"0000000000000000000000000000000000000000000000000000000000000001";
const originalAuthor =
"0000000000000000000000000000000000000000000000000000000000000002";
const originalKind = 30078;
const reposterPubkey =
"0000000000000000000000000000000000000000000000000000000000000003";
const repostKind = 6;
// The Input provided by UI when viewing a Repost
// It incorrectly mixes Original ID with Repost Kind/Author in the current flow
const targetInput = {
videoEventId: originalVideoId,
videoKind: repostKind,
videoAuthorPubkey: reposterPubkey
};
console.log("Input Target:", targetInput);
const descriptor = normalizeCommentTarget(targetInput);
console.log("Generated Descriptor:", JSON.stringify(descriptor, null, 2));
// A valid comment on the ORIGINAL video
const validCommentOnOriginal = {
kind: 1111,
tags: [
["e", originalVideoId, "wss://relay.example.com", "root"],
["K", String(originalKind)],
["P", originalAuthor]
]
};
console.log("Comment Event Tags:", validCommentOnOriginal.tags);
// Run the check
const isVisible = isVideoCommentEvent(validCommentOnOriginal, descriptor);
console.log(`\nIs Comment Visible? ${isVisible}`);
if (!isVisible) {
console.error(
"FAIL: Comment on original video is NOT visible when viewing repost."
);
process.exit(1);
} else {
console.log("PASS: Comment on original video is visible.");
}
-53
View File
@@ -1,53 +0,0 @@
import { __testExports } from "./js/nostr/commentEvents.js";
const { isVideoCommentEvent, normalizeCommentTarget } = __testExports;
const originalVideoId = "0000000000000000000000000000000000000000000000000000000000000001";
const originalAuthor = "0000000000000000000000000000000000000000000000000000000000000002";
const originalKind = "30078";
const reposterPubkey = "0000000000000000000000000000000000000000000000000000000000000003";
const repostKind = "6";
// Scenario: UI passes the Repost event as the "video"
const targetInput = {
videoEventId: originalVideoId, // The ID is usually the original ID even in reposts? No, repost has its own ID.
// But CommentThreadService uses video.id.
// If video is Repost, video.id is Repost ID.
// But comments are on Original ID.
// So if video.id is Repost ID, then we are fetching comments for the Repost ID!
// And the comment event tags the Repost ID? No, it tags the Original ID.
// So we wouldn't even FETCH the comments if we used Repost ID.
// Wait, if loadThread is called with Repost object, videoEventId = Repost ID.
// fetchThread queries for #e = Repost ID.
// But comments are on Original ID.
// So we get NO comments.
// So the issue is even earlier: we are querying for the wrong ID.
// BUT, assuming we somehow got the comment (maybe via legacy #e tag pointing to Repost?),
// let's see if it passes filter.
// Let's assume the UI unwraps the ID but passes the Repost Kind/Pubkey?
// If video.id is Original ID, but video.kind is 6 (Repost Kind) and video.pubkey is Reposter.
videoEventId: originalVideoId,
videoKind: repostKind,
videoAuthorPubkey: reposterPubkey,
};
const descriptor = normalizeCommentTarget(targetInput);
console.log("Descriptor:", JSON.stringify(descriptor, null, 2));
const validCommentOnOriginal = {
kind: 1111,
tags: [
["e", originalVideoId, "wss://relay.example.com", "root"],
["K", originalKind],
["P", originalAuthor],
],
};
console.log("Testing Valid Comment on Original (against Repost metadata):", isVideoCommentEvent(validCommentOnOriginal, descriptor));