mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-05-13 12:09:57 +02:00
serialization tests for events and filters.
This commit is contained in:
parent
5266482b2a
commit
41955a0601
11
event.go
11
event.go
@ -38,14 +38,13 @@ type Event struct {
|
|||||||
type Time time.Time
|
type Time time.Time
|
||||||
|
|
||||||
func (tm *Time) UnmarshalJSON(payload []byte) error {
|
func (tm *Time) UnmarshalJSON(payload []byte) error {
|
||||||
var unix int64
|
unix, err := strconv.ParseInt(string(payload), 10, 64)
|
||||||
err := json.Unmarshal(payload, &unix)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("time must be a unix timestamp as an integer, not '%s': %w",
|
return fmt.Errorf("time must be a unix timestamp as an integer, not '%s': %w",
|
||||||
string(payload), err)
|
string(payload), err)
|
||||||
}
|
}
|
||||||
t := Time(time.Unix(unix, 0))
|
t := Time(time.Unix(unix, 0))
|
||||||
tm = &t
|
*tm = t
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +52,12 @@ func (t Time) MarshalJSON() ([]byte, error) {
|
|||||||
return []byte(strconv.FormatInt(time.Time(t).Unix(), 10)), nil
|
return []byte(strconv.FormatInt(time.Time(t).Unix(), 10)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetID serializes and returns the event ID as a string
|
||||||
|
func (evt *Event) GetID() string {
|
||||||
|
h := sha256.Sum256(evt.Serialize())
|
||||||
|
return hex.EncodeToString(h[:])
|
||||||
|
}
|
||||||
|
|
||||||
// Serialize outputs a byte array that can be hashed/signed to identify/authenticate
|
// Serialize outputs a byte array that can be hashed/signed to identify/authenticate
|
||||||
func (evt *Event) Serialize() []byte {
|
func (evt *Event) Serialize() []byte {
|
||||||
// the serialization process is just putting everything into a JSON array
|
// the serialization process is just putting everything into a JSON array
|
||||||
|
34
event_test.go
Normal file
34
event_test.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package nostr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEventParsingAndVerifying(t *testing.T) {
|
||||||
|
raw := `{"id":"dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962","pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1644271588,"kind":1,"tags":[],"content":"now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?","sig":"230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}`
|
||||||
|
|
||||||
|
var ev Event
|
||||||
|
err := json.Unmarshal([]byte(raw), &ev)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to parse event json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ev.GetID() != ev.ID {
|
||||||
|
t.Errorf("error serializing event id: %s != %s", ev.GetID(), ev.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, _ := ev.CheckSignature(); !ok {
|
||||||
|
t.Error("signature verification failed when it should have succeeded")
|
||||||
|
}
|
||||||
|
|
||||||
|
asjson, err := json.Marshal(ev)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to re marshal event as json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if string(asjson) != raw {
|
||||||
|
t.Log(string(asjson))
|
||||||
|
t.Error("json serialization broken")
|
||||||
|
}
|
||||||
|
}
|
105
filter_test.go
Normal file
105
filter_test.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package nostr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterUnmarshal(t *testing.T) {
|
||||||
|
raw := `{"ids": ["abc"],"#e":["zzz"],"#something":["nothing","bab"],"since":1644254609}`
|
||||||
|
var f Filter
|
||||||
|
err := json.Unmarshal([]byte(raw), &f)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to parse filter json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.Since == nil || f.Since.Format("2006-01-02") != "2022-02-07" ||
|
||||||
|
f.Until != nil ||
|
||||||
|
f.Tags == nil || len(f.Tags) != 2 || !f.Tags["something"].Contains("bab") {
|
||||||
|
t.Error("failed to parse filter correctly")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterMarshal(t *testing.T) {
|
||||||
|
tm := time.Unix(12345678, 0)
|
||||||
|
|
||||||
|
filterj, err := json.Marshal(Filter{
|
||||||
|
Kinds: IntList{1, 2, 4},
|
||||||
|
Tags: map[string]StringList{"fruit": {"banana", "mango"}},
|
||||||
|
Until: &tm,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to marshal filter json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := `{"kinds":[1,2,4],"until":12345678,"#fruit":["banana","mango"]}`
|
||||||
|
if string(filterj) != expected {
|
||||||
|
t.Errorf("filter json was wrong: %s != %s", string(filterj), expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterMatching(t *testing.T) {
|
||||||
|
if (Filter{Kinds: IntList{4, 5}}).Matches(&Event{Kind: 6}) {
|
||||||
|
t.Error("matched event that shouldn't have matched")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(Filter{Kinds: IntList{4, 5}}).Matches(&Event{Kind: 4}) {
|
||||||
|
t.Error("failed to match event by kind")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(Filter{
|
||||||
|
Kinds: IntList{4, 5},
|
||||||
|
Tags: map[string]StringList{
|
||||||
|
"p": {"ooo"},
|
||||||
|
},
|
||||||
|
IDs: StringList{"prefix"},
|
||||||
|
}).Matches(&Event{
|
||||||
|
Kind: 4,
|
||||||
|
Tags: Tags{{"p", "ooo", ",x,x,"}, {"m", "yywyw", "xxx"}},
|
||||||
|
ID: "prefix123",
|
||||||
|
}) {
|
||||||
|
t.Error("failed to match event by kind+tags+id prefix")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterEquality(t *testing.T) {
|
||||||
|
if !FilterEqual(
|
||||||
|
Filter{Kinds: IntList{4, 5}},
|
||||||
|
Filter{Kinds: IntList{4, 5}},
|
||||||
|
) {
|
||||||
|
t.Error("kinds filters should be equal")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !FilterEqual(
|
||||||
|
Filter{Kinds: IntList{4, 5}, Tags: map[string]StringList{"letter": {"a", "b"}}},
|
||||||
|
Filter{Kinds: IntList{4, 5}, Tags: map[string]StringList{"letter": {"b", "a"}}},
|
||||||
|
) {
|
||||||
|
t.Error("kind+tags filters should be equal")
|
||||||
|
}
|
||||||
|
|
||||||
|
tm := time.Now()
|
||||||
|
if !FilterEqual(
|
||||||
|
Filter{
|
||||||
|
Kinds: IntList{4, 5},
|
||||||
|
Tags: map[string]StringList{"letter": {"a", "b"}, "fruit": {"banana"}},
|
||||||
|
Since: &tm,
|
||||||
|
IDs: StringList{"aaaa", "bbbb"},
|
||||||
|
},
|
||||||
|
Filter{
|
||||||
|
Kinds: IntList{5, 4},
|
||||||
|
Tags: map[string]StringList{"letter": {"a", "b"}, "fruit": {"banana"}},
|
||||||
|
Since: &tm,
|
||||||
|
IDs: StringList{"aaaa", "bbbb"},
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
t.Error("kind+2tags+since+ids filters should be equal")
|
||||||
|
}
|
||||||
|
|
||||||
|
if FilterEqual(
|
||||||
|
Filter{Kinds: IntList{1, 4, 5}},
|
||||||
|
Filter{Kinds: IntList{4, 5, 6}},
|
||||||
|
) {
|
||||||
|
t.Error("kinds filters shouldn't be equal")
|
||||||
|
}
|
||||||
|
}
|
4
go.mod
4
go.mod
@ -3,10 +3,10 @@ module github.com/fiatjaf/go-nostr
|
|||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/btcsuite/btcd v0.20.1-beta // indirect
|
github.com/btcsuite/btcd v0.20.1-beta
|
||||||
github.com/fiatjaf/bip340 v1.1.1
|
github.com/fiatjaf/bip340 v1.1.1
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/tyler-smith/go-bip32 v1.0.0
|
github.com/tyler-smith/go-bip32 v1.0.0
|
||||||
github.com/tyler-smith/go-bip39 v1.1.0
|
github.com/tyler-smith/go-bip39 v1.1.0
|
||||||
github.com/valyala/fastjson v1.6.3 // indirect
|
github.com/valyala/fastjson v1.6.3
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user