···
oauthClient := SetupOAuthTestClient(t, oauthStore)
-
voteService := votes.NewService(voteRepo, nil, oauthClient, oauthStore, nil)
// Create test user on PDS
testUserHandle := fmt.Sprintf("voter-%d.local.coves.dev", time.Now().Unix())
···
-
if err := json.NewDecoder(resp.Body).Decode(&voteResp); err != nil {
-
t.Fatalf("Failed to decode vote response: %v", err)
t.Logf("ā
XRPC response received:")
···
oauthStore := SetupOAuthTestStore(t, db)
oauthClient := SetupOAuthTestClient(t, oauthStore)
-
voteService := votes.NewService(voteRepo, nil, oauthClient, oauthStore, nil)
testUserHandle := fmt.Sprintf("toggle-%d.local.coves.dev", time.Now().Unix())
···
-
json.NewDecoder(resp.Body).Decode(&firstVoteResp)
t.Logf("ā
First vote created: %s", firstVoteResp.URI)
···
-
voteConsumer.HandleEvent(ctx, &voteEvent)
// Second upvote (same direction) - should toggle off (delete)
t.Logf("\nš Creating second upvote (toggle off)...")
···
t.Fatalf("Failed to toggle vote: %v", err)
-
defer resp2.Body.Close()
if resp2.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp2.Body)
···
-
voteConsumer.HandleEvent(ctx, &deleteEvent)
// Verify vote was removed from AppView
t.Logf("\nš Verifying vote removed from AppView...")
···
oauthStore := SetupOAuthTestStore(t, db)
oauthClient := SetupOAuthTestClient(t, oauthStore)
-
voteService := votes.NewService(voteRepo, nil, oauthClient, oauthStore, nil)
testUserHandle := fmt.Sprintf("flip-%d.local.coves.dev", time.Now().Unix())
···
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
-
resp, _ := http.DefaultClient.Do(req)
-
json.NewDecoder(resp.Body).Decode(&upvoteResp)
rkey := utils.ExtractRKeyFromURI(upvoteResp.URI)
···
-
voteConsumer.HandleEvent(ctx, &upvoteEvent)
t.Logf("ā
Upvote created and indexed")
···
req2.Header.Set("Content-Type", "application/json")
req2.Header.Set("Authorization", "Bearer "+token)
-
resp2, _ := http.DefaultClient.Do(req2)
var downvoteResp struct {
-
json.NewDecoder(resp2.Body).Decode(&downvoteResp)
// Simulate Jetstream UPDATE event (PDS updates the existing record)
t.Logf("\nš Simulating Jetstream UPDATE event...")
···
-
voteConsumer.HandleEvent(ctx, &updateEvent)
// Verify vote direction changed in AppView
t.Logf("\nš Verifying vote direction changed in AppView...")
···
oauthStore := SetupOAuthTestStore(t, db)
oauthClient := SetupOAuthTestClient(t, oauthStore)
-
voteService := votes.NewService(voteRepo, nil, oauthClient, oauthStore, nil)
testUserHandle := fmt.Sprintf("delete-%d.local.coves.dev", time.Now().Unix())
···
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
-
resp, _ := http.DefaultClient.Do(req)
-
json.NewDecoder(resp.Body).Decode(&voteResp)
rkey := utils.ExtractRKeyFromURI(voteResp.URI)
···
-
voteConsumer.HandleEvent(ctx, &voteEvent)
t.Logf("ā
Vote created and indexed")
···
deleteHttpReq.Header.Set("Content-Type", "application/json")
deleteHttpReq.Header.Set("Authorization", "Bearer "+token)
-
deleteResp, _ := http.DefaultClient.Do(deleteHttpReq)
-
defer deleteResp.Body.Close()
if deleteResp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(deleteResp.Body)
···
// Per lexicon, delete returns empty object {}
var deleteRespBody map[string]interface{}
-
json.NewDecoder(deleteResp.Body).Decode(&deleteRespBody)
if len(deleteRespBody) != 0 {
t.Errorf("Expected empty object per lexicon, got %v", deleteRespBody)
···
-
voteConsumer.HandleEvent(ctx, &deleteEvent)
// Verify vote removed from AppView
t.Logf("\nš Verifying vote removed from AppView...")
···
oauthClient := SetupOAuthTestClient(t, oauthStore)
+
voteService := votes.NewService(voteRepo, oauthClient, oauthStore, nil)
// Create test user on PDS
testUserHandle := fmt.Sprintf("voter-%d.local.coves.dev", time.Now().Unix())
···
+
if decodeErr := json.NewDecoder(resp.Body).Decode(&voteResp); decodeErr != nil {
+
t.Fatalf("Failed to decode vote response: %v", decodeErr)
t.Logf("ā
XRPC response received:")
···
oauthStore := SetupOAuthTestStore(t, db)
oauthClient := SetupOAuthTestClient(t, oauthStore)
+
voteService := votes.NewService(voteRepo, oauthClient, oauthStore, nil)
testUserHandle := fmt.Sprintf("toggle-%d.local.coves.dev", time.Now().Unix())
···
+
if decodeErr := json.NewDecoder(resp.Body).Decode(&firstVoteResp); decodeErr != nil {
+
t.Fatalf("Failed to decode first vote response: %v", decodeErr)
+
if closeErr := resp.Body.Close(); closeErr != nil {
+
t.Logf("Failed to close response body: %v", closeErr)
t.Logf("ā
First vote created: %s", firstVoteResp.URI)
···
+
if handleErr := voteConsumer.HandleEvent(ctx, &voteEvent); handleErr != nil {
+
t.Fatalf("Failed to handle first vote event: %v", handleErr)
// Second upvote (same direction) - should toggle off (delete)
t.Logf("\nš Creating second upvote (toggle off)...")
···
t.Fatalf("Failed to toggle vote: %v", err)
+
if closeErr := resp2.Body.Close(); closeErr != nil {
+
t.Logf("Failed to close response body: %v", closeErr)
if resp2.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp2.Body)
···
+
if handleErr := voteConsumer.HandleEvent(ctx, &deleteEvent); handleErr != nil {
+
t.Fatalf("Failed to handle delete event: %v", handleErr)
// Verify vote was removed from AppView
t.Logf("\nš Verifying vote removed from AppView...")
···
oauthStore := SetupOAuthTestStore(t, db)
oauthClient := SetupOAuthTestClient(t, oauthStore)
+
voteService := votes.NewService(voteRepo, oauthClient, oauthStore, nil)
testUserHandle := fmt.Sprintf("flip-%d.local.coves.dev", time.Now().Unix())
···
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
+
resp, err := http.DefaultClient.Do(req)
+
t.Fatalf("Failed to create upvote: %v", err)
+
if decodeErr := json.NewDecoder(resp.Body).Decode(&upvoteResp); decodeErr != nil {
+
t.Fatalf("Failed to decode upvote response: %v", decodeErr)
+
if closeErr := resp.Body.Close(); closeErr != nil {
+
t.Logf("Failed to close response body: %v", closeErr)
rkey := utils.ExtractRKeyFromURI(upvoteResp.URI)
···
+
if handleErr := voteConsumer.HandleEvent(ctx, &upvoteEvent); handleErr != nil {
+
t.Fatalf("Failed to handle upvote event: %v", handleErr)
t.Logf("ā
Upvote created and indexed")
···
req2.Header.Set("Content-Type", "application/json")
req2.Header.Set("Authorization", "Bearer "+token)
+
resp2, err := http.DefaultClient.Do(req2)
+
t.Fatalf("Failed to create downvote: %v", err)
var downvoteResp struct {
+
if decodeErr := json.NewDecoder(resp2.Body).Decode(&downvoteResp); decodeErr != nil {
+
t.Fatalf("Failed to decode downvote response: %v", decodeErr)
+
if closeErr := resp2.Body.Close(); closeErr != nil {
+
t.Logf("Failed to close response body: %v", closeErr)
// Simulate Jetstream UPDATE event (PDS updates the existing record)
t.Logf("\nš Simulating Jetstream UPDATE event...")
···
+
if handleErr := voteConsumer.HandleEvent(ctx, &updateEvent); handleErr != nil {
+
t.Fatalf("Failed to handle update event: %v", handleErr)
// Verify vote direction changed in AppView
t.Logf("\nš Verifying vote direction changed in AppView...")
···
oauthStore := SetupOAuthTestStore(t, db)
oauthClient := SetupOAuthTestClient(t, oauthStore)
+
voteService := votes.NewService(voteRepo, oauthClient, oauthStore, nil)
testUserHandle := fmt.Sprintf("delete-%d.local.coves.dev", time.Now().Unix())
···
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
+
resp, err := http.DefaultClient.Do(req)
+
t.Fatalf("Failed to create vote: %v", err)
+
if decodeErr := json.NewDecoder(resp.Body).Decode(&voteResp); decodeErr != nil {
+
t.Fatalf("Failed to decode vote response: %v", decodeErr)
+
if closeErr := resp.Body.Close(); closeErr != nil {
+
t.Logf("Failed to close response body: %v", closeErr)
rkey := utils.ExtractRKeyFromURI(voteResp.URI)
···
+
if handleErr := voteConsumer.HandleEvent(ctx, &voteEvent); handleErr != nil {
+
t.Fatalf("Failed to handle vote event: %v", handleErr)
t.Logf("ā
Vote created and indexed")
···
deleteHttpReq.Header.Set("Content-Type", "application/json")
deleteHttpReq.Header.Set("Authorization", "Bearer "+token)
+
deleteResp, err := http.DefaultClient.Do(deleteHttpReq)
+
t.Fatalf("Failed to delete vote: %v", err)
+
if closeErr := deleteResp.Body.Close(); closeErr != nil {
+
t.Logf("Failed to close response body: %v", closeErr)
if deleteResp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(deleteResp.Body)
···
// Per lexicon, delete returns empty object {}
var deleteRespBody map[string]interface{}
+
if decodeErr := json.NewDecoder(deleteResp.Body).Decode(&deleteRespBody); decodeErr != nil {
+
t.Fatalf("Failed to decode delete response: %v", decodeErr)
if len(deleteRespBody) != 0 {
t.Errorf("Expected empty object per lexicon, got %v", deleteRespBody)
···
+
if handleErr := voteConsumer.HandleEvent(ctx, &deleteEvent); handleErr != nil {
+
t.Fatalf("Failed to handle delete event: %v", handleErr)
// Verify vote removed from AppView
t.Logf("\nš Verifying vote removed from AppView...")