mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-02 19:02:28 +00:00
Merge pull request #1388 from PR0M3TH3AN/ai/reproducers-repost-comments-20250222-15793865835676794725
Add reproducer for repost comment visibility bug
This commit is contained in:
4 files changed
+102
-111
No files matched your search
@@ -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.");
|
||||
}
|
||||
@@ -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));
|
||||
Reference in new issue
Block a user