package storage import ( "context" "testing" pb "northwest.io/nostr-grpc/api/nostr/v1" ) func TestStoreEvent(t *testing.T) { store, err := New(":memory:") if err != nil { t.Fatalf("failed to create storage: %v", err) } defer store.Close() ctx := context.Background() // Create test event event := &pb.Event{ Id: "test123", Pubkey: "pubkey123", CreatedAt: 1234567890, Kind: 1, Tags: []*pb.Tag{{Values: []string{"e", "event1"}}}, Content: "Hello, Nostr!", Sig: "sig123", } canonicalJSON := []byte(`[0,"pubkey123",1234567890,1,[["e","event1"]],"Hello, Nostr!"]`) data := &EventData{ Event: event, CanonicalJSON: canonicalJSON, } // Store event err = store.StoreEvent(ctx, data) if err != nil { t.Fatalf("failed to store event: %v", err) } // Verify event was stored retrieved, err := store.GetEvent(ctx, "test123") if err != nil { t.Fatalf("failed to retrieve event: %v", err) } if retrieved.Id != event.Id { t.Errorf("expected ID %s, got %s", event.Id, retrieved.Id) } if retrieved.Content != event.Content { t.Errorf("expected content %s, got %s", event.Content, retrieved.Content) } } func TestStoreEventDuplicate(t *testing.T) { store, err := New(":memory:") if err != nil { t.Fatalf("failed to create storage: %v", err) } defer store.Close() ctx := context.Background() event := &pb.Event{ Id: "duplicate123", Pubkey: "pubkey123", CreatedAt: 1234567890, Kind: 1, Content: "test", Sig: "sig123", } data := &EventData{ Event: event, CanonicalJSON: []byte(`[0,"pubkey123",1234567890,1,[],"test"]`), } // Store first time err = store.StoreEvent(ctx, data) if err != nil { t.Fatalf("failed to store event first time: %v", err) } // Try to store again err = store.StoreEvent(ctx, data) if err != ErrEventExists { t.Errorf("expected ErrEventExists, got %v", err) } } func TestGetEvent(t *testing.T) { store, err := New(":memory:") if err != nil { t.Fatalf("failed to create storage: %v", err) } defer store.Close() ctx := context.Background() // Test non-existent event _, err = store.GetEvent(ctx, "nonexistent") if err != ErrEventNotFound { t.Errorf("expected ErrEventNotFound, got %v", err) } } func TestGetEventWithCanonical(t *testing.T) { store, err := New(":memory:") if err != nil { t.Fatalf("failed to create storage: %v", err) } defer store.Close() ctx := context.Background() canonicalJSON := []byte(`[0,"pubkey123",1234567890,1,[],"test"]`) event := &pb.Event{ Id: "canonical123", Pubkey: "pubkey123", CreatedAt: 1234567890, Kind: 1, Content: "test", Sig: "sig123", } data := &EventData{ Event: event, CanonicalJSON: canonicalJSON, } err = store.StoreEvent(ctx, data) if err != nil { t.Fatalf("failed to store event: %v", err) } // Retrieve with canonical JSON retrieved, err := store.GetEventWithCanonical(ctx, "canonical123") if err != nil { t.Fatalf("failed to retrieve event: %v", err) } if string(retrieved.CanonicalJson) != string(canonicalJSON) { t.Errorf("canonical JSON mismatch:\nexpected: %s\ngot: %s", canonicalJSON, retrieved.CanonicalJson) } } func TestDeleteEvent(t *testing.T) { store, err := New(":memory:") if err != nil { t.Fatalf("failed to create storage: %v", err) } defer store.Close() ctx := context.Background() event := &pb.Event{ Id: "delete123", Pubkey: "pubkey123", CreatedAt: 1234567890, Kind: 1, Content: "to be deleted", Sig: "sig123", } data := &EventData{ Event: event, CanonicalJSON: []byte(`[0,"pubkey123",1234567890,1,[],"to be deleted"]`), } // Store event err = store.StoreEvent(ctx, data) if err != nil { t.Fatalf("failed to store event: %v", err) } // Delete event err = store.DeleteEvent(ctx, "delete123") if err != nil { t.Fatalf("failed to delete event: %v", err) } // Verify event is no longer retrievable _, err = store.GetEvent(ctx, "delete123") if err != ErrEventNotFound { t.Errorf("expected ErrEventNotFound after deletion, got %v", err) } // Try deleting non-existent event err = store.DeleteEvent(ctx, "nonexistent") if err != ErrEventNotFound { t.Errorf("expected ErrEventNotFound, got %v", err) } } func TestCompressDecompressJSON(t *testing.T) { original := []byte(`{"key":"value","array":[1,2,3],"nested":{"a":"b"}}`) compressed, err := compressJSON(original) if err != nil { t.Fatalf("compression failed: %v", err) } // Verify compression reduces size (for larger data) if len(compressed) >= len(original) { t.Logf("Note: compressed size (%d) >= original (%d) - normal for small data", len(compressed), len(original)) } decompressed, err := decompressJSON(compressed) if err != nil { t.Fatalf("decompression failed: %v", err) } if string(decompressed) != string(original) { t.Errorf("decompressed data doesn't match original:\nexpected: %s\ngot: %s", original, decompressed) } } func TestMarshalTags(t *testing.T) { tests := []struct { name string tags []*pb.Tag expected string }{ { name: "empty tags", tags: nil, expected: "[]", }, { name: "single tag", tags: []*pb.Tag{ {Values: []string{"e", "event123"}}, }, expected: `[["e","event123"]]`, }, { name: "multiple tags", tags: []*pb.Tag{ {Values: []string{"e", "event123", "wss://relay.example.com"}}, {Values: []string{"p", "pubkey456"}}, }, expected: `[["e","event123","wss://relay.example.com"],["p","pubkey456"]]`, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, err := marshalTags(tt.tags) if err != nil { t.Fatalf("marshalTags failed: %v", err) } if result != tt.expected { t.Errorf("expected %s, got %s", tt.expected, result) } }) } }