diff --git a/zooid/config_test.go b/zooid/config_test.go index 94359c8..3ef129b 100644 --- a/zooid/config_test.go +++ b/zooid/config_test.go @@ -11,10 +11,9 @@ func TestConfig_IsOwner(t *testing.T) { otherPubkey := nostr.MustPubKeyFromHex("abcdef1234567890123456789012345678901234567890123456789012345678") config := &Config{ - Self: struct { + Info: struct { Name string `toml:"name"` Icon string `toml:"icon"` - Schema string `toml:"schema"` Secret string `toml:"secret"` Pubkey string `toml:"pubkey"` Description string `toml:"description"` @@ -38,16 +37,7 @@ func TestConfig_IsSelf(t *testing.T) { otherPubkey := nostr.MustPubKeyFromHex("abcdef1234567890123456789012345678901234567890123456789012345678") config := &Config{ - Self: struct { - Name string `toml:"name"` - Icon string `toml:"icon"` - Schema string `toml:"schema"` - Secret string `toml:"secret"` - Pubkey string `toml:"pubkey"` - Description string `toml:"description"` - }{ - Secret: secret.Hex(), - }, + secret: secret, } if !config.IsSelf(selfPubkey) { @@ -59,7 +49,7 @@ func TestConfig_IsSelf(t *testing.T) { } } -func TestConfig_GetRolesForPubkey(t *testing.T) { +func TestConfig_GetAllRoles(t *testing.T) { pubkey1 := nostr.MustPubKeyFromHex("1234567890123456789012345678901234567890123456789012345678901234") pubkey2 := nostr.MustPubKeyFromHex("abcdef1234567890123456789012345678901234567890123456789012345678") @@ -80,22 +70,33 @@ func TestConfig_GetRolesForPubkey(t *testing.T) { }, } - roles := config.GetRolesForPubkey(pubkey1) + roles := config.GetAllRoles(pubkey1) if len(roles) != 2 { - t.Errorf("GetRolesForPubkey() returned %d roles, want 2", len(roles)) + t.Errorf("GetAllRoles() returned %d roles, want 2", len(roles)) } - roles = config.GetRolesForPubkey(pubkey2) + roles = config.GetAllRoles(pubkey2) if len(roles) != 2 { - t.Errorf("GetRolesForPubkey() returned %d roles, want 2", len(roles)) + t.Errorf("GetAllRoles() returned %d roles, want 2", len(roles)) } } func TestConfig_CanManage(t *testing.T) { + ownerPubkey := nostr.MustPubKeyFromHex("9999999999999999999999999999999999999999999999999999999999999999") adminPubkey := nostr.MustPubKeyFromHex("1234567890123456789012345678901234567890123456789012345678901234") userPubkey := nostr.MustPubKeyFromHex("abcdef1234567890123456789012345678901234567890123456789012345678") config := &Config{ + secret: nostr.Generate(), + Info: struct { + Name string `toml:"name"` + Icon string `toml:"icon"` + Secret string `toml:"secret"` + Pubkey string `toml:"pubkey"` + Description string `toml:"description"` + }{ + Pubkey: ownerPubkey.Hex(), + }, Roles: map[string]Role{ "admin": { Pubkeys: []string{adminPubkey.Hex()}, @@ -118,10 +119,21 @@ func TestConfig_CanManage(t *testing.T) { } func TestConfig_CanInvite(t *testing.T) { + ownerPubkey := nostr.MustPubKeyFromHex("9999999999999999999999999999999999999999999999999999999999999999") inviterPubkey := nostr.MustPubKeyFromHex("1234567890123456789012345678901234567890123456789012345678901234") userPubkey := nostr.MustPubKeyFromHex("abcdef1234567890123456789012345678901234567890123456789012345678") config := &Config{ + secret: nostr.Generate(), + Info: struct { + Name string `toml:"name"` + Icon string `toml:"icon"` + Secret string `toml:"secret"` + Pubkey string `toml:"pubkey"` + Description string `toml:"description"` + }{ + Pubkey: ownerPubkey.Hex(), + }, Roles: map[string]Role{ "inviter": { Pubkeys: []string{inviterPubkey.Hex()}, @@ -144,9 +156,20 @@ func TestConfig_CanInvite(t *testing.T) { } func TestConfig_MemberRole(t *testing.T) { + ownerPubkey := nostr.MustPubKeyFromHex("9999999999999999999999999999999999999999999999999999999999999999") anyPubkey := nostr.MustPubKeyFromHex("1234567890123456789012345678901234567890123456789012345678901234") config := &Config{ + secret: nostr.Generate(), + Info: struct { + Name string `toml:"name"` + Icon string `toml:"icon"` + Secret string `toml:"secret"` + Pubkey string `toml:"pubkey"` + Description string `toml:"description"` + }{ + Pubkey: ownerPubkey.Hex(), + }, Roles: map[string]Role{ "member": { Pubkeys: []string{}, @@ -155,9 +178,9 @@ func TestConfig_MemberRole(t *testing.T) { }, } - roles := config.GetRolesForPubkey(anyPubkey) + roles := config.GetAllRoles(anyPubkey) if len(roles) != 1 { - t.Errorf("GetRolesForPubkey() should return member role for any pubkey, got %d roles", len(roles)) + t.Errorf("GetAllRoles() should return member role for any pubkey, got %d roles", len(roles)) } if !config.CanInvite(anyPubkey) { diff --git a/zooid/events_test.go b/zooid/events_test.go index 9e2d7fe..059ca51 100644 --- a/zooid/events_test.go +++ b/zooid/events_test.go @@ -10,7 +10,7 @@ func createTestEventStore() *EventStore { schema := &Schema{Name: "test_" + RandomString(8)} config := &Config{ Host: "test.com", - Secret: nostr.Generate(), + secret: nostr.Generate(), } return &EventStore{ Config: config, @@ -534,7 +534,7 @@ func TestEventStore_GetOrCreateApplicationSpecificData(t *testing.T) { dTag := "test/data" - // Test creating new data when none exists + // Test creating new data when none exists (unsigned) event1 := store.GetOrCreateApplicationSpecificData(dTag) if event1.Kind != nostr.KindApplicationSpecificData { @@ -546,9 +546,8 @@ func TestEventStore_GetOrCreateApplicationSpecificData(t *testing.T) { t.Errorf("GetOrCreateApplicationSpecificData() d tag = %v, want %v", dTagFound, dTag) } - if event1.PubKey != store.Config.Secret.Public() { - t.Error("GetOrCreateApplicationSpecificData() should be signed by config secret") - } + // Sign and store the event + store.SignAndStoreEvent(&event1, false) // Test retrieving existing data event2 := store.GetOrCreateApplicationSpecificData(dTag) @@ -557,6 +556,10 @@ func TestEventStore_GetOrCreateApplicationSpecificData(t *testing.T) { t.Error("GetOrCreateApplicationSpecificData() should return same event when called again") } + if event2.PubKey != store.Config.GetSelf() { + t.Error("Retrieved event should be signed by config secret") + } + // Test with different d tag creates new event event3 := store.GetOrCreateApplicationSpecificData("other/data") diff --git a/zooid/groups_test.go b/zooid/groups_test.go index 34863b2..6eed492 100644 --- a/zooid/groups_test.go +++ b/zooid/groups_test.go @@ -39,174 +39,3 @@ func TestGetGroupIDFromEvent(t *testing.T) { }) } } - -func TestMakeGroupMetadataFilter(t *testing.T) { - h := "group123" - filter := MakeGroupMetadataFilter(h) - - if len(filter.Kinds) != 1 || filter.Kinds[0] != nostr.KindSimpleGroupMetadata { - t.Errorf("MakeGroupMetadataFilter() kinds = %v, want [%v]", filter.Kinds, nostr.KindSimpleGroupMetadata) - } - - if filter.Tags["a"][0] != h { - t.Errorf("MakeGroupMetadataFilter() tags a = %v, want %v", filter.Tags["a"], h) - } -} - -func TestMakeGroupEventFilters(t *testing.T) { - h := "group123" - filters := MakeGroupEventFilters(h) - - if len(filters) != 2 { - t.Errorf("MakeGroupEventFilters() length = %v, want 2", len(filters)) - } - - if filters[0].Tags["a"][0] != h { - t.Errorf("MakeGroupEventFilters() first filter tag a = %v, want %v", filters[0].Tags["a"], h) - } - - if filters[1].Tags["h"][0] != h { - t.Errorf("MakeGroupEventFilters() second filter tag h = %v, want %v", filters[1].Tags["h"], h) - } -} - -func TestMakeGroupMembershipCheckFilter(t *testing.T) { - h := "group123" - pubkey := nostr.MustPubKeyFromHex("1234567890123456789012345678901234567890123456789012345678901234") - filter := MakeGroupMembershipCheckFilter(h, pubkey) - - expectedKinds := []nostr.Kind{nostr.KindSimpleGroupPutUser, nostr.KindSimpleGroupRemoveUser} - if len(filter.Kinds) != 2 { - t.Errorf("MakeGroupMembershipCheckFilter() kinds length = %v, want 2", len(filter.Kinds)) - } - for i, kind := range expectedKinds { - if filter.Kinds[i] != kind { - t.Errorf("MakeGroupMembershipCheckFilter() kinds[%d] = %v, want %v", i, filter.Kinds[i], kind) - } - } - - if filter.Tags["p"][0] != pubkey.Hex() { - t.Errorf("MakeGroupMembershipCheckFilter() tag p = %v, want %v", filter.Tags["p"], pubkey.Hex()) - } - - if filter.Tags["h"][0] != h { - t.Errorf("MakeGroupMembershipCheckFilter() tag h = %v, want %v", filter.Tags["h"], h) - } -} - -func TestCheckGroupMembership(t *testing.T) { - - tests := []struct { - name string - events []nostr.Event - want bool - }{ - { - name: "put user event", - events: []nostr.Event{ - {Kind: nostr.KindSimpleGroupPutUser}, - }, - want: true, - }, - { - name: "remove user event", - events: []nostr.Event{ - {Kind: nostr.KindSimpleGroupRemoveUser}, - }, - want: false, - }, - { - name: "no events", - events: []nostr.Event{}, - want: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - seq := func(yield func(nostr.Event) bool) { - for _, event := range tt.events { - if !yield(event) { - return - } - } - } - result := CheckGroupMembership(seq) - if result != tt.want { - t.Errorf("CheckGroupMembership() = %v, want %v", result, tt.want) - } - }) - } -} - -func TestMakePutUserEvent(t *testing.T) { - h := "group123" - pubkey := nostr.MustPubKeyFromHex("1234567890123456789012345678901234567890123456789012345678901234") - - event := MakePutUserEvent(h, pubkey) - - if event.Kind != nostr.KindSimpleGroupPutUser { - t.Errorf("MakePutUserEvent() kind = %v, want %v", event.Kind, nostr.KindSimpleGroupPutUser) - } - - if event.CreatedAt == 0 { - t.Error("MakePutUserEvent() should set CreatedAt") - } - - pTag := event.Tags.Find("p") - if pTag == nil || pTag[1] != pubkey.Hex() { - t.Errorf("MakePutUserEvent() p tag = %v, want %v", pTag, pubkey.Hex()) - } - - hTag := event.Tags.Find("h") - if hTag == nil || hTag[1] != h { - t.Errorf("MakePutUserEvent() h tag = %v, want %v", hTag, h) - } -} - -func TestMakeRemoveUserEvent(t *testing.T) { - h := "group123" - pubkey := nostr.MustPubKeyFromHex("1234567890123456789012345678901234567890123456789012345678901234") - - event := MakeRemoveUserEvent(h, pubkey) - - if event.Kind != nostr.KindSimpleGroupRemoveUser { - t.Errorf("MakeRemoveUserEvent() kind = %v, want %v", event.Kind, nostr.KindSimpleGroupRemoveUser) - } - - if event.CreatedAt == 0 { - t.Error("MakeRemoveUserEvent() should set CreatedAt") - } - - pTag := event.Tags.Find("p") - if pTag == nil || pTag[1] != pubkey.Hex() { - t.Errorf("MakeRemoveUserEvent() p tag = %v, want %v", pTag, pubkey.Hex()) - } - - hTag := event.Tags.Find("h") - if hTag == nil || hTag[1] != h { - t.Errorf("MakeRemoveUserEvent() h tag = %v, want %v", hTag, h) - } -} - -func TestMakeMetadataEvent(t *testing.T) { - originalEvent := nostr.Event{ - Kind: nostr.KindSimpleGroupCreateGroup, - CreatedAt: nostr.Timestamp(1234567890), - Tags: nostr.Tags{{"name", "Test Group"}}, - } - - metadataEvent := MakeMetadataEvent(originalEvent) - - if metadataEvent.Kind != nostr.KindSimpleGroupMetadata { - t.Errorf("MakeMetadataEvent() kind = %v, want %v", metadataEvent.Kind, nostr.KindSimpleGroupMetadata) - } - - if metadataEvent.CreatedAt != originalEvent.CreatedAt { - t.Errorf("MakeMetadataEvent() CreatedAt = %v, want %v", metadataEvent.CreatedAt, originalEvent.CreatedAt) - } - - if len(metadataEvent.Tags) != len(originalEvent.Tags) { - t.Errorf("MakeMetadataEvent() tags length = %v, want %v", len(metadataEvent.Tags), len(originalEvent.Tags)) - } -} diff --git a/zooid/instance_test.go b/zooid/instance_test.go index bdb0281..29a8158 100644 --- a/zooid/instance_test.go +++ b/zooid/instance_test.go @@ -4,6 +4,7 @@ import ( "testing" "fiatjaf.com/nostr" + "fiatjaf.com/nostr/khatru" ) func createTestInstance() *Instance { @@ -12,19 +13,16 @@ func createTestInstance() *Instance { config := &Config{ Host: "test.com", - Secret: ownerSecret, - Self: struct { + secret: ownerSecret, + Info: struct { Name string `toml:"name"` Icon string `toml:"icon"` - Schema string `toml:"schema"` Secret string `toml:"secret"` Pubkey string `toml:"pubkey"` Description string `toml:"description"` }{ Name: "Test Relay", - Secret: ownerSecret.Hex(), Pubkey: ownerPubkey.Hex(), - Schema: "test_relay", }, Roles: map[string]Role{ "admin": { @@ -36,18 +34,25 @@ func createTestInstance() *Instance { } schema := &Schema{Name: "test_" + RandomString(8)} + + relay := &khatru.Relay{} + events := &EventStore{ + Relay: relay, Config: config, Schema: schema, } - instance := &Instance{ + management := &ManagementStore{ Config: config, Events: events, - Management: &ManagementStore{ - Config: config, - Events: events, - }, + } + + instance := &Instance{ + Relay: relay, + Config: config, + Events: events, + Management: management, } instance.Events.Init() @@ -55,169 +60,14 @@ func createTestInstance() *Instance { return instance } -func TestInstance_IsAdmin(t *testing.T) { - instance := createTestInstance() - - ownerPubkey := instance.Config.Secret.Public() - otherPubkey := nostr.Generate().Public() - - // Test owner is admin - if !instance.Config.IsAdmin(ownerPubkey) { - t.Error("IsAdmin() should return true for owner") - } - - // Test non-owner is not admin - if instance.Config.IsAdmin(otherPubkey) { - t.Error("IsAdmin() should return false for non-owner") - } - - // Test user with manage permission is admin - managerPubkey := nostr.Generate().Public() - instance.Config.Roles["manager"] = Role{ - Pubkeys: []string{managerPubkey.Hex()}, - CanManage: true, - } - - if !instance.Config.IsAdmin(managerPubkey) { - t.Error("IsAdmin() should return true for user with manage permissions") - } -} - -func TestInstance_HasAccess(t *testing.T) { - instance := createTestInstance() - - ownerPubkey := instance.Config.Secret.Public() - userSecret := nostr.Generate() - userPubkey := userSecret.Public() - - // Test owner has access - if !instance.HasAccess(ownerPubkey) { - t.Error("HasAccess() should return true for owner") - } - - // Test user without join event has no access - if instance.HasAccess(userPubkey) { - t.Error("HasAccess() should return false for user without join event") - } - - // Add a join event for the user (must be signed by the user) - joinEvent := nostr.Event{ - Kind: RELAY_JOIN, - CreatedAt: nostr.Now(), - PubKey: userPubkey, - Tags: nostr.Tags{{"claim", "test"}}, - } - joinEvent.Sign(userSecret) - - instance.Events.SaveEvent(joinEvent) - - // Test user with join event has access - if !instance.HasAccess(userPubkey) { - t.Error("HasAccess() should return true for user with join event") - } -} - -func TestInstance_IsGroupMember(t *testing.T) { - instance := createTestInstance() - - groupID := "test-group-123" - userPubkey := nostr.Generate().Public() - - // Test user is not initially a member - if instance.IsGroupMember(groupID, userPubkey) { - t.Error("IsGroupMember() should return false for non-member") - } - - // Add user to group - putUserEvent := MakePutUserEvent(groupID, userPubkey) - putUserEvent.Sign(instance.Config.Secret) - instance.Events.SaveEvent(putUserEvent) - - // Test user is now a member - if !instance.IsGroupMember(groupID, userPubkey) { - t.Error("IsGroupMember() should return true after put user event") - } - - // Remove user from group (with a later timestamp to ensure proper ordering) - removeUserEvent := MakeRemoveUserEvent(groupID, userPubkey) - removeUserEvent.CreatedAt = nostr.Now() + 1 // Make it newer - removeUserEvent.Sign(instance.Config.Secret) - instance.Events.SaveEvent(removeUserEvent) - - // Test user is no longer a member - if instance.IsGroupMember(groupID, userPubkey) { - t.Error("IsGroupMember() should return false after remove user event") - } -} - -func TestInstance_HasGroupAccess(t *testing.T) { - instance := createTestInstance() - - groupID := "test-group-456" - userPubkey := nostr.Generate().Public() - - // Create open group metadata - openGroupMeta := nostr.Event{ - Kind: nostr.KindSimpleGroupMetadata, - CreatedAt: nostr.Now(), - Tags: nostr.Tags{ - {"a", groupID}, - {"name", "Open Group"}, - }, - } - openGroupMeta.Sign(instance.Config.Secret) - instance.Events.SaveEvent(openGroupMeta) - - // Test access to open group - if !instance.HasGroupAccess(groupID, userPubkey) { - t.Error("HasGroupAccess() should return true for open group") - } - - // Create closed group metadata - closedGroupID := "closed-group-789" - closedGroupMeta := nostr.Event{ - Kind: nostr.KindSimpleGroupMetadata, - CreatedAt: nostr.Now(), - Tags: nostr.Tags{ - {"a", closedGroupID}, - {"name", "Closed Group"}, - {"closed", ""}, - }, - } - closedGroupMeta.Sign(instance.Config.Secret) - instance.Events.SaveEvent(closedGroupMeta) - - // Test no access to closed group for non-member - if instance.HasGroupAccess(closedGroupID, userPubkey) { - t.Error("HasGroupAccess() should return false for closed group non-member") - } - - // Add user as member to closed group - putUserEvent := MakePutUserEvent(closedGroupID, userPubkey) - putUserEvent.Sign(instance.Config.Secret) - instance.Events.SaveEvent(putUserEvent) - - // Test access to closed group for member - if !instance.HasGroupAccess(closedGroupID, userPubkey) { - t.Error("HasGroupAccess() should return true for closed group member") - } -} - func TestInstance_AllowRecipientEvent(t *testing.T) { instance := createTestInstance() userSecret := nostr.Generate() userPubkey := userSecret.Public() - // Add user access - joinEvent := nostr.Event{ - Kind: RELAY_JOIN, - CreatedAt: nostr.Now(), - PubKey: userPubkey, - Tags: nostr.Tags{{"claim", "test"}}, - } - joinEvent.Sign(userSecret) - instance.Events.SaveEvent(joinEvent) + // Add user as member + instance.Management.AddMember(userPubkey) tests := []struct { name string @@ -289,7 +139,7 @@ func TestInstance_GenerateInviteEvent(t *testing.T) { t.Errorf("GenerateInviteEvent() kind = %v, want %v", inviteEvent.Kind, RELAY_INVITE) } - if inviteEvent.PubKey != instance.Config.Secret.Public() { + if inviteEvent.PubKey != instance.Config.GetSelf() { t.Error("GenerateInviteEvent() should be signed by instance") } @@ -303,106 +153,6 @@ func TestInstance_GenerateInviteEvent(t *testing.T) { if pTag == nil || pTag[1] != userPubkey.Hex() { t.Error("GenerateInviteEvent() should have correct p tag") } - - // Note: The GenerateInviteEvent function actually looks for existing events - // by the target pubkey as author, but creates events signed by instance. - // This seems to be a bug in the implementation, but we test the current behavior. - // Each call will generate a new event since the query won't find a match. - inviteEvent2 := instance.GenerateInviteEvent(userPubkey) - if inviteEvent.ID == inviteEvent2.ID { - t.Error("GenerateInviteEvent() generates new events each time due to query mismatch") - } -} - -func TestInstance_OnJoinEvent(t *testing.T) { - instance := createTestInstance() - - userPubkey := nostr.Generate().Public() - - // Generate an invite first - inviteEvent := instance.GenerateInviteEvent(userPubkey) - claimTag := inviteEvent.Tags.Find("claim") - - tests := []struct { - name string - joinEvent nostr.Event - wantReject bool - wantMsg string - }{ - { - name: "valid join event", - joinEvent: nostr.Event{ - Kind: RELAY_JOIN, - Tags: nostr.Tags{{"claim", claimTag[1]}}, - }, - wantReject: false, - wantMsg: "", - }, - { - name: "join event without claim", - joinEvent: nostr.Event{ - Kind: RELAY_JOIN, - Tags: nostr.Tags{}, - }, - wantReject: true, - wantMsg: "invalid: no claim tag", - }, - { - name: "join event with invalid claim", - joinEvent: nostr.Event{ - Kind: RELAY_JOIN, - Tags: nostr.Tags{{"claim", "invalid-claim"}}, - }, - wantReject: true, - wantMsg: "invalid: failed to validate invite code", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - reject, msg := instance.OnJoinEvent(tt.joinEvent) - if reject != tt.wantReject { - t.Errorf("OnJoinEvent() reject = %v, want %v", reject, tt.wantReject) - } - if msg != tt.wantMsg { - t.Errorf("OnJoinEvent() msg = %v, want %v", msg, tt.wantMsg) - } - }) - } -} - -func TestInstance_GetGroupMetadataEvent(t *testing.T) { - instance := createTestInstance() - - groupID := "test-group-metadata" - - // Test with no metadata event - metaEvent := instance.GetGroupMetadataEvent(groupID) - if !IsEmptyEvent(metaEvent) { - t.Error("GetGroupMetadataEvent() should return empty event when no metadata exists") - } - - // Create metadata event - originalMeta := nostr.Event{ - Kind: nostr.KindSimpleGroupMetadata, - CreatedAt: nostr.Now(), - Tags: nostr.Tags{ - {"a", groupID}, - {"name", "Test Group"}, - }, - } - originalMeta.Sign(instance.Config.Secret) - instance.Events.SaveEvent(originalMeta) - - // Test with metadata event - metaEvent = instance.GetGroupMetadataEvent(groupID) - if IsEmptyEvent(metaEvent) { - t.Error("GetGroupMetadataEvent() should return metadata event") - } - - if metaEvent.ID != originalMeta.ID { - t.Error("GetGroupMetadataEvent() should return correct metadata event") - } } func TestInstance_IsInternalEvent(t *testing.T) { @@ -464,27 +214,3 @@ func TestInstance_IsInternalEvent(t *testing.T) { }) } } - -func TestInstance_HasAccess_WithBannedUser(t *testing.T) { - instance := createTestInstance() - - userSecret := nostr.Generate() - userPubkey := userSecret.Public() - - // Add user to banned list - instance.Management.BanPubkey(userPubkey, "test ban") - - // Test banned user has no access even with join event - joinEvent := nostr.Event{ - Kind: RELAY_JOIN, - CreatedAt: nostr.Now(), - PubKey: userPubkey, - Tags: nostr.Tags{{"claim", "test"}}, - } - joinEvent.Sign(userSecret) - instance.Events.SaveEvent(joinEvent) - - if instance.HasAccess(userPubkey) { - t.Error("HasAccess() should return false for banned user even with join event") - } -} diff --git a/zooid/lib.go b/zooid/lib.go index ba0ac87..8493e35 100644 --- a/zooid/lib.go +++ b/zooid/lib.go @@ -28,17 +28,17 @@ func Dispatch(hostname string) (*Instance, bool) { func Start() { dataDir := Env("DATA") if err := os.MkdirAll(dataDir, 0755); err != nil { - log.Fatal("Failed to create data directory: %v", err) + log.Fatalf("Failed to create data directory: %v", err) } mediaDir := Env("MEDIA") if err := os.MkdirAll(mediaDir, 0755); err != nil { - log.Fatal("Failed to create media directory: %v", err) + log.Fatalf("Failed to create media directory: %v", err) } configDir := Env("CONFIG") if err := os.MkdirAll(configDir, 0755); err != nil { - log.Fatal("Failed to create config directory: %v", err) + log.Fatalf("Failed to create config directory: %v", err) } instancesOnce.Do(func() { @@ -48,7 +48,7 @@ func Start() { entries, err := os.ReadDir(configDir) if err != nil { - log.Fatal("Failed to scan config directory: %v", err) + log.Fatalf("Failed to scan config directory: %v", err) } for _, entry := range entries { diff --git a/zooid/management.go b/zooid/management.go index 1b7d73e..1513862 100644 --- a/zooid/management.go +++ b/zooid/management.go @@ -54,7 +54,7 @@ func (m *ManagementStore) BanEvent(id nostr.ID, reason string) error { func (m *ManagementStore) AllowEvent(id nostr.ID, reason string) error { event := m.Events.GetOrCreateApplicationSpecificData(BANNED_EVENTS) event.Tags = Filter(event.Tags, func(t nostr.Tag) bool { - return t[1] == id.Hex() + return t[1] != id.Hex() }) return m.Events.SignAndStoreEvent(&event, false) diff --git a/zooid/management_test.go b/zooid/management_test.go index 1d0b264..9f2b0ea 100644 --- a/zooid/management_test.go +++ b/zooid/management_test.go @@ -4,15 +4,18 @@ import ( "testing" "fiatjaf.com/nostr" + "fiatjaf.com/nostr/khatru" ) func createTestManagementStore() *ManagementStore { config := &Config{ Host: "test.com", - Secret: nostr.Generate(), + secret: nostr.Generate(), } schema := &Schema{Name: "test_" + RandomString(8)} + relay := &khatru.Relay{} events := &EventStore{ + Relay: relay, Config: config, Schema: schema, } @@ -39,24 +42,11 @@ func TestManagementStore_BanPubkey(t *testing.T) { t.Error("PubkeyIsBanned() should return true after banning") } - // Test banned pubkey list - bannedPubkeys := mgmt.GetBannedPubkeys() - found := false - for _, banned := range bannedPubkeys { - if banned == pubkey { - found = true - break - } - } - if !found { - t.Error("GetBannedPubkeys() should include banned pubkey") - } - // Test banned pubkey items bannedItems := mgmt.GetBannedPubkeyItems() itemFound := false for _, item := range bannedItems { - if item.Pubkey == pubkey && item.Reason == reason { + if item.PubKey == pubkey && item.Reason == reason { itemFound = true break } @@ -78,7 +68,7 @@ func TestManagementStore_AllowPubkey(t *testing.T) { t.Error("Setup: pubkey should be banned") } - mgmt.AllowPubkey(pubkey, "unbanned") + mgmt.AllowPubkey(pubkey) if mgmt.PubkeyIsBanned(pubkey) { t.Error("PubkeyIsBanned() should return false after allowing") @@ -98,24 +88,11 @@ func TestManagementStore_BanEvent(t *testing.T) { t.Error("EventIsBanned() should return true after banning") } - // Test banned event list - bannedEvents := mgmt.GetBannedEvents() - found := false - for _, banned := range bannedEvents { - if banned == eventID { - found = true - break - } - } - if !found { - t.Error("GetBannedEvents() should include banned event") - } - // Test banned event items bannedItems := mgmt.GetBannedEventItems() itemFound := false for _, item := range bannedItems { - if item.ID == eventID && item.Reason == reason { + if item.ID == eventID.Hex() && item.Reason == reason { itemFound = true break }