subscriptions_test.go raw
1 //go:build integration
2 // +build integration
3
4 package neo4j
5
6 import (
7 "testing"
8
9 "next.orly.dev/pkg/nostr/interfaces/signer/p8k"
10 )
11
12 // Note: WebSocket subscription management (AddSubscription, GetSubscriptionCount,
13 // RemoveSubscription, ClearSubscriptions) is handled at the app layer, not the
14 // database layer. Tests for those methods have been removed.
15
16 // All tests in this file use the shared testDB instance from testmain_test.go
17 // to avoid Neo4j authentication rate limiting from too many connections.
18
19 func TestMarkers_SetGetDelete(t *testing.T) {
20 if testDB == nil {
21 t.Skip("Neo4j not available")
22 }
23
24 cleanTestDatabase()
25
26 // Set a marker
27 key := "test-marker"
28 value := []byte("test-value-123")
29 if err := testDB.SetMarker(key, value); err != nil {
30 t.Fatalf("Failed to set marker: %v", err)
31 }
32
33 // Get the marker
34 retrieved, err := testDB.GetMarker(key)
35 if err != nil {
36 t.Fatalf("Failed to get marker: %v", err)
37 }
38 if string(retrieved) != string(value) {
39 t.Fatalf("Marker value mismatch: got %s, expected %s", string(retrieved), string(value))
40 }
41
42 // Update the marker
43 newValue := []byte("updated-value")
44 if err := testDB.SetMarker(key, newValue); err != nil {
45 t.Fatalf("Failed to update marker: %v", err)
46 }
47
48 retrieved, err = testDB.GetMarker(key)
49 if err != nil {
50 t.Fatalf("Failed to get updated marker: %v", err)
51 }
52 if string(retrieved) != string(newValue) {
53 t.Fatalf("Updated marker value mismatch")
54 }
55
56 // Delete the marker
57 if err := testDB.DeleteMarker(key); err != nil {
58 t.Fatalf("Failed to delete marker: %v", err)
59 }
60
61 // Verify marker is deleted
62 _, err = testDB.GetMarker(key)
63 if err == nil {
64 t.Fatal("Expected error when getting deleted marker")
65 }
66
67 t.Logf("✓ Markers set/get/delete works correctly")
68 }
69
70 func TestMarkers_GetNonExistent(t *testing.T) {
71 if testDB == nil {
72 t.Skip("Neo4j not available")
73 }
74
75 // Try to get non-existent marker (don't wipe - just test non-existent key)
76 _, err := testDB.GetMarker("non-existent-marker-unique-12345")
77 if err == nil {
78 t.Fatal("Expected error when getting non-existent marker")
79 }
80
81 t.Logf("✓ Getting non-existent marker returns error as expected")
82 }
83
84 func TestSerial_GetNextSerial(t *testing.T) {
85 if testDB == nil {
86 t.Skip("Neo4j not available")
87 }
88
89 // Get first serial
90 serial1, err := testDB.getNextSerial()
91 if err != nil {
92 t.Fatalf("Failed to get first serial: %v", err)
93 }
94
95 // Get second serial
96 serial2, err := testDB.getNextSerial()
97 if err != nil {
98 t.Fatalf("Failed to get second serial: %v", err)
99 }
100
101 // Serial should increment
102 if serial2 <= serial1 {
103 t.Fatalf("Expected serial to increment: serial1=%d, serial2=%d", serial1, serial2)
104 }
105
106 // Get multiple more serials and verify they're all unique and increasing
107 var serials []uint64
108 for i := 0; i < 10; i++ {
109 s, err := testDB.getNextSerial()
110 if err != nil {
111 t.Fatalf("Failed to get serial %d: %v", i, err)
112 }
113 serials = append(serials, s)
114 }
115
116 for i := 1; i < len(serials); i++ {
117 if serials[i] <= serials[i-1] {
118 t.Fatalf("Serials not increasing: %d <= %d", serials[i], serials[i-1])
119 }
120 }
121
122 t.Logf("✓ Serial generation works correctly (generated %d unique serials)", len(serials)+2)
123 }
124
125 func TestDatabaseReady(t *testing.T) {
126 if testDB == nil {
127 t.Skip("Neo4j not available")
128 }
129
130 // Database should already be ready (testDB is initialized in TestMain)
131 select {
132 case <-testDB.Ready():
133 t.Logf("✓ Database ready signal works correctly")
134 default:
135 t.Fatal("Expected database to be ready")
136 }
137 }
138
139 func TestIdentity(t *testing.T) {
140 if testDB == nil {
141 t.Skip("Neo4j not available")
142 }
143
144 cleanTestDatabase()
145
146 // Get identity (creates if not exists)
147 secret1, err := testDB.GetOrCreateRelayIdentitySecret()
148 if err != nil {
149 t.Fatalf("Failed to get identity: %v", err)
150 }
151 if secret1 == nil {
152 t.Fatal("Expected non-nil secret from GetOrCreateRelayIdentitySecret()")
153 }
154
155 // Get identity again (should return same one)
156 secret2, err := testDB.GetOrCreateRelayIdentitySecret()
157 if err != nil {
158 t.Fatalf("Failed to get identity second time: %v", err)
159 }
160 if secret2 == nil {
161 t.Fatal("Expected non-nil secret from second GetOrCreateRelayIdentitySecret() call")
162 }
163
164 // Secrets should match
165 if len(secret1) != len(secret2) {
166 t.Fatalf("Secret lengths don't match: %d vs %d", len(secret1), len(secret2))
167 }
168 for i := range secret1 {
169 if secret1[i] != secret2[i] {
170 t.Fatal("Identity secrets don't match across calls")
171 }
172 }
173
174 t.Logf("✓ Identity persistence works correctly")
175 }
176
177 func TestWipe(t *testing.T) {
178 if testDB == nil {
179 t.Skip("Neo4j not available")
180 }
181
182 signer, _ := p8k.New()
183 signer.Generate()
184
185 // Add some data
186 if err := testDB.AddNIP43Member(signer.Pub(), "test"); err != nil {
187 t.Fatalf("Failed to add member: %v", err)
188 }
189
190 // Wipe the database
191 if err := testDB.Wipe(); err != nil {
192 t.Fatalf("Failed to wipe database: %v", err)
193 }
194
195 // Verify data is gone
196 isMember, _ := testDB.IsNIP43Member(signer.Pub())
197 if isMember {
198 t.Fatal("Expected data to be wiped")
199 }
200
201 t.Logf("✓ Wipe clears database correctly")
202 }
203