A community based topic aggregation platform built on atproto

test: update integration tests for community.comment namespace

Update all comment integration tests to use the new
social.coves.community.comment namespace.

Files updated:
- comment_consumer_test.go: 18 tests covering create/update/delete
- comment_query_test.go: 11 tests covering queries and pagination
- comment_vote_test.go: 6 tests covering voting on comments

All test data now uses the correct namespace for URI construction,
$type fields, and collection names. Tests verify that the new
namespace works correctly throughout the entire comment lifecycle.

All 22 integration tests passing ✅

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

+61 -61
tests/integration/comment_consumer_test.go
···
t.Run("Create comment on post", func(t *testing.T) {
rkey := generateTID()
-
uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey)
+
uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey)
// Simulate Jetstream comment create event
event := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "test-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafytest123",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "This is a test comment on a post!",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Commit: &jetstream.CommitEvent{
Rev: "test-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafytest456",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Idempotent test comment",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
t.Run("Create nested comment replies", func(t *testing.T) {
// Create first-level comment on post
comment1Rkey := generateTID()
-
comment1URI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, comment1Rkey)
+
comment1URI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, comment1Rkey)
event1 := &jetstream.JetstreamEvent{
Did: testUser.DID,
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: comment1Rkey,
CID: "bafycomment1",
Record: map[string]interface{}{
···
// Create second-level comment (reply to first comment)
comment2Rkey := generateTID()
-
comment2URI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, comment2Rkey)
+
comment2URI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, comment2Rkey)
event2 := &jetstream.JetstreamEvent{
Did: testUser.DID,
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: comment2Rkey,
CID: "bafycomment2",
Record: map[string]interface{}{
···
t.Run("Update comment content preserves vote counts", func(t *testing.T) {
rkey := generateTID()
-
uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey)
+
uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey)
// Create initial comment
createEvent := &jetstream.JetstreamEvent{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafyoriginal",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "update",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafyupdated",
Record: map[string]interface{}{
···
t.Run("Delete comment decrements parent count", func(t *testing.T) {
rkey := generateTID()
-
uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey)
+
uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey)
// Create comment
createEvent := &jetstream.JetstreamEvent{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafydelete",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "delete",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
},
}
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafyidempdelete",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "delete",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
},
}
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: generateTID(),
CID: "bafyinvalid",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: generateTID(),
CID: "bafyinvalid2",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: generateTID(),
CID: "bafyinvalid3",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: generateTID(),
CID: "bafyinvalid4",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: generateTID(),
CID: "bafytoobig",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: generateTID(),
CID: "bafymalformed",
Record: map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: generateTID(),
CID: "bafymalformed2",
Record: map[string]interface{}{
···
// |- Comment 4
comment1 := &comments.Comment{
-
URI: fmt.Sprintf("at://%s/social.coves.feed.comment/1", testUser.DID),
+
URI: fmt.Sprintf("at://%s/social.coves.community.comment/1", testUser.DID),
CID: "bafyc1",
RKey: "1",
CommenterDID: testUser.DID,
···
}
comment2 := &comments.Comment{
-
URI: fmt.Sprintf("at://%s/social.coves.feed.comment/2", testUser.DID),
+
URI: fmt.Sprintf("at://%s/social.coves.community.comment/2", testUser.DID),
CID: "bafyc2",
RKey: "2",
CommenterDID: testUser.DID,
···
}
comment3 := &comments.Comment{
-
URI: fmt.Sprintf("at://%s/social.coves.feed.comment/3", testUser.DID),
+
URI: fmt.Sprintf("at://%s/social.coves.community.comment/3", testUser.DID),
CID: "bafyc3",
RKey: "3",
CommenterDID: testUser.DID,
···
}
comment4 := &comments.Comment{
-
URI: fmt.Sprintf("at://%s/social.coves.feed.comment/4", testUser.DID),
+
URI: fmt.Sprintf("at://%s/social.coves.community.comment/4", testUser.DID),
CID: "bafyc4",
RKey: "4",
CommenterDID: testUser.DID,
···
// When C1 finally arrives, its reply_count should be 1, not 0
parentRkey := generateTID()
-
parentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, parentRkey)
+
parentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, parentRkey)
childRkey := generateTID()
-
childURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, childRkey)
+
childURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, childRkey)
// Step 1: Index child FIRST (before parent exists)
childEvent := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "child-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: childRkey,
CID: "bafychild",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "This is a reply to a comment that doesn't exist yet!",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Commit: &jetstream.CommitEvent{
Rev: "parent-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: parentRkey,
CID: "bafyparent",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "This is the parent comment arriving late",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
t.Run("Multiple children arrive before parent", func(t *testing.T) {
parentRkey := generateTID()
-
parentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, parentRkey)
+
parentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, parentRkey)
// Index 3 children before parent
for i := 1; i <= 3; i++ {
···
Commit: &jetstream.CommitEvent{
Rev: fmt.Sprintf("child-%d-rev", i),
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: childRkey,
CID: fmt.Sprintf("bafychild%d", i),
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": fmt.Sprintf("Reply %d before parent", i),
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Commit: &jetstream.CommitEvent{
Rev: "parent2-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: parentRkey,
CID: "bafyparent2",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Parent with 3 pre-existing children",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
postURI := createTestPost(t, db, testCommunity, testUser.DID, "Resurrection Test", 0, time.Now())
rkey := generateTID()
-
commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey)
+
commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey)
t.Run("Recreate deleted comment with same rkey", func(t *testing.T) {
// Step 1: Create initial comment
···
Commit: &jetstream.CommitEvent{
Rev: "v1",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafyoriginal",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Original comment content",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Commit: &jetstream.CommitEvent{
Rev: "v2",
Operation: "delete",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
},
···
Commit: &jetstream.CommitEvent{
Rev: "v3",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey, // Same rkey!
CID: "bafyresurrected",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Resurrected comment with new content",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
post2URI := createTestPost(t, db, testCommunity, testUser.DID, "Post 2", 0, time.Now())
rkey2 := generateTID()
-
commentURI2 := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey2)
+
commentURI2 := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey2)
// Step 1: Create comment on Post 1
createEvent := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "v1",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey2,
CID: "bafyv1",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Original on Post 1",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Commit: &jetstream.CommitEvent{
Rev: "v2",
Operation: "delete",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey2,
},
···
Commit: &jetstream.CommitEvent{
Rev: "v3",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey2, // Same rkey!
CID: "bafyv3",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "New comment on Post 2",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
postURI2 := createTestPost(t, db, testCommunity, testUser.DID, "Post 2", 0, time.Now())
rkey := generateTID()
-
commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey)
+
commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey)
t.Run("Reject UPDATE that changes parent URI", func(t *testing.T) {
// Create comment on Post 1
···
Commit: &jetstream.CommitEvent{
Rev: "v1",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafycomment1",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Comment on Post 1",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Commit: &jetstream.CommitEvent{
Rev: "v2",
Operation: "update",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: "bafycomment2",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Trying to hijack this comment to Post 2",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
t.Run("Allow UPDATE that only changes content (threading unchanged)", func(t *testing.T) {
rkey2 := generateTID()
-
commentURI2 := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey2)
+
commentURI2 := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey2)
// Create comment
createEvent := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "v1",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey2,
CID: "bafycomment3",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Original content",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Commit: &jetstream.CommitEvent{
Rev: "v2",
Operation: "update",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey2,
CID: "bafycomment4",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Updated content",
"reply": map[string]interface{}{
"root": map[string]interface{}{
+6 -6
tests/integration/comment_query_test.go
···
commentURIs := make([]string, 5)
for i := 0; i < 5; i++ {
rkey := generateTID()
-
uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey)
+
uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey)
commentURIs[i] = uri
event := &jetstream.JetstreamEvent{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: rkey,
CID: fmt.Sprintf("bafyc%d", i),
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": fmt.Sprintf("Comment %d", i),
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "delete",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: strings.Split(commentURIs[1], "/")[4],
},
}
···
Kind: "commit",
Commit: &jetstream.CommitEvent{
Operation: "delete",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: strings.Split(commentURIs[3], "/")[4],
},
}
···
ctx := context.Background()
rkey := generateTID()
-
uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", commenterDID, rkey)
+
uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", commenterDID, rkey)
// Insert comment directly for speed
_, err := db.ExecContext(ctx, `
+15 -15
tests/integration/comment_vote_test.go
···
t.Run("Upvote on comment increments count", func(t *testing.T) {
// Create a comment
commentRKey := generateTID()
-
commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey)
+
commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey)
commentCID := "bafycomment123"
commentEvent := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "test-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: commentRKey,
CID: commentCID,
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Comment to vote on",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
t.Run("Downvote on comment increments downvote count", func(t *testing.T) {
// Create a comment
commentRKey := generateTID()
-
commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey)
+
commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey)
commentCID := "bafycomment456"
commentEvent := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "test-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: commentRKey,
CID: commentCID,
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Comment to downvote",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
t.Run("Delete vote decrements comment counts", func(t *testing.T) {
// Create comment
commentRKey := generateTID()
-
commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey)
+
commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey)
commentCID := "bafycomment789"
commentEvent := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "test-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: commentRKey,
CID: commentCID,
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Comment for vote deletion test",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
t.Run("Viewer with vote sees vote state", func(t *testing.T) {
// Create comment
commentRKey := generateTID()
-
commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey)
+
commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey)
commentCID := "bafycomment111"
commentEvent := &jetstream.JetstreamEvent{
···
Commit: &jetstream.CommitEvent{
Rev: "test-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: commentRKey,
CID: commentCID,
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Comment with viewer vote",
"reply": map[string]interface{}{
"root": map[string]interface{}{
···
t.Run("Viewer without vote sees empty state", func(t *testing.T) {
// Create comment (no vote)
commentRKey := generateTID()
-
commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey)
+
commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey)
commentEvent := &jetstream.JetstreamEvent{
Did: testUser.DID,
···
Commit: &jetstream.CommitEvent{
Rev: "test-rev",
Operation: "create",
-
Collection: "social.coves.feed.comment",
+
Collection: "social.coves.community.comment",
RKey: commentRKey,
CID: "bafycomment222",
Record: map[string]interface{}{
-
"$type": "social.coves.feed.comment",
+
"$type": "social.coves.community.comment",
"content": "Comment without viewer vote",
"reply": map[string]interface{}{
"root": map[string]interface{}{