//go:build integration // +build integration package neo4j import ( "testing" "git.mleku.dev/mleku/nostr/interfaces/signer/p8k" ) // Note: WebSocket subscription management (AddSubscription, GetSubscriptionCount, // RemoveSubscription, ClearSubscriptions) is handled at the app layer, not the // database layer. Tests for those methods have been removed. // All tests in this file use the shared testDB instance from testmain_test.go // to avoid Neo4j authentication rate limiting from too many connections. func TestMarkers_SetGetDelete(t *testing.T) { if testDB == nil { t.Skip("Neo4j not available") } cleanTestDatabase() // Set a marker key := "test-marker" value := []byte("test-value-123") if err := testDB.SetMarker(key, value); err != nil { t.Fatalf("Failed to set marker: %v", err) } // Get the marker retrieved, err := testDB.GetMarker(key) if err != nil { t.Fatalf("Failed to get marker: %v", err) } if string(retrieved) != string(value) { t.Fatalf("Marker value mismatch: got %s, expected %s", string(retrieved), string(value)) } // Update the marker newValue := []byte("updated-value") if err := testDB.SetMarker(key, newValue); err != nil { t.Fatalf("Failed to update marker: %v", err) } retrieved, err = testDB.GetMarker(key) if err != nil { t.Fatalf("Failed to get updated marker: %v", err) } if string(retrieved) != string(newValue) { t.Fatalf("Updated marker value mismatch") } // Delete the marker if err := testDB.DeleteMarker(key); err != nil { t.Fatalf("Failed to delete marker: %v", err) } // Verify marker is deleted _, err = testDB.GetMarker(key) if err == nil { t.Fatal("Expected error when getting deleted marker") } t.Logf("✓ Markers set/get/delete works correctly") } func TestMarkers_GetNonExistent(t *testing.T) { if testDB == nil { t.Skip("Neo4j not available") } // Try to get non-existent marker (don't wipe - just test non-existent key) _, err := testDB.GetMarker("non-existent-marker-unique-12345") if err == nil { t.Fatal("Expected error when getting non-existent marker") } t.Logf("✓ Getting non-existent marker returns error as expected") } func TestSerial_GetNextSerial(t *testing.T) { if testDB == nil { t.Skip("Neo4j not available") } // Get first serial serial1, err := testDB.getNextSerial() if err != nil { t.Fatalf("Failed to get first serial: %v", err) } // Get second serial serial2, err := testDB.getNextSerial() if err != nil { t.Fatalf("Failed to get second serial: %v", err) } // Serial should increment if serial2 <= serial1 { t.Fatalf("Expected serial to increment: serial1=%d, serial2=%d", serial1, serial2) } // Get multiple more serials and verify they're all unique and increasing var serials []uint64 for i := 0; i < 10; i++ { s, err := testDB.getNextSerial() if err != nil { t.Fatalf("Failed to get serial %d: %v", i, err) } serials = append(serials, s) } for i := 1; i < len(serials); i++ { if serials[i] <= serials[i-1] { t.Fatalf("Serials not increasing: %d <= %d", serials[i], serials[i-1]) } } t.Logf("✓ Serial generation works correctly (generated %d unique serials)", len(serials)+2) } func TestDatabaseReady(t *testing.T) { if testDB == nil { t.Skip("Neo4j not available") } // Database should already be ready (testDB is initialized in TestMain) select { case <-testDB.Ready(): t.Logf("✓ Database ready signal works correctly") default: t.Fatal("Expected database to be ready") } } func TestIdentity(t *testing.T) { if testDB == nil { t.Skip("Neo4j not available") } cleanTestDatabase() // Get identity (creates if not exists) secret1, err := testDB.GetOrCreateRelayIdentitySecret() if err != nil { t.Fatalf("Failed to get identity: %v", err) } if secret1 == nil { t.Fatal("Expected non-nil secret from GetOrCreateRelayIdentitySecret()") } // Get identity again (should return same one) secret2, err := testDB.GetOrCreateRelayIdentitySecret() if err != nil { t.Fatalf("Failed to get identity second time: %v", err) } if secret2 == nil { t.Fatal("Expected non-nil secret from second GetOrCreateRelayIdentitySecret() call") } // Secrets should match if len(secret1) != len(secret2) { t.Fatalf("Secret lengths don't match: %d vs %d", len(secret1), len(secret2)) } for i := range secret1 { if secret1[i] != secret2[i] { t.Fatal("Identity secrets don't match across calls") } } t.Logf("✓ Identity persistence works correctly") } func TestWipe(t *testing.T) { if testDB == nil { t.Skip("Neo4j not available") } signer, _ := p8k.New() signer.Generate() // Add some data if err := testDB.AddNIP43Member(signer.Pub(), "test"); err != nil { t.Fatalf("Failed to add member: %v", err) } // Wipe the database if err := testDB.Wipe(); err != nil { t.Fatalf("Failed to wipe database: %v", err) } // Verify data is gone isMember, _ := testDB.IsNIP43Member(signer.Pub()) if isMember { t.Fatal("Expected data to be wiped") } t.Logf("✓ Wipe clears database correctly") }