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>

+82 -82
+61 -61
tests/integration/comment_consumer_test.go
··· 32 33 t.Run("Create comment on post", func(t *testing.T) { 34 rkey := generateTID() 35 - uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey) 36 37 // Simulate Jetstream comment create event 38 event := &jetstream.JetstreamEvent{ ··· 41 Commit: &jetstream.CommitEvent{ 42 Rev: "test-rev", 43 Operation: "create", 44 - Collection: "social.coves.feed.comment", 45 RKey: rkey, 46 CID: "bafytest123", 47 Record: map[string]interface{}{ 48 - "$type": "social.coves.feed.comment", 49 "content": "This is a test comment on a post!", 50 "reply": map[string]interface{}{ 51 "root": map[string]interface{}{ ··· 115 Commit: &jetstream.CommitEvent{ 116 Rev: "test-rev", 117 Operation: "create", 118 - Collection: "social.coves.feed.comment", 119 RKey: rkey, 120 CID: "bafytest456", 121 Record: map[string]interface{}{ 122 - "$type": "social.coves.feed.comment", 123 "content": "Idempotent test comment", 124 "reply": map[string]interface{}{ 125 "root": map[string]interface{}{ ··· 191 t.Run("Create nested comment replies", func(t *testing.T) { 192 // Create first-level comment on post 193 comment1Rkey := generateTID() 194 - comment1URI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, comment1Rkey) 195 196 event1 := &jetstream.JetstreamEvent{ 197 Did: testUser.DID, 198 Kind: "commit", 199 Commit: &jetstream.CommitEvent{ 200 Operation: "create", 201 - Collection: "social.coves.feed.comment", 202 RKey: comment1Rkey, 203 CID: "bafycomment1", 204 Record: map[string]interface{}{ ··· 225 226 // Create second-level comment (reply to first comment) 227 comment2Rkey := generateTID() 228 - comment2URI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, comment2Rkey) 229 230 event2 := &jetstream.JetstreamEvent{ 231 Did: testUser.DID, 232 Kind: "commit", 233 Commit: &jetstream.CommitEvent{ 234 Operation: "create", 235 - Collection: "social.coves.feed.comment", 236 RKey: comment2Rkey, 237 CID: "bafycomment2", 238 Record: map[string]interface{}{ ··· 346 347 t.Run("Update comment content preserves vote counts", func(t *testing.T) { 348 rkey := generateTID() 349 - uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey) 350 351 // Create initial comment 352 createEvent := &jetstream.JetstreamEvent{ ··· 354 Kind: "commit", 355 Commit: &jetstream.CommitEvent{ 356 Operation: "create", 357 - Collection: "social.coves.feed.comment", 358 RKey: rkey, 359 CID: "bafyoriginal", 360 Record: map[string]interface{}{ ··· 395 Kind: "commit", 396 Commit: &jetstream.CommitEvent{ 397 Operation: "update", 398 - Collection: "social.coves.feed.comment", 399 RKey: rkey, 400 CID: "bafyupdated", 401 Record: map[string]interface{}{ ··· 472 473 t.Run("Delete comment decrements parent count", func(t *testing.T) { 474 rkey := generateTID() 475 - uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey) 476 477 // Create comment 478 createEvent := &jetstream.JetstreamEvent{ ··· 480 Kind: "commit", 481 Commit: &jetstream.CommitEvent{ 482 Operation: "create", 483 - Collection: "social.coves.feed.comment", 484 RKey: rkey, 485 CID: "bafydelete", 486 Record: map[string]interface{}{ ··· 518 Kind: "commit", 519 Commit: &jetstream.CommitEvent{ 520 Operation: "delete", 521 - Collection: "social.coves.feed.comment", 522 RKey: rkey, 523 }, 524 } ··· 559 Kind: "commit", 560 Commit: &jetstream.CommitEvent{ 561 Operation: "create", 562 - Collection: "social.coves.feed.comment", 563 RKey: rkey, 564 CID: "bafyidempdelete", 565 Record: map[string]interface{}{ ··· 590 Kind: "commit", 591 Commit: &jetstream.CommitEvent{ 592 Operation: "delete", 593 - Collection: "social.coves.feed.comment", 594 RKey: rkey, 595 }, 596 } ··· 651 Kind: "commit", 652 Commit: &jetstream.CommitEvent{ 653 Operation: "create", 654 - Collection: "social.coves.feed.comment", 655 RKey: generateTID(), 656 CID: "bafyinvalid", 657 Record: map[string]interface{}{ ··· 683 Kind: "commit", 684 Commit: &jetstream.CommitEvent{ 685 Operation: "create", 686 - Collection: "social.coves.feed.comment", 687 RKey: generateTID(), 688 CID: "bafyinvalid2", 689 Record: map[string]interface{}{ ··· 715 Kind: "commit", 716 Commit: &jetstream.CommitEvent{ 717 Operation: "create", 718 - Collection: "social.coves.feed.comment", 719 RKey: generateTID(), 720 CID: "bafyinvalid3", 721 Record: map[string]interface{}{ ··· 747 Kind: "commit", 748 Commit: &jetstream.CommitEvent{ 749 Operation: "create", 750 - Collection: "social.coves.feed.comment", 751 RKey: generateTID(), 752 CID: "bafyinvalid4", 753 Record: map[string]interface{}{ ··· 779 Kind: "commit", 780 Commit: &jetstream.CommitEvent{ 781 Operation: "create", 782 - Collection: "social.coves.feed.comment", 783 RKey: generateTID(), 784 CID: "bafytoobig", 785 Record: map[string]interface{}{ ··· 814 Kind: "commit", 815 Commit: &jetstream.CommitEvent{ 816 Operation: "create", 817 - Collection: "social.coves.feed.comment", 818 RKey: generateTID(), 819 CID: "bafymalformed", 820 Record: map[string]interface{}{ ··· 849 Kind: "commit", 850 Commit: &jetstream.CommitEvent{ 851 Operation: "create", 852 - Collection: "social.coves.feed.comment", 853 RKey: generateTID(), 854 CID: "bafymalformed2", 855 Record: map[string]interface{}{ ··· 911 // |- Comment 4 912 913 comment1 := &comments.Comment{ 914 - URI: fmt.Sprintf("at://%s/social.coves.feed.comment/1", testUser.DID), 915 CID: "bafyc1", 916 RKey: "1", 917 CommenterDID: testUser.DID, ··· 925 } 926 927 comment2 := &comments.Comment{ 928 - URI: fmt.Sprintf("at://%s/social.coves.feed.comment/2", testUser.DID), 929 CID: "bafyc2", 930 RKey: "2", 931 CommenterDID: testUser.DID, ··· 939 } 940 941 comment3 := &comments.Comment{ 942 - URI: fmt.Sprintf("at://%s/social.coves.feed.comment/3", testUser.DID), 943 CID: "bafyc3", 944 RKey: "3", 945 CommenterDID: testUser.DID, ··· 953 } 954 955 comment4 := &comments.Comment{ 956 - URI: fmt.Sprintf("at://%s/social.coves.feed.comment/4", testUser.DID), 957 CID: "bafyc4", 958 RKey: "4", 959 CommenterDID: testUser.DID, ··· 1074 // When C1 finally arrives, its reply_count should be 1, not 0 1075 1076 parentRkey := generateTID() 1077 - parentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, parentRkey) 1078 1079 childRkey := generateTID() 1080 - childURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, childRkey) 1081 1082 // Step 1: Index child FIRST (before parent exists) 1083 childEvent := &jetstream.JetstreamEvent{ ··· 1086 Commit: &jetstream.CommitEvent{ 1087 Rev: "child-rev", 1088 Operation: "create", 1089 - Collection: "social.coves.feed.comment", 1090 RKey: childRkey, 1091 CID: "bafychild", 1092 Record: map[string]interface{}{ 1093 - "$type": "social.coves.feed.comment", 1094 "content": "This is a reply to a comment that doesn't exist yet!", 1095 "reply": map[string]interface{}{ 1096 "root": map[string]interface{}{ ··· 1128 Commit: &jetstream.CommitEvent{ 1129 Rev: "parent-rev", 1130 Operation: "create", 1131 - Collection: "social.coves.feed.comment", 1132 RKey: parentRkey, 1133 CID: "bafyparent", 1134 Record: map[string]interface{}{ 1135 - "$type": "social.coves.feed.comment", 1136 "content": "This is the parent comment arriving late", 1137 "reply": map[string]interface{}{ 1138 "root": map[string]interface{}{ ··· 1178 1179 t.Run("Multiple children arrive before parent", func(t *testing.T) { 1180 parentRkey := generateTID() 1181 - parentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, parentRkey) 1182 1183 // Index 3 children before parent 1184 for i := 1; i <= 3; i++ { ··· 1189 Commit: &jetstream.CommitEvent{ 1190 Rev: fmt.Sprintf("child-%d-rev", i), 1191 Operation: "create", 1192 - Collection: "social.coves.feed.comment", 1193 RKey: childRkey, 1194 CID: fmt.Sprintf("bafychild%d", i), 1195 Record: map[string]interface{}{ 1196 - "$type": "social.coves.feed.comment", 1197 "content": fmt.Sprintf("Reply %d before parent", i), 1198 "reply": map[string]interface{}{ 1199 "root": map[string]interface{}{ ··· 1223 Commit: &jetstream.CommitEvent{ 1224 Rev: "parent2-rev", 1225 Operation: "create", 1226 - Collection: "social.coves.feed.comment", 1227 RKey: parentRkey, 1228 CID: "bafyparent2", 1229 Record: map[string]interface{}{ 1230 - "$type": "social.coves.feed.comment", 1231 "content": "Parent with 3 pre-existing children", 1232 "reply": map[string]interface{}{ 1233 "root": map[string]interface{}{ ··· 1283 postURI := createTestPost(t, db, testCommunity, testUser.DID, "Resurrection Test", 0, time.Now()) 1284 1285 rkey := generateTID() 1286 - commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey) 1287 1288 t.Run("Recreate deleted comment with same rkey", func(t *testing.T) { 1289 // Step 1: Create initial comment ··· 1293 Commit: &jetstream.CommitEvent{ 1294 Rev: "v1", 1295 Operation: "create", 1296 - Collection: "social.coves.feed.comment", 1297 RKey: rkey, 1298 CID: "bafyoriginal", 1299 Record: map[string]interface{}{ 1300 - "$type": "social.coves.feed.comment", 1301 "content": "Original comment content", 1302 "reply": map[string]interface{}{ 1303 "root": map[string]interface{}{ ··· 1338 Commit: &jetstream.CommitEvent{ 1339 Rev: "v2", 1340 Operation: "delete", 1341 - Collection: "social.coves.feed.comment", 1342 RKey: rkey, 1343 }, 1344 } ··· 1365 Commit: &jetstream.CommitEvent{ 1366 Rev: "v3", 1367 Operation: "create", 1368 - Collection: "social.coves.feed.comment", 1369 RKey: rkey, // Same rkey! 1370 CID: "bafyresurrected", 1371 Record: map[string]interface{}{ 1372 - "$type": "social.coves.feed.comment", 1373 "content": "Resurrected comment with new content", 1374 "reply": map[string]interface{}{ 1375 "root": map[string]interface{}{ ··· 1424 post2URI := createTestPost(t, db, testCommunity, testUser.DID, "Post 2", 0, time.Now()) 1425 1426 rkey2 := generateTID() 1427 - commentURI2 := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey2) 1428 1429 // Step 1: Create comment on Post 1 1430 createEvent := &jetstream.JetstreamEvent{ ··· 1433 Commit: &jetstream.CommitEvent{ 1434 Rev: "v1", 1435 Operation: "create", 1436 - Collection: "social.coves.feed.comment", 1437 RKey: rkey2, 1438 CID: "bafyv1", 1439 Record: map[string]interface{}{ 1440 - "$type": "social.coves.feed.comment", 1441 "content": "Original on Post 1", 1442 "reply": map[string]interface{}{ 1443 "root": map[string]interface{}{ ··· 1476 Commit: &jetstream.CommitEvent{ 1477 Rev: "v2", 1478 Operation: "delete", 1479 - Collection: "social.coves.feed.comment", 1480 RKey: rkey2, 1481 }, 1482 } ··· 1502 Commit: &jetstream.CommitEvent{ 1503 Rev: "v3", 1504 Operation: "create", 1505 - Collection: "social.coves.feed.comment", 1506 RKey: rkey2, // Same rkey! 1507 CID: "bafyv3", 1508 Record: map[string]interface{}{ 1509 - "$type": "social.coves.feed.comment", 1510 "content": "New comment on Post 2", 1511 "reply": map[string]interface{}{ 1512 "root": map[string]interface{}{ ··· 1588 postURI2 := createTestPost(t, db, testCommunity, testUser.DID, "Post 2", 0, time.Now()) 1589 1590 rkey := generateTID() 1591 - commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey) 1592 1593 t.Run("Reject UPDATE that changes parent URI", func(t *testing.T) { 1594 // Create comment on Post 1 ··· 1598 Commit: &jetstream.CommitEvent{ 1599 Rev: "v1", 1600 Operation: "create", 1601 - Collection: "social.coves.feed.comment", 1602 RKey: rkey, 1603 CID: "bafycomment1", 1604 Record: map[string]interface{}{ 1605 - "$type": "social.coves.feed.comment", 1606 "content": "Comment on Post 1", 1607 "reply": map[string]interface{}{ 1608 "root": map[string]interface{}{ ··· 1631 Commit: &jetstream.CommitEvent{ 1632 Rev: "v2", 1633 Operation: "update", 1634 - Collection: "social.coves.feed.comment", 1635 RKey: rkey, 1636 CID: "bafycomment2", 1637 Record: map[string]interface{}{ 1638 - "$type": "social.coves.feed.comment", 1639 "content": "Trying to hijack this comment to Post 2", 1640 "reply": map[string]interface{}{ 1641 "root": map[string]interface{}{ ··· 1679 1680 t.Run("Allow UPDATE that only changes content (threading unchanged)", func(t *testing.T) { 1681 rkey2 := generateTID() 1682 - commentURI2 := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey2) 1683 1684 // Create comment 1685 createEvent := &jetstream.JetstreamEvent{ ··· 1688 Commit: &jetstream.CommitEvent{ 1689 Rev: "v1", 1690 Operation: "create", 1691 - Collection: "social.coves.feed.comment", 1692 RKey: rkey2, 1693 CID: "bafycomment3", 1694 Record: map[string]interface{}{ 1695 - "$type": "social.coves.feed.comment", 1696 "content": "Original content", 1697 "reply": map[string]interface{}{ 1698 "root": map[string]interface{}{ ··· 1721 Commit: &jetstream.CommitEvent{ 1722 Rev: "v2", 1723 Operation: "update", 1724 - Collection: "social.coves.feed.comment", 1725 RKey: rkey2, 1726 CID: "bafycomment4", 1727 Record: map[string]interface{}{ 1728 - "$type": "social.coves.feed.comment", 1729 "content": "Updated content", 1730 "reply": map[string]interface{}{ 1731 "root": map[string]interface{}{
··· 32 33 t.Run("Create comment on post", func(t *testing.T) { 34 rkey := generateTID() 35 + uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey) 36 37 // Simulate Jetstream comment create event 38 event := &jetstream.JetstreamEvent{ ··· 41 Commit: &jetstream.CommitEvent{ 42 Rev: "test-rev", 43 Operation: "create", 44 + Collection: "social.coves.community.comment", 45 RKey: rkey, 46 CID: "bafytest123", 47 Record: map[string]interface{}{ 48 + "$type": "social.coves.community.comment", 49 "content": "This is a test comment on a post!", 50 "reply": map[string]interface{}{ 51 "root": map[string]interface{}{ ··· 115 Commit: &jetstream.CommitEvent{ 116 Rev: "test-rev", 117 Operation: "create", 118 + Collection: "social.coves.community.comment", 119 RKey: rkey, 120 CID: "bafytest456", 121 Record: map[string]interface{}{ 122 + "$type": "social.coves.community.comment", 123 "content": "Idempotent test comment", 124 "reply": map[string]interface{}{ 125 "root": map[string]interface{}{ ··· 191 t.Run("Create nested comment replies", func(t *testing.T) { 192 // Create first-level comment on post 193 comment1Rkey := generateTID() 194 + comment1URI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, comment1Rkey) 195 196 event1 := &jetstream.JetstreamEvent{ 197 Did: testUser.DID, 198 Kind: "commit", 199 Commit: &jetstream.CommitEvent{ 200 Operation: "create", 201 + Collection: "social.coves.community.comment", 202 RKey: comment1Rkey, 203 CID: "bafycomment1", 204 Record: map[string]interface{}{ ··· 225 226 // Create second-level comment (reply to first comment) 227 comment2Rkey := generateTID() 228 + comment2URI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, comment2Rkey) 229 230 event2 := &jetstream.JetstreamEvent{ 231 Did: testUser.DID, 232 Kind: "commit", 233 Commit: &jetstream.CommitEvent{ 234 Operation: "create", 235 + Collection: "social.coves.community.comment", 236 RKey: comment2Rkey, 237 CID: "bafycomment2", 238 Record: map[string]interface{}{ ··· 346 347 t.Run("Update comment content preserves vote counts", func(t *testing.T) { 348 rkey := generateTID() 349 + uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey) 350 351 // Create initial comment 352 createEvent := &jetstream.JetstreamEvent{ ··· 354 Kind: "commit", 355 Commit: &jetstream.CommitEvent{ 356 Operation: "create", 357 + Collection: "social.coves.community.comment", 358 RKey: rkey, 359 CID: "bafyoriginal", 360 Record: map[string]interface{}{ ··· 395 Kind: "commit", 396 Commit: &jetstream.CommitEvent{ 397 Operation: "update", 398 + Collection: "social.coves.community.comment", 399 RKey: rkey, 400 CID: "bafyupdated", 401 Record: map[string]interface{}{ ··· 472 473 t.Run("Delete comment decrements parent count", func(t *testing.T) { 474 rkey := generateTID() 475 + uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey) 476 477 // Create comment 478 createEvent := &jetstream.JetstreamEvent{ ··· 480 Kind: "commit", 481 Commit: &jetstream.CommitEvent{ 482 Operation: "create", 483 + Collection: "social.coves.community.comment", 484 RKey: rkey, 485 CID: "bafydelete", 486 Record: map[string]interface{}{ ··· 518 Kind: "commit", 519 Commit: &jetstream.CommitEvent{ 520 Operation: "delete", 521 + Collection: "social.coves.community.comment", 522 RKey: rkey, 523 }, 524 } ··· 559 Kind: "commit", 560 Commit: &jetstream.CommitEvent{ 561 Operation: "create", 562 + Collection: "social.coves.community.comment", 563 RKey: rkey, 564 CID: "bafyidempdelete", 565 Record: map[string]interface{}{ ··· 590 Kind: "commit", 591 Commit: &jetstream.CommitEvent{ 592 Operation: "delete", 593 + Collection: "social.coves.community.comment", 594 RKey: rkey, 595 }, 596 } ··· 651 Kind: "commit", 652 Commit: &jetstream.CommitEvent{ 653 Operation: "create", 654 + Collection: "social.coves.community.comment", 655 RKey: generateTID(), 656 CID: "bafyinvalid", 657 Record: map[string]interface{}{ ··· 683 Kind: "commit", 684 Commit: &jetstream.CommitEvent{ 685 Operation: "create", 686 + Collection: "social.coves.community.comment", 687 RKey: generateTID(), 688 CID: "bafyinvalid2", 689 Record: map[string]interface{}{ ··· 715 Kind: "commit", 716 Commit: &jetstream.CommitEvent{ 717 Operation: "create", 718 + Collection: "social.coves.community.comment", 719 RKey: generateTID(), 720 CID: "bafyinvalid3", 721 Record: map[string]interface{}{ ··· 747 Kind: "commit", 748 Commit: &jetstream.CommitEvent{ 749 Operation: "create", 750 + Collection: "social.coves.community.comment", 751 RKey: generateTID(), 752 CID: "bafyinvalid4", 753 Record: map[string]interface{}{ ··· 779 Kind: "commit", 780 Commit: &jetstream.CommitEvent{ 781 Operation: "create", 782 + Collection: "social.coves.community.comment", 783 RKey: generateTID(), 784 CID: "bafytoobig", 785 Record: map[string]interface{}{ ··· 814 Kind: "commit", 815 Commit: &jetstream.CommitEvent{ 816 Operation: "create", 817 + Collection: "social.coves.community.comment", 818 RKey: generateTID(), 819 CID: "bafymalformed", 820 Record: map[string]interface{}{ ··· 849 Kind: "commit", 850 Commit: &jetstream.CommitEvent{ 851 Operation: "create", 852 + Collection: "social.coves.community.comment", 853 RKey: generateTID(), 854 CID: "bafymalformed2", 855 Record: map[string]interface{}{ ··· 911 // |- Comment 4 912 913 comment1 := &comments.Comment{ 914 + URI: fmt.Sprintf("at://%s/social.coves.community.comment/1", testUser.DID), 915 CID: "bafyc1", 916 RKey: "1", 917 CommenterDID: testUser.DID, ··· 925 } 926 927 comment2 := &comments.Comment{ 928 + URI: fmt.Sprintf("at://%s/social.coves.community.comment/2", testUser.DID), 929 CID: "bafyc2", 930 RKey: "2", 931 CommenterDID: testUser.DID, ··· 939 } 940 941 comment3 := &comments.Comment{ 942 + URI: fmt.Sprintf("at://%s/social.coves.community.comment/3", testUser.DID), 943 CID: "bafyc3", 944 RKey: "3", 945 CommenterDID: testUser.DID, ··· 953 } 954 955 comment4 := &comments.Comment{ 956 + URI: fmt.Sprintf("at://%s/social.coves.community.comment/4", testUser.DID), 957 CID: "bafyc4", 958 RKey: "4", 959 CommenterDID: testUser.DID, ··· 1074 // When C1 finally arrives, its reply_count should be 1, not 0 1075 1076 parentRkey := generateTID() 1077 + parentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, parentRkey) 1078 1079 childRkey := generateTID() 1080 + childURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, childRkey) 1081 1082 // Step 1: Index child FIRST (before parent exists) 1083 childEvent := &jetstream.JetstreamEvent{ ··· 1086 Commit: &jetstream.CommitEvent{ 1087 Rev: "child-rev", 1088 Operation: "create", 1089 + Collection: "social.coves.community.comment", 1090 RKey: childRkey, 1091 CID: "bafychild", 1092 Record: map[string]interface{}{ 1093 + "$type": "social.coves.community.comment", 1094 "content": "This is a reply to a comment that doesn't exist yet!", 1095 "reply": map[string]interface{}{ 1096 "root": map[string]interface{}{ ··· 1128 Commit: &jetstream.CommitEvent{ 1129 Rev: "parent-rev", 1130 Operation: "create", 1131 + Collection: "social.coves.community.comment", 1132 RKey: parentRkey, 1133 CID: "bafyparent", 1134 Record: map[string]interface{}{ 1135 + "$type": "social.coves.community.comment", 1136 "content": "This is the parent comment arriving late", 1137 "reply": map[string]interface{}{ 1138 "root": map[string]interface{}{ ··· 1178 1179 t.Run("Multiple children arrive before parent", func(t *testing.T) { 1180 parentRkey := generateTID() 1181 + parentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, parentRkey) 1182 1183 // Index 3 children before parent 1184 for i := 1; i <= 3; i++ { ··· 1189 Commit: &jetstream.CommitEvent{ 1190 Rev: fmt.Sprintf("child-%d-rev", i), 1191 Operation: "create", 1192 + Collection: "social.coves.community.comment", 1193 RKey: childRkey, 1194 CID: fmt.Sprintf("bafychild%d", i), 1195 Record: map[string]interface{}{ 1196 + "$type": "social.coves.community.comment", 1197 "content": fmt.Sprintf("Reply %d before parent", i), 1198 "reply": map[string]interface{}{ 1199 "root": map[string]interface{}{ ··· 1223 Commit: &jetstream.CommitEvent{ 1224 Rev: "parent2-rev", 1225 Operation: "create", 1226 + Collection: "social.coves.community.comment", 1227 RKey: parentRkey, 1228 CID: "bafyparent2", 1229 Record: map[string]interface{}{ 1230 + "$type": "social.coves.community.comment", 1231 "content": "Parent with 3 pre-existing children", 1232 "reply": map[string]interface{}{ 1233 "root": map[string]interface{}{ ··· 1283 postURI := createTestPost(t, db, testCommunity, testUser.DID, "Resurrection Test", 0, time.Now()) 1284 1285 rkey := generateTID() 1286 + commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey) 1287 1288 t.Run("Recreate deleted comment with same rkey", func(t *testing.T) { 1289 // Step 1: Create initial comment ··· 1293 Commit: &jetstream.CommitEvent{ 1294 Rev: "v1", 1295 Operation: "create", 1296 + Collection: "social.coves.community.comment", 1297 RKey: rkey, 1298 CID: "bafyoriginal", 1299 Record: map[string]interface{}{ 1300 + "$type": "social.coves.community.comment", 1301 "content": "Original comment content", 1302 "reply": map[string]interface{}{ 1303 "root": map[string]interface{}{ ··· 1338 Commit: &jetstream.CommitEvent{ 1339 Rev: "v2", 1340 Operation: "delete", 1341 + Collection: "social.coves.community.comment", 1342 RKey: rkey, 1343 }, 1344 } ··· 1365 Commit: &jetstream.CommitEvent{ 1366 Rev: "v3", 1367 Operation: "create", 1368 + Collection: "social.coves.community.comment", 1369 RKey: rkey, // Same rkey! 1370 CID: "bafyresurrected", 1371 Record: map[string]interface{}{ 1372 + "$type": "social.coves.community.comment", 1373 "content": "Resurrected comment with new content", 1374 "reply": map[string]interface{}{ 1375 "root": map[string]interface{}{ ··· 1424 post2URI := createTestPost(t, db, testCommunity, testUser.DID, "Post 2", 0, time.Now()) 1425 1426 rkey2 := generateTID() 1427 + commentURI2 := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey2) 1428 1429 // Step 1: Create comment on Post 1 1430 createEvent := &jetstream.JetstreamEvent{ ··· 1433 Commit: &jetstream.CommitEvent{ 1434 Rev: "v1", 1435 Operation: "create", 1436 + Collection: "social.coves.community.comment", 1437 RKey: rkey2, 1438 CID: "bafyv1", 1439 Record: map[string]interface{}{ 1440 + "$type": "social.coves.community.comment", 1441 "content": "Original on Post 1", 1442 "reply": map[string]interface{}{ 1443 "root": map[string]interface{}{ ··· 1476 Commit: &jetstream.CommitEvent{ 1477 Rev: "v2", 1478 Operation: "delete", 1479 + Collection: "social.coves.community.comment", 1480 RKey: rkey2, 1481 }, 1482 } ··· 1502 Commit: &jetstream.CommitEvent{ 1503 Rev: "v3", 1504 Operation: "create", 1505 + Collection: "social.coves.community.comment", 1506 RKey: rkey2, // Same rkey! 1507 CID: "bafyv3", 1508 Record: map[string]interface{}{ 1509 + "$type": "social.coves.community.comment", 1510 "content": "New comment on Post 2", 1511 "reply": map[string]interface{}{ 1512 "root": map[string]interface{}{ ··· 1588 postURI2 := createTestPost(t, db, testCommunity, testUser.DID, "Post 2", 0, time.Now()) 1589 1590 rkey := generateTID() 1591 + commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey) 1592 1593 t.Run("Reject UPDATE that changes parent URI", func(t *testing.T) { 1594 // Create comment on Post 1 ··· 1598 Commit: &jetstream.CommitEvent{ 1599 Rev: "v1", 1600 Operation: "create", 1601 + Collection: "social.coves.community.comment", 1602 RKey: rkey, 1603 CID: "bafycomment1", 1604 Record: map[string]interface{}{ 1605 + "$type": "social.coves.community.comment", 1606 "content": "Comment on Post 1", 1607 "reply": map[string]interface{}{ 1608 "root": map[string]interface{}{ ··· 1631 Commit: &jetstream.CommitEvent{ 1632 Rev: "v2", 1633 Operation: "update", 1634 + Collection: "social.coves.community.comment", 1635 RKey: rkey, 1636 CID: "bafycomment2", 1637 Record: map[string]interface{}{ 1638 + "$type": "social.coves.community.comment", 1639 "content": "Trying to hijack this comment to Post 2", 1640 "reply": map[string]interface{}{ 1641 "root": map[string]interface{}{ ··· 1679 1680 t.Run("Allow UPDATE that only changes content (threading unchanged)", func(t *testing.T) { 1681 rkey2 := generateTID() 1682 + commentURI2 := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey2) 1683 1684 // Create comment 1685 createEvent := &jetstream.JetstreamEvent{ ··· 1688 Commit: &jetstream.CommitEvent{ 1689 Rev: "v1", 1690 Operation: "create", 1691 + Collection: "social.coves.community.comment", 1692 RKey: rkey2, 1693 CID: "bafycomment3", 1694 Record: map[string]interface{}{ 1695 + "$type": "social.coves.community.comment", 1696 "content": "Original content", 1697 "reply": map[string]interface{}{ 1698 "root": map[string]interface{}{ ··· 1721 Commit: &jetstream.CommitEvent{ 1722 Rev: "v2", 1723 Operation: "update", 1724 + Collection: "social.coves.community.comment", 1725 RKey: rkey2, 1726 CID: "bafycomment4", 1727 Record: map[string]interface{}{ 1728 + "$type": "social.coves.community.comment", 1729 "content": "Updated content", 1730 "reply": map[string]interface{}{ 1731 "root": map[string]interface{}{
+6 -6
tests/integration/comment_query_test.go
··· 538 commentURIs := make([]string, 5) 539 for i := 0; i < 5; i++ { 540 rkey := generateTID() 541 - uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, rkey) 542 commentURIs[i] = uri 543 544 event := &jetstream.JetstreamEvent{ ··· 546 Kind: "commit", 547 Commit: &jetstream.CommitEvent{ 548 Operation: "create", 549 - Collection: "social.coves.feed.comment", 550 RKey: rkey, 551 CID: fmt.Sprintf("bafyc%d", i), 552 Record: map[string]interface{}{ 553 - "$type": "social.coves.feed.comment", 554 "content": fmt.Sprintf("Comment %d", i), 555 "reply": map[string]interface{}{ 556 "root": map[string]interface{}{ ··· 576 Kind: "commit", 577 Commit: &jetstream.CommitEvent{ 578 Operation: "delete", 579 - Collection: "social.coves.feed.comment", 580 RKey: strings.Split(commentURIs[1], "/")[4], 581 }, 582 } ··· 587 Kind: "commit", 588 Commit: &jetstream.CommitEvent{ 589 Operation: "delete", 590 - Collection: "social.coves.feed.comment", 591 RKey: strings.Split(commentURIs[3], "/")[4], 592 }, 593 } ··· 794 795 ctx := context.Background() 796 rkey := generateTID() 797 - uri := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", commenterDID, rkey) 798 799 // Insert comment directly for speed 800 _, err := db.ExecContext(ctx, `
··· 538 commentURIs := make([]string, 5) 539 for i := 0; i < 5; i++ { 540 rkey := generateTID() 541 + uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, rkey) 542 commentURIs[i] = uri 543 544 event := &jetstream.JetstreamEvent{ ··· 546 Kind: "commit", 547 Commit: &jetstream.CommitEvent{ 548 Operation: "create", 549 + Collection: "social.coves.community.comment", 550 RKey: rkey, 551 CID: fmt.Sprintf("bafyc%d", i), 552 Record: map[string]interface{}{ 553 + "$type": "social.coves.community.comment", 554 "content": fmt.Sprintf("Comment %d", i), 555 "reply": map[string]interface{}{ 556 "root": map[string]interface{}{ ··· 576 Kind: "commit", 577 Commit: &jetstream.CommitEvent{ 578 Operation: "delete", 579 + Collection: "social.coves.community.comment", 580 RKey: strings.Split(commentURIs[1], "/")[4], 581 }, 582 } ··· 587 Kind: "commit", 588 Commit: &jetstream.CommitEvent{ 589 Operation: "delete", 590 + Collection: "social.coves.community.comment", 591 RKey: strings.Split(commentURIs[3], "/")[4], 592 }, 593 } ··· 794 795 ctx := context.Background() 796 rkey := generateTID() 797 + uri := fmt.Sprintf("at://%s/social.coves.community.comment/%s", commenterDID, rkey) 798 799 // Insert comment directly for speed 800 _, err := db.ExecContext(ctx, `
+15 -15
tests/integration/comment_vote_test.go
··· 43 t.Run("Upvote on comment increments count", func(t *testing.T) { 44 // Create a comment 45 commentRKey := generateTID() 46 - commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey) 47 commentCID := "bafycomment123" 48 49 commentEvent := &jetstream.JetstreamEvent{ ··· 52 Commit: &jetstream.CommitEvent{ 53 Rev: "test-rev", 54 Operation: "create", 55 - Collection: "social.coves.feed.comment", 56 RKey: commentRKey, 57 CID: commentCID, 58 Record: map[string]interface{}{ 59 - "$type": "social.coves.feed.comment", 60 "content": "Comment to vote on", 61 "reply": map[string]interface{}{ 62 "root": map[string]interface{}{ ··· 143 t.Run("Downvote on comment increments downvote count", func(t *testing.T) { 144 // Create a comment 145 commentRKey := generateTID() 146 - commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey) 147 commentCID := "bafycomment456" 148 149 commentEvent := &jetstream.JetstreamEvent{ ··· 152 Commit: &jetstream.CommitEvent{ 153 Rev: "test-rev", 154 Operation: "create", 155 - Collection: "social.coves.feed.comment", 156 RKey: commentRKey, 157 CID: commentCID, 158 Record: map[string]interface{}{ 159 - "$type": "social.coves.feed.comment", 160 "content": "Comment to downvote", 161 "reply": map[string]interface{}{ 162 "root": map[string]interface{}{ ··· 221 t.Run("Delete vote decrements comment counts", func(t *testing.T) { 222 // Create comment 223 commentRKey := generateTID() 224 - commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey) 225 commentCID := "bafycomment789" 226 227 commentEvent := &jetstream.JetstreamEvent{ ··· 230 Commit: &jetstream.CommitEvent{ 231 Rev: "test-rev", 232 Operation: "create", 233 - Collection: "social.coves.feed.comment", 234 RKey: commentRKey, 235 CID: commentCID, 236 Record: map[string]interface{}{ 237 - "$type": "social.coves.feed.comment", 238 "content": "Comment for vote deletion test", 239 "reply": map[string]interface{}{ 240 "root": map[string]interface{}{ ··· 353 t.Run("Viewer with vote sees vote state", func(t *testing.T) { 354 // Create comment 355 commentRKey := generateTID() 356 - commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey) 357 commentCID := "bafycomment111" 358 359 commentEvent := &jetstream.JetstreamEvent{ ··· 362 Commit: &jetstream.CommitEvent{ 363 Rev: "test-rev", 364 Operation: "create", 365 - Collection: "social.coves.feed.comment", 366 RKey: commentRKey, 367 CID: commentCID, 368 Record: map[string]interface{}{ 369 - "$type": "social.coves.feed.comment", 370 "content": "Comment with viewer vote", 371 "reply": map[string]interface{}{ 372 "root": map[string]interface{}{ ··· 465 t.Run("Viewer without vote sees empty state", func(t *testing.T) { 466 // Create comment (no vote) 467 commentRKey := generateTID() 468 - commentURI := fmt.Sprintf("at://%s/social.coves.feed.comment/%s", testUser.DID, commentRKey) 469 470 commentEvent := &jetstream.JetstreamEvent{ 471 Did: testUser.DID, ··· 473 Commit: &jetstream.CommitEvent{ 474 Rev: "test-rev", 475 Operation: "create", 476 - Collection: "social.coves.feed.comment", 477 RKey: commentRKey, 478 CID: "bafycomment222", 479 Record: map[string]interface{}{ 480 - "$type": "social.coves.feed.comment", 481 "content": "Comment without viewer vote", 482 "reply": map[string]interface{}{ 483 "root": map[string]interface{}{
··· 43 t.Run("Upvote on comment increments count", func(t *testing.T) { 44 // Create a comment 45 commentRKey := generateTID() 46 + commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey) 47 commentCID := "bafycomment123" 48 49 commentEvent := &jetstream.JetstreamEvent{ ··· 52 Commit: &jetstream.CommitEvent{ 53 Rev: "test-rev", 54 Operation: "create", 55 + Collection: "social.coves.community.comment", 56 RKey: commentRKey, 57 CID: commentCID, 58 Record: map[string]interface{}{ 59 + "$type": "social.coves.community.comment", 60 "content": "Comment to vote on", 61 "reply": map[string]interface{}{ 62 "root": map[string]interface{}{ ··· 143 t.Run("Downvote on comment increments downvote count", func(t *testing.T) { 144 // Create a comment 145 commentRKey := generateTID() 146 + commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey) 147 commentCID := "bafycomment456" 148 149 commentEvent := &jetstream.JetstreamEvent{ ··· 152 Commit: &jetstream.CommitEvent{ 153 Rev: "test-rev", 154 Operation: "create", 155 + Collection: "social.coves.community.comment", 156 RKey: commentRKey, 157 CID: commentCID, 158 Record: map[string]interface{}{ 159 + "$type": "social.coves.community.comment", 160 "content": "Comment to downvote", 161 "reply": map[string]interface{}{ 162 "root": map[string]interface{}{ ··· 221 t.Run("Delete vote decrements comment counts", func(t *testing.T) { 222 // Create comment 223 commentRKey := generateTID() 224 + commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey) 225 commentCID := "bafycomment789" 226 227 commentEvent := &jetstream.JetstreamEvent{ ··· 230 Commit: &jetstream.CommitEvent{ 231 Rev: "test-rev", 232 Operation: "create", 233 + Collection: "social.coves.community.comment", 234 RKey: commentRKey, 235 CID: commentCID, 236 Record: map[string]interface{}{ 237 + "$type": "social.coves.community.comment", 238 "content": "Comment for vote deletion test", 239 "reply": map[string]interface{}{ 240 "root": map[string]interface{}{ ··· 353 t.Run("Viewer with vote sees vote state", func(t *testing.T) { 354 // Create comment 355 commentRKey := generateTID() 356 + commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey) 357 commentCID := "bafycomment111" 358 359 commentEvent := &jetstream.JetstreamEvent{ ··· 362 Commit: &jetstream.CommitEvent{ 363 Rev: "test-rev", 364 Operation: "create", 365 + Collection: "social.coves.community.comment", 366 RKey: commentRKey, 367 CID: commentCID, 368 Record: map[string]interface{}{ 369 + "$type": "social.coves.community.comment", 370 "content": "Comment with viewer vote", 371 "reply": map[string]interface{}{ 372 "root": map[string]interface{}{ ··· 465 t.Run("Viewer without vote sees empty state", func(t *testing.T) { 466 // Create comment (no vote) 467 commentRKey := generateTID() 468 + commentURI := fmt.Sprintf("at://%s/social.coves.community.comment/%s", testUser.DID, commentRKey) 469 470 commentEvent := &jetstream.JetstreamEvent{ 471 Did: testUser.DID, ··· 473 Commit: &jetstream.CommitEvent{ 474 Rev: "test-rev", 475 Operation: "create", 476 + Collection: "social.coves.community.comment", 477 RKey: commentRKey, 478 CID: "bafycomment222", 479 Record: map[string]interface{}{ 480 + "$type": "social.coves.community.comment", 481 "content": "Comment without viewer vote", 482 "reply": map[string]interface{}{ 483 "root": map[string]interface{}{