package storage import ( "context" "fmt" "testing" "time" pb "northwest.io/nostr-grpc/api/nostr/v1" ) func TestProcessDeletion(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: "event123", Pubkey: "alice", CreatedAt: time.Now().Unix(), Kind: 1, Tags: []*pb.Tag{}, Content: "to be deleted", Sig: "sig1", } err = store.StoreEvent(ctx, &EventData{ Event: event, CanonicalJSON: []byte(`[0,"alice",1234567890,1,[],"to be deleted"]`), }) if err != nil { t.Fatalf("failed to store event: %v", err) } retrieved, err := store.GetEvent(ctx, "event123") if err != nil { t.Fatalf("event should exist before deletion: %v", err) } if retrieved.Id != "event123" { t.Errorf("expected event123, got %s", retrieved.Id) } deletionEvent := &pb.Event{ Id: "deletion123", Pubkey: "alice", CreatedAt: time.Now().Unix(), Kind: KindDeletion, Tags: []*pb.Tag{ {Values: []string{"e", "event123"}}, }, Content: "deleting my event", Sig: "sig2", } err = store.ProcessDeletion(ctx, deletionEvent) if err != nil { t.Fatalf("failed to process deletion: %v", err) } _, err = store.GetEvent(ctx, "event123") if err != ErrEventNotFound { t.Errorf("event should be deleted, got error: %v", err) } } func TestProcessDeletionWrongAuthor(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: "event456", Pubkey: "alice", CreatedAt: time.Now().Unix(), Kind: 1, Tags: []*pb.Tag{}, Content: "alice's event", Sig: "sig1", } err = store.StoreEvent(ctx, &EventData{ Event: event, CanonicalJSON: []byte(`[0,"alice",1234567890,1,[],"alice's event"]`), }) if err != nil { t.Fatalf("failed to store event: %v", err) } deletionEvent := &pb.Event{ Id: "deletion456", Pubkey: "bob", CreatedAt: time.Now().Unix(), Kind: KindDeletion, Tags: []*pb.Tag{ {Values: []string{"e", "event456"}}, }, Content: "trying to delete alice's event", Sig: "sig2", } err = store.ProcessDeletion(ctx, deletionEvent) if err != nil { t.Fatalf("process deletion should succeed but not delete: %v", err) } retrieved, err := store.GetEvent(ctx, "event456") if err != nil { t.Fatalf("event should still exist: %v", err) } if retrieved.Id != "event456" { t.Errorf("expected event456, got %s", retrieved.Id) } } func TestProcessDeletionMultipleEvents(t *testing.T) { store, err := New(":memory:") if err != nil { t.Fatalf("failed to create storage: %v", err) } defer store.Close() ctx := context.Background() for i := 1; i <= 3; i++ { event := &pb.Event{ Id: fmt.Sprintf("event%d", i), Pubkey: "alice", CreatedAt: time.Now().Unix(), Kind: 1, Tags: []*pb.Tag{}, Content: fmt.Sprintf("event %d", i), Sig: fmt.Sprintf("sig%d", i), } err = store.StoreEvent(ctx, &EventData{ Event: event, CanonicalJSON: []byte(fmt.Sprintf(`[0,"alice",1234567890,1,[],"event %d"]`, i)), }) if err != nil { t.Fatalf("failed to store event: %v", err) } } deletionEvent := &pb.Event{ Id: "deletion789", Pubkey: "alice", CreatedAt: time.Now().Unix(), Kind: KindDeletion, Tags: []*pb.Tag{ {Values: []string{"e", "event1"}}, {Values: []string{"e", "event2"}}, }, Content: "deleting multiple events", Sig: "sig_del", } err = store.ProcessDeletion(ctx, deletionEvent) if err != nil { t.Fatalf("failed to process deletion: %v", err) } _, err = store.GetEvent(ctx, "event1") if err != ErrEventNotFound { t.Error("event1 should be deleted") } _, err = store.GetEvent(ctx, "event2") if err != ErrEventNotFound { t.Error("event2 should be deleted") } _, err = store.GetEvent(ctx, "event3") if err != nil { t.Error("event3 should still exist") } }