You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
342 lines
8.0 KiB
342 lines
8.0 KiB
package neo4j |
|
|
|
import ( |
|
"context" |
|
"os" |
|
"testing" |
|
"time" |
|
|
|
"git.mleku.dev/mleku/nostr/encoders/hex" |
|
"git.mleku.dev/mleku/nostr/interfaces/signer/p8k" |
|
) |
|
|
|
func TestNIP43_AddAndRemoveMember(t *testing.T) { |
|
neo4jURI := os.Getenv("ORLY_NEO4J_URI") |
|
if neo4jURI == "" { |
|
t.Skip("Skipping Neo4j test: ORLY_NEO4J_URI not set") |
|
} |
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
tempDir := t.TempDir() |
|
db, err := New(ctx, cancel, tempDir, "debug") |
|
if err != nil { |
|
t.Fatalf("Failed to create database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
<-db.Ready() |
|
|
|
if err := db.Wipe(); err != nil { |
|
t.Fatalf("Failed to wipe database: %v", err) |
|
} |
|
|
|
signer, _ := p8k.New() |
|
signer.Generate() |
|
pubkey := signer.Pub() |
|
|
|
// Add member |
|
inviteCode := "test-invite-123" |
|
if err := db.AddNIP43Member(pubkey, inviteCode); err != nil { |
|
t.Fatalf("Failed to add NIP-43 member: %v", err) |
|
} |
|
|
|
// Check membership |
|
isMember, err := db.IsNIP43Member(pubkey) |
|
if err != nil { |
|
t.Fatalf("Failed to check membership: %v", err) |
|
} |
|
if !isMember { |
|
t.Fatal("Expected pubkey to be a member") |
|
} |
|
|
|
// Get membership details |
|
membership, err := db.GetNIP43Membership(pubkey) |
|
if err != nil { |
|
t.Fatalf("Failed to get membership: %v", err) |
|
} |
|
if membership.InviteCode != inviteCode { |
|
t.Fatalf("Invite code mismatch: got %s, expected %s", membership.InviteCode, inviteCode) |
|
} |
|
|
|
// Remove member |
|
if err := db.RemoveNIP43Member(pubkey); err != nil { |
|
t.Fatalf("Failed to remove member: %v", err) |
|
} |
|
|
|
// Verify no longer a member |
|
isMember, _ = db.IsNIP43Member(pubkey) |
|
if isMember { |
|
t.Fatal("Expected pubkey to not be a member after removal") |
|
} |
|
|
|
t.Logf("✓ NIP-43 add and remove member works correctly") |
|
} |
|
|
|
func TestNIP43_GetAllMembers(t *testing.T) { |
|
neo4jURI := os.Getenv("ORLY_NEO4J_URI") |
|
if neo4jURI == "" { |
|
t.Skip("Skipping Neo4j test: ORLY_NEO4J_URI not set") |
|
} |
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
tempDir := t.TempDir() |
|
db, err := New(ctx, cancel, tempDir, "debug") |
|
if err != nil { |
|
t.Fatalf("Failed to create database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
<-db.Ready() |
|
|
|
if err := db.Wipe(); err != nil { |
|
t.Fatalf("Failed to wipe database: %v", err) |
|
} |
|
|
|
// Add multiple members |
|
var pubkeys [][]byte |
|
for i := 0; i < 3; i++ { |
|
signer, _ := p8k.New() |
|
signer.Generate() |
|
pubkey := signer.Pub() |
|
pubkeys = append(pubkeys, pubkey) |
|
|
|
if err := db.AddNIP43Member(pubkey, "invite"+string(rune('A'+i))); err != nil { |
|
t.Fatalf("Failed to add member %d: %v", i, err) |
|
} |
|
} |
|
|
|
// Get all members |
|
members, err := db.GetAllNIP43Members() |
|
if err != nil { |
|
t.Fatalf("Failed to get all members: %v", err) |
|
} |
|
|
|
if len(members) != 3 { |
|
t.Fatalf("Expected 3 members, got %d", len(members)) |
|
} |
|
|
|
// Verify all added pubkeys are in the members list |
|
memberMap := make(map[string]bool) |
|
for _, m := range members { |
|
memberMap[hex.Enc(m)] = true |
|
} |
|
|
|
for i, pk := range pubkeys { |
|
if !memberMap[hex.Enc(pk)] { |
|
t.Fatalf("Member %d not found in list", i) |
|
} |
|
} |
|
|
|
t.Logf("✓ GetAllNIP43Members returned %d members", len(members)) |
|
} |
|
|
|
func TestNIP43_InviteCode(t *testing.T) { |
|
neo4jURI := os.Getenv("ORLY_NEO4J_URI") |
|
if neo4jURI == "" { |
|
t.Skip("Skipping Neo4j test: ORLY_NEO4J_URI not set") |
|
} |
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
tempDir := t.TempDir() |
|
db, err := New(ctx, cancel, tempDir, "debug") |
|
if err != nil { |
|
t.Fatalf("Failed to create database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
<-db.Ready() |
|
|
|
if err := db.Wipe(); err != nil { |
|
t.Fatalf("Failed to wipe database: %v", err) |
|
} |
|
|
|
// Store valid invite code (expires in 1 hour) |
|
validCode := "valid-code-123" |
|
expiresAt := time.Now().Add(1 * time.Hour) |
|
if err := db.StoreInviteCode(validCode, expiresAt); err != nil { |
|
t.Fatalf("Failed to store invite code: %v", err) |
|
} |
|
|
|
// Validate the code |
|
isValid, err := db.ValidateInviteCode(validCode) |
|
if err != nil { |
|
t.Fatalf("Failed to validate invite code: %v", err) |
|
} |
|
if !isValid { |
|
t.Fatal("Expected valid invite code to be valid") |
|
} |
|
|
|
// Test non-existent code |
|
isValid, err = db.ValidateInviteCode("non-existent-code") |
|
if err != nil { |
|
t.Fatalf("Failed to validate non-existent code: %v", err) |
|
} |
|
if isValid { |
|
t.Fatal("Expected non-existent code to be invalid") |
|
} |
|
|
|
// Delete the invite code |
|
if err := db.DeleteInviteCode(validCode); err != nil { |
|
t.Fatalf("Failed to delete invite code: %v", err) |
|
} |
|
|
|
// Verify code is no longer valid |
|
isValid, _ = db.ValidateInviteCode(validCode) |
|
if isValid { |
|
t.Fatal("Expected deleted code to be invalid") |
|
} |
|
|
|
t.Logf("✓ NIP-43 invite code operations work correctly") |
|
} |
|
|
|
func TestNIP43_ExpiredInviteCode(t *testing.T) { |
|
neo4jURI := os.Getenv("ORLY_NEO4J_URI") |
|
if neo4jURI == "" { |
|
t.Skip("Skipping Neo4j test: ORLY_NEO4J_URI not set") |
|
} |
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
tempDir := t.TempDir() |
|
db, err := New(ctx, cancel, tempDir, "debug") |
|
if err != nil { |
|
t.Fatalf("Failed to create database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
<-db.Ready() |
|
|
|
if err := db.Wipe(); err != nil { |
|
t.Fatalf("Failed to wipe database: %v", err) |
|
} |
|
|
|
// Store expired invite code (expired 1 hour ago) |
|
expiredCode := "expired-code-123" |
|
expiresAt := time.Now().Add(-1 * time.Hour) |
|
if err := db.StoreInviteCode(expiredCode, expiresAt); err != nil { |
|
t.Fatalf("Failed to store expired invite code: %v", err) |
|
} |
|
|
|
// Validate should return false for expired code |
|
isValid, err := db.ValidateInviteCode(expiredCode) |
|
if err != nil { |
|
t.Fatalf("Failed to validate expired code: %v", err) |
|
} |
|
if isValid { |
|
t.Fatal("Expected expired code to be invalid") |
|
} |
|
|
|
t.Logf("✓ Expired invite code correctly detected as invalid") |
|
} |
|
|
|
func TestNIP43_DuplicateMember(t *testing.T) { |
|
neo4jURI := os.Getenv("ORLY_NEO4J_URI") |
|
if neo4jURI == "" { |
|
t.Skip("Skipping Neo4j test: ORLY_NEO4J_URI not set") |
|
} |
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
tempDir := t.TempDir() |
|
db, err := New(ctx, cancel, tempDir, "debug") |
|
if err != nil { |
|
t.Fatalf("Failed to create database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
<-db.Ready() |
|
|
|
if err := db.Wipe(); err != nil { |
|
t.Fatalf("Failed to wipe database: %v", err) |
|
} |
|
|
|
signer, _ := p8k.New() |
|
signer.Generate() |
|
pubkey := signer.Pub() |
|
|
|
// Add member first time |
|
if err := db.AddNIP43Member(pubkey, "invite1"); err != nil { |
|
t.Fatalf("Failed to add member: %v", err) |
|
} |
|
|
|
// Add same member again (should not error, just update) |
|
if err := db.AddNIP43Member(pubkey, "invite2"); err != nil { |
|
t.Fatalf("Failed to re-add member: %v", err) |
|
} |
|
|
|
// Check membership still exists |
|
isMember, _ := db.IsNIP43Member(pubkey) |
|
if !isMember { |
|
t.Fatal("Expected pubkey to still be a member") |
|
} |
|
|
|
// Get all members should have only 1 entry |
|
members, _ := db.GetAllNIP43Members() |
|
if len(members) != 1 { |
|
t.Fatalf("Expected 1 member, got %d", len(members)) |
|
} |
|
|
|
t.Logf("✓ Duplicate member handling works correctly") |
|
} |
|
|
|
func TestNIP43_MembershipPersistence(t *testing.T) { |
|
neo4jURI := os.Getenv("ORLY_NEO4J_URI") |
|
if neo4jURI == "" { |
|
t.Skip("Skipping Neo4j test: ORLY_NEO4J_URI not set") |
|
} |
|
|
|
ctx, cancel := context.WithCancel(context.Background()) |
|
defer cancel() |
|
|
|
tempDir := t.TempDir() |
|
db, err := New(ctx, cancel, tempDir, "debug") |
|
if err != nil { |
|
t.Fatalf("Failed to create database: %v", err) |
|
} |
|
defer db.Close() |
|
|
|
<-db.Ready() |
|
|
|
if err := db.Wipe(); err != nil { |
|
t.Fatalf("Failed to wipe database: %v", err) |
|
} |
|
|
|
signer, _ := p8k.New() |
|
signer.Generate() |
|
pubkey := signer.Pub() |
|
|
|
// Add member |
|
inviteCode := "persistence-test" |
|
if err := db.AddNIP43Member(pubkey, inviteCode); err != nil { |
|
t.Fatalf("Failed to add member: %v", err) |
|
} |
|
|
|
// Get membership and verify all fields |
|
membership, err := db.GetNIP43Membership(pubkey) |
|
if err != nil { |
|
t.Fatalf("Failed to get membership: %v", err) |
|
} |
|
|
|
if membership.InviteCode != inviteCode { |
|
t.Fatalf("InviteCode mismatch") |
|
} |
|
|
|
if membership.AddedAt.IsZero() { |
|
t.Fatal("AddedAt should not be zero") |
|
} |
|
|
|
// Verify the pubkey in membership matches |
|
if hex.Enc(membership.Pubkey[:]) != hex.Enc(pubkey) { |
|
t.Fatal("Pubkey mismatch in membership") |
|
} |
|
|
|
t.Logf("✓ NIP-43 membership persistence verified") |
|
}
|
|
|