diff --git a/internal/db/postgres/vote_repo_test.go b/internal/db/postgres/vote_repo_test.go index 67dd2f3..5367219 100644 --- a/internal/db/postgres/vote_repo_test.go +++ b/internal/db/postgres/vote_repo_test.go @@ -67,7 +67,7 @@ func TestVoteRepo_Create(t *testing.T) { CID: "bafyreigtest123", RKey: "3k1234567890", VoterDID: voterDID, - SubjectURI: "at://did:plc:community/social.coves.post.record/abc123", + SubjectURI: "at://did:plc:community/social.coves.community.post/abc123", SubjectCID: "bafyreigpost123", Direction: "up", CreatedAt: time.Now(), @@ -95,7 +95,7 @@ func TestVoteRepo_Create_Idempotent(t *testing.T) { CID: "bafyreigtest456", RKey: "3k9876543210", VoterDID: voterDID, - SubjectURI: "at://did:plc:community/social.coves.post.record/xyz789", + SubjectURI: "at://did:plc:community/social.coves.community.post/xyz789", SubjectCID: "bafyreigpost456", Direction: "down", CreatedAt: time.Now(), @@ -136,7 +136,7 @@ func TestVoteRepo_Create_VoterNotFound(t *testing.T) { CID: "bafyreignovoter", RKey: "3k1111111111", VoterDID: "did:plc:nonexistentvoter", - SubjectURI: "at://did:plc:community/social.coves.post.record/test123", + SubjectURI: "at://did:plc:community/social.coves.community.post/test123", SubjectCID: "bafyreigpost789", Direction: "up", CreatedAt: time.Now(), @@ -168,7 +168,7 @@ func TestVoteRepo_GetByURI(t *testing.T) { CID: "bafyreigtest789", RKey: "3k5555555555", VoterDID: voterDID, - SubjectURI: "at://did:plc:community/social.coves.post.record/post123", + SubjectURI: "at://did:plc:community/social.coves.community.post/post123", SubjectCID: "bafyreigpost999", Direction: "up", CreatedAt: time.Now(), @@ -207,7 +207,7 @@ func TestVoteRepo_GetByVoterAndSubject(t *testing.T) { voterDID := "did:plc:testvoter999" createTestUser(t, db, "testvoter999.test", voterDID) - subjectURI := "at://did:plc:community/social.coves.post.record/subject123" + subjectURI := "at://did:plc:community/social.coves.community.post/subject123" // Create vote vote := &votes.Vote{ @@ -238,7 +238,7 @@ func TestVoteRepo_GetByVoterAndSubject_NotFound(t *testing.T) { repo := NewVoteRepository(db) ctx := context.Background() - _, err := repo.GetByVoterAndSubject(ctx, "did:plc:nobody", "at://did:plc:community/social.coves.post.record/nopost") + _, err := repo.GetByVoterAndSubject(ctx, "did:plc:nobody", "at://did:plc:community/social.coves.community.post/nopost") assert.ErrorIs(t, err, votes.ErrVoteNotFound) } @@ -259,7 +259,7 @@ func TestVoteRepo_Delete(t *testing.T) { CID: "bafyreigdelete", RKey: "3k7777777777", VoterDID: voterDID, - SubjectURI: "at://did:plc:community/social.coves.post.record/deletetest", + SubjectURI: "at://did:plc:community/social.coves.community.post/deletetest", SubjectCID: "bafyreigdeletepost", Direction: "up", CreatedAt: time.Now(), @@ -297,7 +297,7 @@ func TestVoteRepo_Delete_Idempotent(t *testing.T) { CID: "bafyreigdelete2", RKey: "3k8888888888", VoterDID: voterDID, - SubjectURI: "at://did:plc:community/social.coves.post.record/deletetest2", + SubjectURI: "at://did:plc:community/social.coves.community.post/deletetest2", SubjectCID: "bafyreigdeletepost2", Direction: "down", CreatedAt: time.Now(), @@ -327,7 +327,7 @@ func TestVoteRepo_ListBySubject(t *testing.T) { createTestUser(t, db, "testvoterlist1.test", voterDID1) createTestUser(t, db, "testvoterlist2.test", voterDID2) - subjectURI := "at://did:plc:community/social.coves.post.record/listtest" + subjectURI := "at://did:plc:community/social.coves.community.post/listtest" // Create multiple votes on same subject vote1 := &votes.Vote{ @@ -377,7 +377,7 @@ func TestVoteRepo_ListByVoter(t *testing.T) { CID: "bafyreigvoter1", RKey: "3k0000000001", VoterDID: voterDID, - SubjectURI: "at://did:plc:community/social.coves.post.record/post1", + SubjectURI: "at://did:plc:community/social.coves.community.post/post1", SubjectCID: "bafyreigp1", Direction: "up", CreatedAt: time.Now(), @@ -387,7 +387,7 @@ func TestVoteRepo_ListByVoter(t *testing.T) { CID: "bafyreigvoter2", RKey: "3k0000000002", VoterDID: voterDID, - SubjectURI: "at://did:plc:community/social.coves.post.record/post2", + SubjectURI: "at://did:plc:community/social.coves.community.post/post2", SubjectCID: "bafyreigp2", Direction: "down", CreatedAt: time.Now(), diff --git a/tests/integration/aggregator_e2e_test.go b/tests/integration/aggregator_e2e_test.go index 6a750e6..4387917 100644 --- a/tests/integration/aggregator_e2e_test.go +++ b/tests/integration/aggregator_e2e_test.go @@ -332,7 +332,7 @@ func TestAggregator_E2E_WithJetstream(t *testing.T) { reqJSON, err := json.Marshal(reqBody) require.NoError(t, err) - req := httptest.NewRequest("POST", "/xrpc/social.coves.post.create", bytes.NewReader(reqJSON)) + req := httptest.NewRequest("POST", "/xrpc/social.coves.community.post.create", bytes.NewReader(reqJSON)) req.Header.Set("Content-Type", "application/json") // Create JWT for aggregator (not a user) @@ -360,11 +360,11 @@ func TestAggregator_E2E_WithJetstream(t *testing.T) { Kind: "commit", Commit: &jetstream.CommitEvent{ Operation: "create", - Collection: "social.coves.post.record", + Collection: "social.coves.community.post", RKey: rkey, CID: response.CID, Record: map[string]interface{}{ - "$type": "social.coves.post.record", + "$type": "social.coves.community.post", "community": communityDID, "author": aggregatorDID, // Aggregator is the author "title": title, @@ -422,7 +422,7 @@ func TestAggregator_E2E_WithJetstream(t *testing.T) { reqJSON, err := json.Marshal(reqBody) require.NoError(t, err) - req := httptest.NewRequest("POST", "/xrpc/social.coves.post.create", bytes.NewReader(reqJSON)) + req := httptest.NewRequest("POST", "/xrpc/social.coves.community.post.create", bytes.NewReader(reqJSON)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+createSimpleTestJWT(aggregatorDID)) @@ -444,7 +444,7 @@ func TestAggregator_E2E_WithJetstream(t *testing.T) { reqJSON, err := json.Marshal(reqBody) require.NoError(t, err) - req := httptest.NewRequest("POST", "/xrpc/social.coves.post.create", bytes.NewReader(reqJSON)) + req := httptest.NewRequest("POST", "/xrpc/social.coves.community.post.create", bytes.NewReader(reqJSON)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+createSimpleTestJWT(aggregatorDID)) @@ -465,7 +465,7 @@ func TestAggregator_E2E_WithJetstream(t *testing.T) { reqJSON, err = json.Marshal(reqBody) require.NoError(t, err) - req = httptest.NewRequest("POST", "/xrpc/social.coves.post.create", bytes.NewReader(reqJSON)) + req = httptest.NewRequest("POST", "/xrpc/social.coves.community.post.create", bytes.NewReader(reqJSON)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+createSimpleTestJWT(aggregatorDID)) @@ -657,7 +657,7 @@ func TestAggregator_E2E_WithJetstream(t *testing.T) { reqJSON, err := json.Marshal(reqBody) require.NoError(t, err) - req := httptest.NewRequest("POST", "/xrpc/social.coves.post.create", bytes.NewReader(reqJSON)) + req := httptest.NewRequest("POST", "/xrpc/social.coves.community.post.create", bytes.NewReader(reqJSON)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+createSimpleTestJWT(unauthorizedAggDID)) @@ -781,7 +781,7 @@ func TestAggregator_E2E_WithJetstream(t *testing.T) { reqJSON, err := json.Marshal(reqBody) require.NoError(t, err) - req := httptest.NewRequest("POST", "/xrpc/social.coves.post.create", bytes.NewReader(reqJSON)) + req := httptest.NewRequest("POST", "/xrpc/social.coves.community.post.create", bytes.NewReader(reqJSON)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+createSimpleTestJWT(aggregatorDID)) diff --git a/tests/integration/aggregator_test.go b/tests/integration/aggregator_test.go index 8523f7d..ea0af30 100644 --- a/tests/integration/aggregator_test.go +++ b/tests/integration/aggregator_test.go @@ -544,7 +544,7 @@ func TestAggregatorService_PostCreationIntegration(t *testing.T) { }) t.Run("records aggregator post for rate limiting", func(t *testing.T) { - postURI := fmt.Sprintf("at://%s/social.coves.post.record/post1", communityDID) + postURI := fmt.Sprintf("at://%s/social.coves.community.post/post1", communityDID) err := aggRepo.RecordAggregatorPost(ctx, aggregatorDID, communityDID, postURI, "bafy123") if err != nil { @@ -627,7 +627,7 @@ func TestAggregatorService_RateLimiting(t *testing.T) { t.Run("allows posts within rate limit", func(t *testing.T) { // Create 9 posts (under the 10/hour limit) for i := 0; i < 9; i++ { - postURI := fmt.Sprintf("at://%s/social.coves.post.record/post%d", communityDID, i) + postURI := fmt.Sprintf("at://%s/social.coves.community.post/post%d", communityDID, i) if err := aggRepo.RecordAggregatorPost(ctx, aggregatorDID, communityDID, postURI, "bafy123"); err != nil { t.Fatalf("Failed to record post %d: %v", i, err) } @@ -642,7 +642,7 @@ func TestAggregatorService_RateLimiting(t *testing.T) { t.Run("enforces rate limit at 10 posts/hour", func(t *testing.T) { // Add one more post to hit the limit (total = 10) - postURI := fmt.Sprintf("at://%s/social.coves.post.record/post10", communityDID) + postURI := fmt.Sprintf("at://%s/social.coves.community.post/post10", communityDID) if err := aggRepo.RecordAggregatorPost(ctx, aggregatorDID, communityDID, postURI, "bafy123"); err != nil { t.Fatalf("Failed to record 10th post: %v", err) } @@ -801,7 +801,7 @@ func TestAggregatorTriggers(t *testing.T) { // Record 5 posts for i := 0; i < 5; i++ { - postURI := fmt.Sprintf("at://%s/social.coves.post.record/triggerpost%d", communityDID, i) + postURI := fmt.Sprintf("at://%s/social.coves.community.post/triggerpost%d", communityDID, i) if err := aggRepo.RecordAggregatorPost(ctx, aggregatorDID, communityDID, postURI, "bafy123"); err != nil { t.Fatalf("Failed to record post %d: %v", i, err) } diff --git a/tests/integration/feed_test.go b/tests/integration/feed_test.go index f15fc6b..a4051de 100644 --- a/tests/integration/feed_test.go +++ b/tests/integration/feed_test.go @@ -81,7 +81,7 @@ func TestGetCommunityFeed_Hot(t *testing.T) { assert.NotNil(t, feedPost.Post.Record, "Post %d should have Record field", i) record, ok := feedPost.Post.Record.(map[string]interface{}) require.True(t, ok, "Record should be a map") - assert.Equal(t, "social.coves.post.record", record["$type"], "Record should have correct $type") + assert.Equal(t, "social.coves.community.post", record["$type"], "Record should have correct $type") assert.NotEmpty(t, record["community"], "Record should have community") assert.NotEmpty(t, record["author"], "Record should have author") assert.NotEmpty(t, record["createdAt"], "Record should have createdAt") diff --git a/tests/integration/helpers.go b/tests/integration/helpers.go index f37923c..717b41c 100644 --- a/tests/integration/helpers.go +++ b/tests/integration/helpers.go @@ -274,7 +274,7 @@ func createTestPost(t *testing.T, db *sql.DB, communityDID, authorDID, title str // Generate URI rkey := fmt.Sprintf("post-%d", time.Now().UnixNano()) - uri := fmt.Sprintf("at://%s/social.coves.post.record/%s", communityDID, rkey) + uri := fmt.Sprintf("at://%s/social.coves.community.post/%s", communityDID, rkey) // Insert post _, err := db.ExecContext(ctx, ` diff --git a/tests/integration/post_creation_test.go b/tests/integration/post_creation_test.go index 1688d9b..c8db667 100644 --- a/tests/integration/post_creation_test.go +++ b/tests/integration/post_creation_test.go @@ -1,6 +1,7 @@ package integration import ( + "Coves/internal/api/middleware" "Coves/internal/atproto/identity" "Coves/internal/core/communities" "Coves/internal/core/posts" @@ -97,7 +98,8 @@ func TestPostCreation_Basic(t *testing.T) { // This will fail at token refresh step (expected for unit test) // We're using a fake token that can't be parsed - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) // For now, we expect an error because token is fake // In a full E2E test with real PDS, this would succeed @@ -123,7 +125,8 @@ func TestPostCreation_Basic(t *testing.T) { // Should resolve handle to DID and proceed // Will still fail at token refresh (expected with fake token) - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) // Should fail at token refresh, not community resolution assert.Contains(t, err.Error(), "failed to refresh community credentials") @@ -152,7 +155,8 @@ func TestPostCreation_Basic(t *testing.T) { // Should resolve handle to DID and proceed // Will still fail at token refresh (expected with fake token) - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) // Should fail at token refresh, not community resolution assert.Contains(t, err.Error(), "failed to refresh community credentials") @@ -167,7 +171,8 @@ func TestPostCreation_Basic(t *testing.T) { AuthorDID: testUserDID, } - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) assert.True(t, posts.IsValidationError(err)) }) @@ -181,7 +186,8 @@ func TestPostCreation_Basic(t *testing.T) { AuthorDID: testUserDID, } - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) // Should fail with community not found (wrapped in error) assert.Contains(t, err.Error(), "community not found") @@ -196,7 +202,8 @@ func TestPostCreation_Basic(t *testing.T) { AuthorDID: "", // Missing! } - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) assert.True(t, posts.IsValidationError(err)) assert.Contains(t, err.Error(), "authorDid") @@ -211,7 +218,8 @@ func TestPostCreation_Basic(t *testing.T) { AuthorDID: testUserDID, } - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) assert.Equal(t, posts.ErrCommunityNotFound, err) }) @@ -226,7 +234,8 @@ func TestPostCreation_Basic(t *testing.T) { AuthorDID: testUserDID, } - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) assert.True(t, posts.IsValidationError(err)) assert.Contains(t, err.Error(), "too long") @@ -236,13 +245,18 @@ func TestPostCreation_Basic(t *testing.T) { content := "Post with invalid label" req := posts.CreatePostRequest{ - Community: testCommunity.DID, - Content: &content, - ContentLabels: []string{"invalid_label"}, // Not in known values! - AuthorDID: testUserDID, + Community: testCommunity.DID, + Content: &content, + Labels: &posts.SelfLabels{ + Values: []posts.SelfLabel{ + {Val: "invalid_label"}, // Not in known values! + }, + }, + AuthorDID: testUserDID, } - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) assert.True(t, posts.IsValidationError(err)) assert.Contains(t, err.Error(), "unknown content label") @@ -252,14 +266,20 @@ func TestPostCreation_Basic(t *testing.T) { content := "Post with valid labels" req := posts.CreatePostRequest{ - Community: testCommunity.DID, - Content: &content, - ContentLabels: []string{"nsfw", "spoiler"}, - AuthorDID: testUserDID, + Community: testCommunity.DID, + Content: &content, + Labels: &posts.SelfLabels{ + Values: []posts.SelfLabel{ + {Val: "nsfw"}, + {Val: "spoiler"}, + }, + }, + AuthorDID: testUserDID, } // Will fail at token refresh (expected with fake token) - _, err := postService.CreatePost(ctx, req) + authCtx := middleware.SetTestUserDID(ctx, testUserDID) + _, err := postService.CreatePost(authCtx, req) require.Error(t, err) // Should fail at token refresh, not validation assert.Contains(t, err.Error(), "failed to refresh community credentials") @@ -316,7 +336,7 @@ func TestPostRepository_Create(t *testing.T) { title := "Test Title" post := &posts.Post{ - URI: "at://" + testCommunityDID + "/social.coves.post.record/test123", + URI: "at://" + testCommunityDID + "/social.coves.community.post/test123", CID: "bafy2test123", RKey: "test123", AuthorDID: testUserDID, @@ -335,7 +355,7 @@ func TestPostRepository_Create(t *testing.T) { content := "Duplicate post" post1 := &posts.Post{ - URI: "at://" + testCommunityDID + "/social.coves.post.record/duplicate", + URI: "at://" + testCommunityDID + "/social.coves.community.post/duplicate", CID: "bafy2duplicate1", RKey: "duplicate", AuthorDID: testUserDID, @@ -348,7 +368,7 @@ func TestPostRepository_Create(t *testing.T) { // Try to insert again with same URI post2 := &posts.Post{ - URI: "at://" + testCommunityDID + "/social.coves.post.record/duplicate", + URI: "at://" + testCommunityDID + "/social.coves.community.post/duplicate", CID: "bafy2duplicate2", RKey: "duplicate", AuthorDID: testUserDID, diff --git a/tests/integration/post_e2e_test.go b/tests/integration/post_e2e_test.go index 463c6d9..f308120 100644 --- a/tests/integration/post_e2e_test.go +++ b/tests/integration/post_e2e_test.go @@ -33,7 +33,7 @@ import ( // XRPC endpoint → AppView Service → PDS write → Jetstream consumer → DB indexing // // This is a TRUE E2E test that simulates what happens in production: -// 1. Client calls POST /xrpc/social.coves.post.create with auth token +// 1. Client calls POST /xrpc/social.coves.community.post.create with auth token // 2. Handler validates and calls PostService.CreatePost() // 3. Service writes post to community's PDS repository // 4. PDS broadcasts event to firehose/Jetstream @@ -116,11 +116,11 @@ func TestPostCreation_E2E_WithJetstream(t *testing.T) { Kind: "commit", Commit: &jetstream.CommitEvent{ Operation: "create", - Collection: "social.coves.post.record", + Collection: "social.coves.community.post", RKey: rkey, CID: "bafy2bzaceabc123def456", // Fake CID Record: map[string]interface{}{ - "$type": "social.coves.post.record", + "$type": "social.coves.community.post", "community": community.DID, "author": author.DID, "title": *postReq.Title, @@ -138,7 +138,7 @@ func TestPostCreation_E2E_WithJetstream(t *testing.T) { } // STEP 4: Verify post was indexed in AppView database - expectedURI := fmt.Sprintf("at://%s/social.coves.post.record/%s", community.DID, rkey) + expectedURI := fmt.Sprintf("at://%s/social.coves.community.post/%s", community.DID, rkey) indexedPost, err := postRepo.GetByURI(ctx, expectedURI) if err != nil { t.Fatalf("Post not indexed in AppView: %v", err) @@ -187,11 +187,11 @@ func TestPostCreation_E2E_WithJetstream(t *testing.T) { Kind: "commit", Commit: &jetstream.CommitEvent{ Operation: "create", - Collection: "social.coves.post.record", + Collection: "social.coves.community.post", RKey: generateTID(), CID: "bafy2bzacefake", Record: map[string]interface{}{ - "$type": "social.coves.post.record", + "$type": "social.coves.community.post", "community": community.DID, // Claims to be for this community "author": author.DID, "title": "Fake Post", @@ -227,11 +227,11 @@ func TestPostCreation_E2E_WithJetstream(t *testing.T) { Kind: "commit", Commit: &jetstream.CommitEvent{ Operation: "create", - Collection: "social.coves.post.record", + Collection: "social.coves.community.post", RKey: rkey, CID: "bafy2bzaceidempotent", Record: map[string]interface{}{ - "$type": "social.coves.post.record", + "$type": "social.coves.community.post", "community": community.DID, "author": author.DID, "title": "Duplicate Test", @@ -256,7 +256,7 @@ func TestPostCreation_E2E_WithJetstream(t *testing.T) { } // Verify only one post in database - uri := fmt.Sprintf("at://%s/social.coves.post.record/%s", community.DID, rkey) + uri := fmt.Sprintf("at://%s/social.coves.community.post/%s", community.DID, rkey) post, err := postRepo.GetByURI(ctx, uri) if err != nil { t.Fatalf("Post not found: %v", err) @@ -281,11 +281,11 @@ func TestPostCreation_E2E_WithJetstream(t *testing.T) { Kind: "commit", Commit: &jetstream.CommitEvent{ Operation: "create", - Collection: "social.coves.post.record", + Collection: "social.coves.community.post", RKey: generateTID(), CID: "bafy2bzaceorphaned", Record: map[string]interface{}{ - "$type": "social.coves.post.record", + "$type": "social.coves.community.post", "community": unknownCommunityDID, "author": author.DID, "title": "Orphaned Post", @@ -313,7 +313,7 @@ func TestPostCreation_E2E_WithJetstream(t *testing.T) { } // TestPostCreation_E2E_LivePDS tests the COMPLETE end-to-end flow with a live PDS: -// 1. HTTP POST to /xrpc/social.coves.post.create (with auth) +// 1. HTTP POST to /xrpc/social.coves.community.post.create (with auth) // 2. Handler → Service → Write to community's PDS repository // 3. PDS → Jetstream firehose event // 4. Jetstream consumer → Index in AppView database @@ -472,7 +472,7 @@ func TestPostCreation_E2E_LivePDS(t *testing.T) { require.NoError(t, err) // Create HTTP request - req := httptest.NewRequest("POST", "/xrpc/social.coves.post.create", bytes.NewReader(reqJSON)) + req := httptest.NewRequest("POST", "/xrpc/social.coves.community.post.create", bytes.NewReader(reqJSON)) req.Header.Set("Content-Type", "application/json") // Create a simple JWT for testing (Phase 1: no signature verification) @@ -511,7 +511,7 @@ func TestPostCreation_E2E_LivePDS(t *testing.T) { pdsHostname = strings.Split(pdsHostname, ":")[0] // Remove port // Build Jetstream URL with filters for post records - jetstreamURL := fmt.Sprintf("ws://%s:6008/subscribe?wantedCollections=social.coves.post.record", + jetstreamURL := fmt.Sprintf("ws://%s:6008/subscribe?wantedCollections=social.coves.community.post", pdsHostname) t.Logf(" Jetstream URL: %s", jetstreamURL) @@ -653,7 +653,7 @@ func subscribeToJetstreamForPost( // Check if this is a post event for the target DID if event.Did == targetDID && event.Kind == "commit" && - event.Commit != nil && event.Commit.Collection == "social.coves.post.record" { + event.Commit != nil && event.Commit.Collection == "social.coves.community.post" { // Process the event through the consumer if err := consumer.HandleEvent(ctx, &event); err != nil { return fmt.Errorf("failed to process event: %w", err) diff --git a/tests/integration/post_handler_test.go b/tests/integration/post_handler_test.go index 4a80568..71819f6 100644 --- a/tests/integration/post_handler_test.go +++ b/tests/integration/post_handler_test.go @@ -55,7 +55,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -82,7 +82,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // No auth context set rec := httptest.NewRecorder() @@ -108,7 +108,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -131,7 +131,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { // Invalid JSON invalidJSON := []byte(`{"community": "did:plc:test123", "content": `) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(invalidJSON)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(invalidJSON)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -157,7 +157,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -192,7 +192,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -231,7 +231,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -269,7 +269,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -307,7 +307,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -345,7 +345,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) // Mock authenticated user context ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") @@ -373,7 +373,7 @@ func TestPostHandler_SecurityValidation(t *testing.T) { for _, method := range methods { t.Run(method, func(t *testing.T) { - req := httptest.NewRequest(method, "/xrpc/social.coves.post.create", nil) + req := httptest.NewRequest(method, "/xrpc/social.coves.community.post.create", nil) rec := httptest.NewRecorder() handler.HandleCreate(rec, req) @@ -422,7 +422,7 @@ func TestPostHandler_SpecialCharacters(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") req = req.WithContext(ctx) @@ -452,7 +452,7 @@ func TestPostHandler_SpecialCharacters(t *testing.T) { } body, _ := json.Marshal(payload) - req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.post.create", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/xrpc/social.coves.community.post.create", bytes.NewReader(body)) ctx := middleware.SetTestUserDID(req.Context(), "did:plc:alice") req = req.WithContext(ctx) diff --git a/tests/integration/timeline_test.go b/tests/integration/timeline_test.go index ad3eaf0..a24982c 100644 --- a/tests/integration/timeline_test.go +++ b/tests/integration/timeline_test.go @@ -100,7 +100,7 @@ func TestGetTimeline_Basic(t *testing.T) { assert.NotNil(t, feedPost.Post.Record, "Post %d should have Record field", i) record, ok := feedPost.Post.Record.(map[string]interface{}) require.True(t, ok, "Record should be a map") - assert.Equal(t, "social.coves.post.record", record["$type"], "Record should have correct $type") + assert.Equal(t, "social.coves.community.post", record["$type"], "Record should have correct $type") assert.NotEmpty(t, record["community"], "Record should have community") assert.NotEmpty(t, record["author"], "Record should have author") assert.NotEmpty(t, record["createdAt"], "Record should have createdAt") diff --git a/tests/lexicon-test-data/actor/saved-invalid-type.json b/tests/lexicon-test-data/actor/saved-invalid-type.json index fc0cca3..ec5b436 100644 --- a/tests/lexicon-test-data/actor/saved-invalid-type.json +++ b/tests/lexicon-test-data/actor/saved-invalid-type.json @@ -1,6 +1,6 @@ { "$type": "social.coves.actor.saved", - "subject": "at://did:plc:exampleuser/social.coves.post.record/3k7a3dmb5bk2c", + "subject": "at://$1/social.coves.community.post/3k7a3dmb5bk2c", "type": "article", "createdAt": "2025-01-09T14:30:00Z" } \ No newline at end of file diff --git a/tests/lexicon-test-data/actor/saved-valid.json b/tests/lexicon-test-data/actor/saved-valid.json index f41fabe..92ea22a 100644 --- a/tests/lexicon-test-data/actor/saved-valid.json +++ b/tests/lexicon-test-data/actor/saved-valid.json @@ -1,6 +1,6 @@ { "$type": "social.coves.actor.saved", - "subject": "at://did:plc:exampleuser/social.coves.post.record/3k7a3dmb5bk2c", + "subject": "at://$1/social.coves.community.post/3k7a3dmb5bk2c", "type": "post", "createdAt": "2025-01-09T14:30:00Z", "note": "Great tutorial on Go concurrency patterns" diff --git a/tests/lexicon-test-data/interaction/comment-invalid-content.json b/tests/lexicon-test-data/interaction/comment-invalid-content.json index 8619cbe..6a3f152 100644 --- a/tests/lexicon-test-data/interaction/comment-invalid-content.json +++ b/tests/lexicon-test-data/interaction/comment-invalid-content.json @@ -1,5 +1,14 @@ { - "$type": "social.coves.interaction.comment", - "post": "at://did:plc:author123/social.coves.post.record/3k7a3dmb5bk2c", + "$type": "social.coves.feed.comment", + "reply": { + "root": { + "uri": "at://did:plc:test123/social.coves.community.post/3k7a3dmb5bk2c", + "cid": "bafyreigj3fwnwjuzr35k2kuzmb5dixxczrzjhqkr5srlqplsh6gq3bj3si" + }, + "parent": { + "uri": "at://did:plc:test123/social.coves.community.post/3k7a3dmb5bk2c", + "cid": "bafyreigj3fwnwjuzr35k2kuzmb5dixxczrzjhqkr5srlqplsh6gq3bj3si" + } + }, "createdAt": "2025-01-09T16:45:00Z" -} \ No newline at end of file +} diff --git a/tests/lexicon-test-data/interaction/comment-valid-sticker.json b/tests/lexicon-test-data/interaction/comment-valid-sticker.json index 1e1e24c..3108bf1 100644 --- a/tests/lexicon-test-data/interaction/comment-valid-sticker.json +++ b/tests/lexicon-test-data/interaction/comment-valid-sticker.json @@ -1,10 +1,15 @@ { - "$type": "social.coves.interaction.comment", - "subject": "at://did:plc:author123/social.coves.post.record/3k7a3dmb5bk2c", - "content": { - "$type": "social.coves.interaction.comment#stickerContent", - "stickerId": "thumbs-up", - "stickerPackId": "default-pack" + "$type": "social.coves.feed.comment", + "reply": { + "root": { + "uri": "at://did:plc:test123/social.coves.community.post/3k7a3dmb5bk2c", + "cid": "bafyreigj3fwnwjuzr35k2kuzmb5dixxczrzjhqkr5srlqplsh6gq3bj3si" + }, + "parent": { + "uri": "at://did:plc:test123/social.coves.community.post/3k7a3dmb5bk2c", + "cid": "bafyreigj3fwnwjuzr35k2kuzmb5dixxczrzjhqkr5srlqplsh6gq3bj3si" + } }, + "content": "👍", "createdAt": "2025-01-09T16:50:00Z" -} \ No newline at end of file +} diff --git a/tests/lexicon-test-data/interaction/comment-valid-text.json b/tests/lexicon-test-data/interaction/comment-valid-text.json index a71c434..1b695ac 100644 --- a/tests/lexicon-test-data/interaction/comment-valid-text.json +++ b/tests/lexicon-test-data/interaction/comment-valid-text.json @@ -1,23 +1,29 @@ { - "$type": "social.coves.interaction.comment", - "subject": "at://did:plc:author123/social.coves.post.record/3k7a3dmb5bk2c", - "content": { - "$type": "social.coves.interaction.comment#textContent", - "text": "Great post! I especially liked the part about @alice.example.com's contribution to the project.", - "facets": [ - { - "index": { - "byteStart": 46, - "byteEnd": 64 - }, - "features": [ - { - "$type": "social.coves.richtext.facet#mention", - "did": "did:plc:aliceuser123" - } - ] - } - ] + "$type": "social.coves.feed.comment", + "reply": { + "root": { + "uri": "at://did:plc:test123/social.coves.community.post/3k7a3dmb5bk2c", + "cid": "bafyreigj3fwnwjuzr35k2kuzmb5dixxczrzjhqkr5srlqplsh6gq3bj3si" + }, + "parent": { + "uri": "at://did:plc:test123/social.coves.community.post/3k7a3dmb5bk2c", + "cid": "bafyreigj3fwnwjuzr35k2kuzmb5dixxczrzjhqkr5srlqplsh6gq3bj3si" + } }, + "content": "Great post! I especially liked the part about @alice.example.com's contribution to the project.", + "facets": [ + { + "index": { + "byteStart": 46, + "byteEnd": 64 + }, + "features": [ + { + "$type": "social.coves.richtext.facet#mention", + "did": "did:plc:aliceuser123" + } + ] + } + ], "createdAt": "2025-01-09T16:30:00Z" -} \ No newline at end of file +} diff --git a/tests/lexicon-test-data/moderation/tribunal-vote-invalid-decision.json b/tests/lexicon-test-data/moderation/tribunal-vote-invalid-decision.json index bb78a31..01d9d3c 100644 --- a/tests/lexicon-test-data/moderation/tribunal-vote-invalid-decision.json +++ b/tests/lexicon-test-data/moderation/tribunal-vote-invalid-decision.json @@ -1,7 +1,7 @@ { "$type": "social.coves.moderation.tribunalVote", "tribunal": "at://did:plc:community123/social.coves.moderation.tribunal/3k7a3dmb5bk2c", - "subject": "at://did:plc:user123/social.coves.post.record/3k7a2clb4bj2b", + "subject": "at://$1/social.coves.community.post/3k7a2clb4bj2b", "decision": "maybe", "createdAt": "2025-01-09T18:00:00Z" } \ No newline at end of file diff --git a/tests/lexicon-test-data/moderation/tribunal-vote-valid.json b/tests/lexicon-test-data/moderation/tribunal-vote-valid.json index b6087a4..6a42232 100644 --- a/tests/lexicon-test-data/moderation/tribunal-vote-valid.json +++ b/tests/lexicon-test-data/moderation/tribunal-vote-valid.json @@ -1,7 +1,7 @@ { "$type": "social.coves.moderation.tribunalVote", "tribunal": "at://did:plc:community123/social.coves.moderation.tribunal/3k7a3dmb5bk2c", - "subject": "at://did:plc:spammer123/social.coves.post.record/3k7a2clb4bj2b", + "subject": "at://$1/social.coves.community.post/3k7a2clb4bj2b", "decision": "remove", "reasoning": "The moderator's action was justified based on clear violation of Rule 2 (No Spam). The user posted the same promotional content across multiple communities within a short timeframe.", "precedents": [ diff --git a/tests/lexicon-test-data/post/post-invalid-enum-type.json b/tests/lexicon-test-data/post/post-invalid-enum-type.json index bdaccd2..19af8cc 100644 --- a/tests/lexicon-test-data/post/post-invalid-enum-type.json +++ b/tests/lexicon-test-data/post/post-invalid-enum-type.json @@ -1,11 +1,11 @@ { - "$type": "social.coves.post.record", + "$type": "social.coves.community.post", "community": "did:plc:programming123", + "author": "did:plc:testauthor123", "postType": "invalid-type", "title": "This has an invalid post type", - "text": "The postType field has an invalid value", + "content": "The postType field is not defined in the schema and should be rejected", "tags": [], - "language": "en", - "contentWarnings": [], + "langs": ["en"], "createdAt": "2025-01-09T14:30:00Z" -} \ No newline at end of file +} diff --git a/tests/lexicon-test-data/post/post-invalid-missing-community.json b/tests/lexicon-test-data/post/post-invalid-missing-community.json index 34ba2b5..135dbb2 100644 --- a/tests/lexicon-test-data/post/post-invalid-missing-community.json +++ b/tests/lexicon-test-data/post/post-invalid-missing-community.json @@ -1,10 +1,9 @@ { - "$type": "social.coves.post.record", - "postType": "text", + "$type": "social.coves.community.post", + "author": "did:plc:testauthor123", "title": "Test Post", - "text": "This post is missing the required community field", + "content": "This post is missing the required community field", "tags": ["test"], - "language": "en", - "contentWarnings": [], + "langs": ["en"], "createdAt": "2025-01-09T14:30:00Z" -} \ No newline at end of file +} diff --git a/tests/lexicon-test-data/post/post-valid-text.json b/tests/lexicon-test-data/post/post-valid-text.json index 4f19de7..8d6380c 100644 --- a/tests/lexicon-test-data/post/post-valid-text.json +++ b/tests/lexicon-test-data/post/post-valid-text.json @@ -1,10 +1,10 @@ { - "$type": "social.coves.post.record", + "$type": "social.coves.community.post", "community": "did:plc:programming123", - "postType": "text", + "author": "did:plc:testauthor123", "title": "Best practices for error handling in Go", - "text": "I've been working with Go for a while now and wanted to share some thoughts on error handling patterns...", - "textFacets": [ + "content": "I've been working with Go for a while now and wanted to share some thoughts on error handling patterns...", + "facets": [ { "index": { "byteStart": 20, @@ -18,7 +18,6 @@ } ], "tags": ["golang", "error-handling", "best-practices"], - "language": "en", - "contentWarnings": [], + "langs": ["en"], "createdAt": "2025-01-09T14:30:00Z" -} \ No newline at end of file +}