mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-03-17 13:22:56 +01:00
200 lines
12 KiB
Go
200 lines
12 KiB
Go
//go:build sonic
|
|
|
|
package nostr
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestParseMessage(t *testing.T) {
|
|
testCases := []struct {
|
|
Name string
|
|
Message string
|
|
ExpectedEnvelope Envelope
|
|
}{
|
|
{
|
|
Name: "nil",
|
|
Message: "",
|
|
ExpectedEnvelope: nil,
|
|
},
|
|
{
|
|
Name: "invalid string",
|
|
Message: "invalid input",
|
|
ExpectedEnvelope: nil,
|
|
},
|
|
{
|
|
Name: "invalid string with a comma",
|
|
Message: "invalid, input",
|
|
ExpectedEnvelope: nil,
|
|
},
|
|
{
|
|
Name: "EVENT envelope with subscription id",
|
|
Message: `["EVENT","_",{"kind":1,"id":"dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962","pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1644271588,"tags":[],"content":"now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?","sig":"230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}]`,
|
|
ExpectedEnvelope: &EventEnvelope{SubscriptionID: ptr("_"), Event: Event{Kind: 1, ID: "dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962", PubKey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", CreatedAt: 1644271588, Tags: Tags{}, Content: "now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?", Sig: "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}},
|
|
},
|
|
{
|
|
Name: "EVENT envelope without subscription id",
|
|
Message: `["EVENT",{"kind":1,"id":"dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962","pubkey":"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d","created_at":1644271588,"tags":[],"content":"now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?","sig":"230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}]`,
|
|
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 1, ID: "dc90c95f09947507c1044e8f48bcf6350aa6bff1507dd4acfc755b9239b5c962", PubKey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", CreatedAt: 1644271588, Tags: Tags{}, Content: "now that https://blueskyweb.org/blog/2-7-2022-overview was announced we can stop working on nostr?", Sig: "230e9d8f0ddaf7eb70b5f7741ccfa37e87a455c9a469282e3464e2052d3192cd63a167e196e381ef9d7e69e9ea43af2443b839974dc85d8aaab9efe1d9296524"}},
|
|
},
|
|
{
|
|
Name: "EVENT envelope with tags",
|
|
Message: `["EVENT",{"kind":3,"id":"9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2","pubkey":"373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7","created_at":1644844224,"tags":[["p","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"],["e","75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"],["p","46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"]],"content":"{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}","sig":"811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}]`,
|
|
ExpectedEnvelope: &EventEnvelope{Event: Event{Kind: 3, ID: "9e662bdd7d8abc40b5b15ee1ff5e9320efc87e9274d8d440c58e6eed2dddfbe2", PubKey: "373ebe3d45ec91977296a178d9f19f326c70631d2a1b0bbba5c5ecc2eb53b9e7", CreatedAt: 1644844224, Tags: Tags{Tag{"p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"}, Tag{"e", "75fc5ac2487363293bd27fb0d14fb966477d0f1dbc6361d37806a6a740eda91e"}, Tag{"p", "46d0dfd3a724a302ca9175163bdf788f3606b3fd1bb12d5fe055d1e418cb60ea"}}, Content: "{\"wss://nostr-pub.wellorder.net\":{\"read\":true,\"write\":true},\"wss://nostr.bitcoiner.social\":{\"read\":false,\"write\":true},\"wss://expensive-relay.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relayer.fiatjaf.com\":{\"read\":true,\"write\":true},\"wss://relay.bitid.nz\":{\"read\":true,\"write\":true},\"wss://nostr.rocks\":{\"read\":true,\"write\":true}}", Sig: "811355d3484d375df47581cb5d66bed05002c2978894098304f20b595e571b7e01b2efd906c5650080ffe49cf1c62b36715698e9d88b9e8be43029a2f3fa66be"}},
|
|
},
|
|
{
|
|
Name: "NOTICE envelope",
|
|
Message: `["NOTICE","kjasbdlasvdluiasvd\"kjasbdksab\\d"]`,
|
|
ExpectedEnvelope: ptr(NoticeEnvelope("kjasbdlasvdluiasvd\"kjasbdksab\\d")),
|
|
},
|
|
{
|
|
Name: "EOSE envelope",
|
|
Message: `["EOSE","kjasbdlasvdluiasvd\"kjasbdksab\\d"]`,
|
|
ExpectedEnvelope: ptr(EOSEEnvelope("kjasbdlasvdluiasvd\"kjasbdksab\\d")),
|
|
},
|
|
{
|
|
Name: "COUNT envelope",
|
|
Message: `["COUNT","z",{"count":12}]`,
|
|
ExpectedEnvelope: &CountEnvelope{SubscriptionID: "z", Count: ptr(int64(12))},
|
|
},
|
|
{
|
|
Name: "COUNT envelope with HLL",
|
|
Message: `["COUNT","sub1",{"count":42, "hll": "0100000101000000000000040000000001020000000002000000000200000003000002040000000101020001010000000000000007000004010000000200040000020400000000000102000002000004010000010000000301000102030002000301000300010000070000000001000004000102010000000400010002000000000103000100010001000001040100020001000000000000010000020000000000030100000001000400010000000000000901010100000000040000000b030000010100010000010000010000000003000000000000010003000100020000000000010000010100000100000104000200030001000300000001000101000102"}]`,
|
|
ExpectedEnvelope: &CountEnvelope{SubscriptionID: "sub1", Count: ptr(int64(42)), HyperLogLog: []byte{1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 2, 4, 0, 0, 0, 1, 1, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 4, 1, 0, 0, 0, 2, 0, 4, 0, 0, 2, 4, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 4, 1, 0, 0, 1, 0, 0, 0, 3, 1, 0, 1, 2, 3, 0, 2, 0, 3, 1, 0, 3, 0, 1, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 4, 0, 1, 2, 1, 0, 0, 0, 4, 0, 1, 0, 2, 0, 0, 0, 0, 1, 3, 0, 1, 0, 1, 0, 1, 0, 0, 1, 4, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 9, 1, 1, 1, 0, 0, 0, 0, 4, 0, 0, 0, 11, 3, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 4, 0, 2, 0, 3, 0, 1, 0, 3, 0, 0, 0, 1, 0, 1, 1, 0, 1, 2}},
|
|
},
|
|
{
|
|
Name: "OK envelope success",
|
|
Message: `["OK","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa",true,""]`,
|
|
ExpectedEnvelope: &OKEnvelope{EventID: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa", OK: true, Reason: ""},
|
|
},
|
|
{
|
|
Name: "OK envelope failure",
|
|
Message: `["OK","3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa",false,"error: could not connect to the database"]`,
|
|
ExpectedEnvelope: &OKEnvelope{EventID: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefaaaaa", OK: false, Reason: "error: could not connect to the database"},
|
|
},
|
|
{
|
|
Name: "CLOSED envelope with underscore",
|
|
Message: `["CLOSED","_","error: something went wrong"]`,
|
|
ExpectedEnvelope: &ClosedEnvelope{SubscriptionID: "_", Reason: "error: something went wrong"},
|
|
},
|
|
{
|
|
Name: "CLOSED envelope with colon",
|
|
Message: `["CLOSED",":1","auth-required: take a selfie and send it to the CIA"]`,
|
|
ExpectedEnvelope: &ClosedEnvelope{SubscriptionID: ":1", Reason: "auth-required: take a selfie and send it to the CIA"},
|
|
},
|
|
{
|
|
Name: "AUTH envelope with challenge",
|
|
Message: `["AUTH","kjsabdlasb aslkd kasndkad \"as.kdnbskadb"]`,
|
|
ExpectedEnvelope: &AuthEnvelope{Challenge: ptr("kjsabdlasb aslkd kasndkad \"as.kdnbskadb")},
|
|
},
|
|
{
|
|
Name: "AUTH envelope with event",
|
|
Message: `["AUTH",{"kind":1,"id":"ae1fc7154296569d87ca4663f6bdf448c217d1590d28c85d158557b8b43b4d69","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1683660344,"tags":[],"content":"hello world","sig":"94e10947814b1ebe38af42300ecd90c7642763896c4f69506ae97bfdf54eec3c0c21df96b7d95daa74ff3d414b1d758ee95fc258125deebc31df0c6ba9396a51"}]`,
|
|
ExpectedEnvelope: &AuthEnvelope{Event: Event{Kind: 1, ID: "ae1fc7154296569d87ca4663f6bdf448c217d1590d28c85d158557b8b43b4d69", PubKey: "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", CreatedAt: 1683660344, Tags: Tags{}, Content: "hello world", Sig: "94e10947814b1ebe38af42300ecd90c7642763896c4f69506ae97bfdf54eec3c0c21df96b7d95daa74ff3d414b1d758ee95fc258125deebc31df0c6ba9396a51"}},
|
|
},
|
|
{
|
|
Name: "REQ envelope",
|
|
Message: `["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"}}}}},
|
|
},
|
|
{
|
|
Name: "CLOSE envelope",
|
|
Message: `["CLOSE","subscription123"]`,
|
|
ExpectedEnvelope: ptr(CloseEnvelope("subscription123")),
|
|
},
|
|
{
|
|
Name: "AUTH envelope from nak 23gmt bug",
|
|
Message: `["AUTH","c45b2b06ad92e28a"]`,
|
|
ExpectedEnvelope: &AuthEnvelope{Challenge: ptr("c45b2b06ad92e28a")},
|
|
},
|
|
{
|
|
Name: "REQ from jumble",
|
|
Message: `["REQ","sub:1",{"kinds":[1,6],"limit":100}]`,
|
|
ExpectedEnvelope: &ReqEnvelope{SubscriptionID: "sub:1", Filters: Filters{{Kinds: []int{1, 6}, Limit: 100}}},
|
|
},
|
|
}
|
|
|
|
t.Run("standard", func(t *testing.T) {
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.Name, func(t *testing.T) {
|
|
envelope := ParseMessage(testCase.Message)
|
|
if testCase.ExpectedEnvelope == nil && envelope == nil {
|
|
return
|
|
}
|
|
|
|
if testCase.ExpectedEnvelope == nil {
|
|
require.Nil(t, envelope, "expected nil but got %v", envelope)
|
|
return
|
|
}
|
|
|
|
require.NotNil(t, envelope, "expected non-nil envelope but got nil")
|
|
require.Equal(t, testCase.ExpectedEnvelope.String(), envelope.String())
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("sonic", func(t *testing.T) {
|
|
smp := NewSonicMessageParser()
|
|
|
|
for _, testCase := range testCases {
|
|
t.Run(testCase.Name, func(t *testing.T) {
|
|
envelope, err := smp.ParseMessage(testCase.Message)
|
|
|
|
if testCase.ExpectedEnvelope == nil && envelope == nil {
|
|
return
|
|
}
|
|
|
|
if testCase.ExpectedEnvelope == nil {
|
|
require.Nil(t, envelope, "expected nil but got %v", envelope)
|
|
return
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, envelope, "expected non-nil envelope but got nil")
|
|
require.Equal(t, testCase.ExpectedEnvelope, envelope)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestParseMessagesFromFile(t *testing.T) {
|
|
file, err := os.Open("testdata/messages.jsonl")
|
|
if err != nil {
|
|
t.Skipf("Skipping test because testdata/messages.jsonl could not be opened: %v", err)
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
smp := NewSonicMessageParser()
|
|
lineNum := 0
|
|
|
|
for scanner.Scan() {
|
|
lineNum++
|
|
line := scanner.Bytes()
|
|
if len(line) == 0 {
|
|
continue
|
|
}
|
|
|
|
standardEnvelope := ParseMessage(string(line))
|
|
sonicEnvelope, err := smp.ParseMessage(string(line))
|
|
|
|
if standardEnvelope == nil {
|
|
require.Nil(t, sonicEnvelope, "line %d: standard parser returned nil but sonic parser didn't", lineNum)
|
|
continue
|
|
}
|
|
|
|
require.NoError(t, err, "line %d: sonic parser returned error", lineNum)
|
|
require.NotNil(t, sonicEnvelope, "line %d: standard parser returned non-nil but sonic parser returned nil", lineNum)
|
|
|
|
require.Equal(t, standardEnvelope, sonicEnvelope,
|
|
"line %d: parsers returned different results", lineNum)
|
|
}
|
|
|
|
require.NoError(t, scanner.Err(), "error reading file")
|
|
}
|