Skip to content

Commit

Permalink
Add contacts extractor
Browse files Browse the repository at this point in the history
  • Loading branch information
boreq committed Nov 16, 2023
1 parent fef8844 commit d3ae45c
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
5 changes: 5 additions & 0 deletions internal/fixtures/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ func somePrivateKeyHex() string {
return nostr.GeneratePrivateKey()
}

func SomePublicKey() domain.PublicKey {
p, _ := SomeKeyPair()
return p
}

func SomeKeyPair() (publicKey domain.PublicKey, secretKeyHex string) {
hex := somePrivateKeyHex()

Expand Down
45 changes: 45 additions & 0 deletions service/domain/contacts_extractor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package domain

import (
"github.com/boreq/errors"
"github.com/planetary-social/nos-event-service/internal"
"github.com/planetary-social/nos-event-service/internal/logging"
)

// ContactsExtractor does its best to get relay addresses out of events. It
// should only error out on obvious programming errors but not on malformed user
// input.
type ContactsExtractor struct {
logger logging.Logger
}

func NewContactsExtractor(logger logging.Logger) *ContactsExtractor {
return &ContactsExtractor{logger: logger.New("contactsExtractor")}
}

func (e *ContactsExtractor) Extract(event Event) ([]PublicKey, error) {
switch event.Kind() {
case EventKindContacts:
return e.extractFromContacts(event)
default:
return nil, nil
}
}

func (e *ContactsExtractor) extractFromContacts(event Event) ([]PublicKey, error) {
if event.Kind() != EventKindContacts {
return nil, errors.New("invalid event kind")
}

results := internal.NewEmptySet[PublicKey]()
for _, tag := range event.Tags() {
if tag.IsProfile() {
publicKey, err := tag.Profile()
if err != nil {
return nil, errors.Wrap(err, "error grabbing the profile tag")
}
results.Put(publicKey)
}
}
return results.List(), nil
}
65 changes: 65 additions & 0 deletions service/domain/contacts_extractor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package domain_test

import (
"sort"
"testing"

"github.com/planetary-social/nos-event-service/internal/fixtures"
"github.com/planetary-social/nos-event-service/service/domain"
"github.com/stretchr/testify/require"
)

func TestContactsExtractor(t *testing.T) {
publicKey1 := fixtures.SomePublicKey()
publicKey2 := fixtures.SomePublicKey()

testCases := []struct {
Name string

Kind domain.EventKind
Tags []domain.EventTag

Result []domain.PublicKey
}{
{
Name: "contacts",

Kind: domain.EventKindContacts,
Tags: []domain.EventTag{
domain.MustNewEventTag([]string{
"p", publicKey1.Hex(),
}),
domain.MustNewEventTag([]string{
"p", publicKey2.Hex(),
}),
},

Result: []domain.PublicKey{
publicKey1,
publicKey2,
},
},
}

for _, testCase := range testCases {
t.Run(testCase.Name, func(t *testing.T) {
event := fixtures.Event(testCase.Kind, testCase.Tags, fixtures.SomeString())

logger := fixtures.TestLogger(t)
extractor := domain.NewContactsExtractor(logger)

result, err := extractor.Extract(event)
require.NoError(t, err)

sort.Slice(result, func(i, j int) bool {
return result[i].Hex() < result[j].Hex()
})

sort.Slice(testCase.Result, func(i, j int) bool {
return testCase.Result[i].Hex() < testCase.Result[j].Hex()
})

require.Equal(t, testCase.Result, result)
})
}
}
8 changes: 8 additions & 0 deletions service/domain/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ func NewEventTag(tag []string) (EventTag, error) {
return EventTag{name: name, tag: tag}, nil
}

func MustNewEventTag(tag []string) EventTag {
v, err := NewEventTag(tag)
if err != nil {
panic(err)
}
return v
}

func (e EventTag) Name() EventTagName {
return e.name
}
Expand Down

0 comments on commit d3ae45c

Please sign in to comment.