summaryrefslogtreecommitdiffstats
path: root/internal/handler/grpc/convert_test.go
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-02-13 17:48:36 -0800
committerbndw <ben@bdw.to>2026-02-13 17:48:36 -0800
commit62d31434ddbadff18580826576e1169f539e23f0 (patch)
treea3e56da30e33ddf0dbfdea407df6724c9640a7b1 /internal/handler/grpc/convert_test.go
parent5fcf5bd1fa5b2e707cea82c4652ea65c3c113c1a (diff)
feat: add gRPC handler with event validation and publishing
Handler implementation: - EventStore interface (consumer-side) - Server with PublishEvent, QueryEvents, CountEvents, PublishBatch - pb.Event <-> nostr.Event conversion helpers - Signature and ID validation using existing nostr package - Canonical JSON generation for storage 9 tests passing
Diffstat (limited to 'internal/handler/grpc/convert_test.go')
-rw-r--r--internal/handler/grpc/convert_test.go143
1 files changed, 143 insertions, 0 deletions
diff --git a/internal/handler/grpc/convert_test.go b/internal/handler/grpc/convert_test.go
new file mode 100644
index 0000000..6da2d89
--- /dev/null
+++ b/internal/handler/grpc/convert_test.go
@@ -0,0 +1,143 @@
1package grpc
2
3import (
4 "testing"
5
6 pb "northwest.io/nostr-grpc/api/nostr/v1"
7 "northwest.io/nostr-grpc/internal/nostr"
8)
9
10func TestNostrToPB(t *testing.T) {
11 nostrEvent := &nostr.Event{
12 ID: "abc123",
13 PubKey: "pubkey123",
14 CreatedAt: 1234567890,
15 Kind: 1,
16 Tags: nostr.Tags{{"e", "event1"}, {"p", "pubkey1"}},
17 Content: "Hello, Nostr!",
18 Sig: "sig123",
19 }
20
21 pbEvent := NostrToPB(nostrEvent)
22
23 if pbEvent.Id != nostrEvent.ID {
24 t.Errorf("ID mismatch: expected %s, got %s", nostrEvent.ID, pbEvent.Id)
25 }
26 if pbEvent.Pubkey != nostrEvent.PubKey {
27 t.Errorf("Pubkey mismatch: expected %s, got %s", nostrEvent.PubKey, pbEvent.Pubkey)
28 }
29 if pbEvent.CreatedAt != nostrEvent.CreatedAt {
30 t.Errorf("CreatedAt mismatch: expected %d, got %d", nostrEvent.CreatedAt, pbEvent.CreatedAt)
31 }
32 if pbEvent.Kind != int32(nostrEvent.Kind) {
33 t.Errorf("Kind mismatch: expected %d, got %d", nostrEvent.Kind, pbEvent.Kind)
34 }
35 if pbEvent.Content != nostrEvent.Content {
36 t.Errorf("Content mismatch: expected %s, got %s", nostrEvent.Content, pbEvent.Content)
37 }
38 if pbEvent.Sig != nostrEvent.Sig {
39 t.Errorf("Sig mismatch: expected %s, got %s", nostrEvent.Sig, pbEvent.Sig)
40 }
41
42 if len(pbEvent.Tags) != len(nostrEvent.Tags) {
43 t.Fatalf("Tags length mismatch: expected %d, got %d", len(nostrEvent.Tags), len(pbEvent.Tags))
44 }
45
46 for i, tag := range pbEvent.Tags {
47 if len(tag.Values) != len(nostrEvent.Tags[i]) {
48 t.Errorf("Tag[%d] values length mismatch", i)
49 continue
50 }
51 for j, val := range tag.Values {
52 if val != nostrEvent.Tags[i][j] {
53 t.Errorf("Tag[%d][%d] mismatch: expected %s, got %s", i, j, nostrEvent.Tags[i][j], val)
54 }
55 }
56 }
57}
58
59func TestPBToNostr(t *testing.T) {
60 pbEvent := &pb.Event{
61 Id: "abc123",
62 Pubkey: "pubkey123",
63 CreatedAt: 1234567890,
64 Kind: 1,
65 Tags: []*pb.Tag{{Values: []string{"e", "event1"}}, {Values: []string{"p", "pubkey1"}}},
66 Content: "Hello, Nostr!",
67 Sig: "sig123",
68 }
69
70 nostrEvent := PBToNostr(pbEvent)
71
72 if nostrEvent.ID != pbEvent.Id {
73 t.Errorf("ID mismatch: expected %s, got %s", pbEvent.Id, nostrEvent.ID)
74 }
75 if nostrEvent.PubKey != pbEvent.Pubkey {
76 t.Errorf("Pubkey mismatch: expected %s, got %s", pbEvent.Pubkey, nostrEvent.PubKey)
77 }
78 if nostrEvent.CreatedAt != pbEvent.CreatedAt {
79 t.Errorf("CreatedAt mismatch: expected %d, got %d", pbEvent.CreatedAt, nostrEvent.CreatedAt)
80 }
81 if nostrEvent.Kind != int(pbEvent.Kind) {
82 t.Errorf("Kind mismatch: expected %d, got %d", pbEvent.Kind, nostrEvent.Kind)
83 }
84 if nostrEvent.Content != pbEvent.Content {
85 t.Errorf("Content mismatch: expected %s, got %s", pbEvent.Content, nostrEvent.Content)
86 }
87 if nostrEvent.Sig != pbEvent.Sig {
88 t.Errorf("Sig mismatch: expected %s, got %s", pbEvent.Sig, nostrEvent.Sig)
89 }
90
91 if len(nostrEvent.Tags) != len(pbEvent.Tags) {
92 t.Fatalf("Tags length mismatch: expected %d, got %d", len(pbEvent.Tags), len(nostrEvent.Tags))
93 }
94
95 for i, tag := range nostrEvent.Tags {
96 if len(tag) != len(pbEvent.Tags[i].Values) {
97 t.Errorf("Tag[%d] values length mismatch", i)
98 continue
99 }
100 for j, val := range tag {
101 if val != pbEvent.Tags[i].Values[j] {
102 t.Errorf("Tag[%d][%d] mismatch: expected %s, got %s", i, j, pbEvent.Tags[i].Values[j], val)
103 }
104 }
105 }
106}
107
108func TestRoundTrip(t *testing.T) {
109 original := &nostr.Event{
110 ID: "roundtrip123",
111 PubKey: "pubkey_roundtrip",
112 CreatedAt: 9876543210,
113 Kind: 7,
114 Tags: nostr.Tags{{"e", "evt"}, {"p", "pk", "relay"}},
115 Content: "Round trip test",
116 Sig: "signature",
117 }
118
119 pb := NostrToPB(original)
120 backToNostr := PBToNostr(pb)
121
122 if backToNostr.ID != original.ID {
123 t.Errorf("Round trip ID mismatch")
124 }
125 if backToNostr.PubKey != original.PubKey {
126 t.Errorf("Round trip PubKey mismatch")
127 }
128 if backToNostr.CreatedAt != original.CreatedAt {
129 t.Errorf("Round trip CreatedAt mismatch")
130 }
131 if backToNostr.Kind != original.Kind {
132 t.Errorf("Round trip Kind mismatch")
133 }
134 if backToNostr.Content != original.Content {
135 t.Errorf("Round trip Content mismatch")
136 }
137 if backToNostr.Sig != original.Sig {
138 t.Errorf("Round trip Sig mismatch")
139 }
140 if len(backToNostr.Tags) != len(original.Tags) {
141 t.Fatalf("Round trip Tags length mismatch")
142 }
143}