Update tests
This commit is contained in:
+42
-19
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
+18
-292
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user