mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-07-01 19:11:05 +02:00
fix ParseMessage() so it works with CLOSED and improve tests.
This commit is contained in:
34
envelopes.go
34
envelopes.go
@ -16,6 +16,7 @@ func ParseMessage(message []byte) Envelope {
|
||||
return nil
|
||||
}
|
||||
label := message[0:firstComma]
|
||||
|
||||
var v Envelope
|
||||
switch {
|
||||
case bytes.Contains(label, []byte("EVENT")):
|
||||
@ -34,11 +35,11 @@ func ParseMessage(message []byte) Envelope {
|
||||
v = &OKEnvelope{}
|
||||
case bytes.Contains(label, []byte("AUTH")):
|
||||
v = &AuthEnvelope{}
|
||||
case bytes.Contains(label, []byte("CLOSED")):
|
||||
v = &ClosedEnvelope{}
|
||||
case bytes.Contains(label, []byte("CLOSE")):
|
||||
x := CloseEnvelope("")
|
||||
v = &x
|
||||
case bytes.Contains(label, []byte("CLOSED")):
|
||||
v = &ClosedEnvelope{}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@ -53,6 +54,7 @@ type Envelope interface {
|
||||
Label() string
|
||||
UnmarshalJSON([]byte) error
|
||||
MarshalJSON() ([]byte, error)
|
||||
String() string
|
||||
}
|
||||
|
||||
type EventEnvelope struct {
|
||||
@ -143,6 +145,10 @@ type CountEnvelope struct {
|
||||
}
|
||||
|
||||
func (_ CountEnvelope) Label() string { return "COUNT" }
|
||||
func (c CountEnvelope) String() string {
|
||||
v, _ := json.Marshal(c)
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v *CountEnvelope) UnmarshalJSON(data []byte) error {
|
||||
r := gjson.ParseBytes(data)
|
||||
@ -198,6 +204,10 @@ func (v CountEnvelope) MarshalJSON() ([]byte, error) {
|
||||
type NoticeEnvelope string
|
||||
|
||||
func (_ NoticeEnvelope) Label() string { return "NOTICE" }
|
||||
func (n NoticeEnvelope) String() string {
|
||||
v, _ := json.Marshal(n)
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v *NoticeEnvelope) UnmarshalJSON(data []byte) error {
|
||||
r := gjson.ParseBytes(data)
|
||||
@ -220,6 +230,10 @@ func (v NoticeEnvelope) MarshalJSON() ([]byte, error) {
|
||||
type EOSEEnvelope string
|
||||
|
||||
func (_ EOSEEnvelope) Label() string { return "EOSE" }
|
||||
func (e EOSEEnvelope) String() string {
|
||||
v, _ := json.Marshal(e)
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v *EOSEEnvelope) UnmarshalJSON(data []byte) error {
|
||||
r := gjson.ParseBytes(data)
|
||||
@ -242,6 +256,10 @@ func (v EOSEEnvelope) MarshalJSON() ([]byte, error) {
|
||||
type CloseEnvelope string
|
||||
|
||||
func (_ CloseEnvelope) Label() string { return "CLOSE" }
|
||||
func (c CloseEnvelope) String() string {
|
||||
v, _ := json.Marshal(c)
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v *CloseEnvelope) UnmarshalJSON(data []byte) error {
|
||||
r := gjson.ParseBytes(data)
|
||||
@ -269,6 +287,10 @@ type ClosedEnvelope struct {
|
||||
}
|
||||
|
||||
func (_ ClosedEnvelope) Label() string { return "CLOSED" }
|
||||
func (c ClosedEnvelope) String() string {
|
||||
v, _ := json.Marshal(c)
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v *ClosedEnvelope) UnmarshalJSON(data []byte) error {
|
||||
r := gjson.ParseBytes(data)
|
||||
@ -299,6 +321,10 @@ type OKEnvelope struct {
|
||||
}
|
||||
|
||||
func (_ OKEnvelope) Label() string { return "OK" }
|
||||
func (o OKEnvelope) String() string {
|
||||
v, _ := json.Marshal(o)
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v *OKEnvelope) UnmarshalJSON(data []byte) error {
|
||||
r := gjson.ParseBytes(data)
|
||||
@ -334,6 +360,10 @@ type AuthEnvelope struct {
|
||||
}
|
||||
|
||||
func (_ AuthEnvelope) Label() string { return "AUTH" }
|
||||
func (a AuthEnvelope) String() string {
|
||||
v, _ := json.Marshal(a)
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v *AuthEnvelope) UnmarshalJSON(data []byte) error {
|
||||
r := gjson.ParseBytes(data)
|
||||
|
@ -2,7 +2,6 @@ package nostr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -89,15 +88,18 @@ func TestOKEnvelopeEncodingAndDecoding(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestClosedEnvelopeEncodingAndDecoding(t *testing.T) {
|
||||
src := `["CLOSED","_","error: something went wrong"]`
|
||||
var env ClosedEnvelope
|
||||
json.Unmarshal([]byte(src), &env)
|
||||
if env.SubscriptionID != "_" {
|
||||
t.Error("failed to decode CLOSED")
|
||||
}
|
||||
|
||||
if res, _ := json.Marshal(env); string(res) != src {
|
||||
t.Errorf("failed to encode CLOSED: expected '%s', got '%s'", src, string(res))
|
||||
for _, src := range []string{
|
||||
`["CLOSED","_","error: something went wrong"]`,
|
||||
`["CLOSED",":1","auth-required: take a selfie and send it to the CIA"]`,
|
||||
} {
|
||||
var env ClosedEnvelope
|
||||
json.Unmarshal([]byte(src), &env)
|
||||
if env.SubscriptionID != "_" && env.SubscriptionID != ":1" {
|
||||
t.Error("failed to decode CLOSED")
|
||||
}
|
||||
if res, _ := json.Marshal(env); string(res) != src {
|
||||
t.Errorf("failed to encode CLOSED: expected '%s', got '%s'", src, string(res))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +131,7 @@ func TestParseMessage(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Message []byte
|
||||
ExpectedEnvelope interface{}
|
||||
ExpectedEnvelope Envelope
|
||||
}{
|
||||
{
|
||||
Name: "nil",
|
||||
@ -146,14 +148,37 @@ func TestParseMessage(t *testing.T) {
|
||||
Message: []byte("invalid, input"),
|
||||
ExpectedEnvelope: nil,
|
||||
},
|
||||
{
|
||||
Name: "CLOSED envelope",
|
||||
Message: []byte(`["CLOSED",":1","error: we are broken"]`),
|
||||
ExpectedEnvelope: &ClosedEnvelope{SubscriptionID: ":1", Reason: "error: we are broken"},
|
||||
},
|
||||
{
|
||||
Name: "AUTH envelope",
|
||||
Message: []byte(`["AUTH","bisteka"]`),
|
||||
ExpectedEnvelope: &AuthEnvelope{Challenge: ptr("bisteka")},
|
||||
},
|
||||
{
|
||||
Name: "REQ envelope",
|
||||
Message: []byte(`["REQ","million", {"kinds": [1]}, {"kinds": [30023 ], "#d": ["buteko", "batuke"]}]`),
|
||||
ExpectedEnvelope: &ReqEnvelope{SubscriptionID: "million", Filters: Filters{{Kinds: []int{1}}, {Kinds: []int{30023}, Tags: TagMap{"d": []string{"buteko", "batuke"}}}}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.Name, func(t *testing.T) {
|
||||
envelope := ParseMessage(testCase.Message)
|
||||
if !reflect.DeepEqual(testCase.ExpectedEnvelope, envelope) {
|
||||
t.Fatal("unexpected output")
|
||||
if testCase.ExpectedEnvelope == nil && envelope == nil {
|
||||
return
|
||||
}
|
||||
if testCase.ExpectedEnvelope == nil && envelope != nil {
|
||||
t.Fatalf("expected nil but got %v\n", envelope)
|
||||
}
|
||||
if testCase.ExpectedEnvelope.String() != envelope.String() {
|
||||
t.Fatalf("unexpected output:\n %s\n != %s", testCase.ExpectedEnvelope, envelope)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func ptr[S any](s S) *S { return &s }
|
||||
|
Reference in New Issue
Block a user