restructure package. Change label extraction strategy.
This commit is contained in:
+77
@@ -0,0 +1,77 @@
|
|||||||
|
// Package envelope provides types and functions for working with Nostr protocol
|
||||||
|
// websocket messages. It defines the Envelope type representing a Nostr message
|
||||||
|
// and offers utilities for creating, parsing, and validating standardized message
|
||||||
|
// formats.
|
||||||
|
package envelope
|
||||||
|
|
||||||
|
// Envelope represents a Nostr websocket message.
|
||||||
|
type Envelope []byte
|
||||||
|
|
||||||
|
// GetLabel extracts the message label from an envelope.
|
||||||
|
// Returns the label as a byte slice or an error if the envelope is malformed.
|
||||||
|
func GetLabel(env Envelope) ([]byte, error) {
|
||||||
|
// begin walking byte slice
|
||||||
|
i, n := 0, len(env)
|
||||||
|
|
||||||
|
// skip whitespace before '['
|
||||||
|
for i < n && isSpace(env[i]) {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
// expect '['
|
||||||
|
if i >= n || env[i] != '[' {
|
||||||
|
return nil, ErrInvalidEnvelope
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
|
||||||
|
// skip whitespace before '"'
|
||||||
|
for i < n && isSpace(env[i]) {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
// expect '"'
|
||||||
|
if i >= n || env[i] != '"' {
|
||||||
|
return nil, ErrInvalidEnvelope
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
|
||||||
|
// scan label: [A-Z]+ terminated by '"'
|
||||||
|
start := i
|
||||||
|
for i < n && env[i] != '"' { // do until end or '"' is reached
|
||||||
|
if env[i] < 'A' || env[i] > 'Z' { // character is not [A-Z]
|
||||||
|
return nil, ErrInvalidEnvelope
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
if i == n || i == start { // a label was not found in the previous loop
|
||||||
|
return nil, ErrInvalidEnvelope
|
||||||
|
}
|
||||||
|
|
||||||
|
return env[start:i], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSpace(b byte) bool {
|
||||||
|
return b == ' ' || b == '\t' || b == '\n' || b == '\r'
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStandardLabels returns a set of standard Nostr websocket message labels
|
||||||
|
func GetStandardLabels() map[string]struct{} {
|
||||||
|
return map[string]struct{}{
|
||||||
|
"EVENT": {},
|
||||||
|
"REQ": {},
|
||||||
|
"CLOSE": {},
|
||||||
|
"CLOSED": {},
|
||||||
|
"EOSE": {},
|
||||||
|
"NOTICE": {},
|
||||||
|
"OK": {},
|
||||||
|
"AUTH": {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStandardLabel checks if the given label is a standard Nostr websocket message label
|
||||||
|
func IsStandardLabel(label string) bool {
|
||||||
|
labels := GetStandardLabels()
|
||||||
|
_, ok := labels[label]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
// Package envelope provides types and functions for working with Nostr protocol
|
|
||||||
// websocket messages. It defines the Envelope type representing a Nostr message
|
|
||||||
// and offers utilities for creating, parsing, and validating standardized message
|
|
||||||
// formats.
|
|
||||||
package envelope
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"git.wisehodl.dev/jay/go-roots-ws/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Envelope represents a Nostr websocket message.
|
|
||||||
type Envelope []byte
|
|
||||||
|
|
||||||
// GetLabel extracts the message label from an envelope.
|
|
||||||
// Returns the label as a string or an error if the envelope is malformed.
|
|
||||||
func GetLabel(env Envelope) (string, error) {
|
|
||||||
var arr []json.RawMessage
|
|
||||||
if err := json.Unmarshal(env, &arr); err != nil {
|
|
||||||
return "", fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(arr) < 1 {
|
|
||||||
return "", fmt.Errorf("%w: empty envelope", errors.InvalidEnvelope)
|
|
||||||
}
|
|
||||||
|
|
||||||
var label string
|
|
||||||
if err := json.Unmarshal(arr[0], &label); err != nil {
|
|
||||||
return "", fmt.Errorf("%w: label is not a string", errors.WrongFieldType)
|
|
||||||
}
|
|
||||||
|
|
||||||
return label, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetStandardLabels returns a set of standard Nostr websocket message labels
|
|
||||||
func GetStandardLabels() map[string]struct{} {
|
|
||||||
return map[string]struct{}{
|
|
||||||
"EVENT": {},
|
|
||||||
"REQ": {},
|
|
||||||
"CLOSE": {},
|
|
||||||
"CLOSED": {},
|
|
||||||
"EOSE": {},
|
|
||||||
"NOTICE": {},
|
|
||||||
"OK": {},
|
|
||||||
"AUTH": {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsStandardLabel checks if the given label is a standard Nostr websocket message label
|
|
||||||
func IsStandardLabel(label string) bool {
|
|
||||||
labels := GetStandardLabels()
|
|
||||||
_, ok := labels[label]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package envelope
|
package envelope
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.wisehodl.dev/jay/go-roots-ws/errors"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@@ -10,36 +9,34 @@ func TestGetLabel(t *testing.T) {
|
|||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
env Envelope
|
env Envelope
|
||||||
wantLabel string
|
wantLabel []byte
|
||||||
wantErr error
|
wantErr error
|
||||||
wantErrText string
|
wantErrText string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid envelope with EVENT label",
|
name: "valid envelope with EVENT label",
|
||||||
env: []byte(`["EVENT",{"id":"abc123"}]`),
|
env: []byte(`["EVENT",{"id":"abc123"}]`),
|
||||||
wantLabel: "EVENT",
|
wantLabel: []byte("EVENT"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid envelope with custom label",
|
name: "valid envelope with custom label",
|
||||||
env: []byte(`["TEST",{"data":"value"}]`),
|
env: []byte(`["TEST",{"data":"value"}]`),
|
||||||
wantLabel: "TEST",
|
wantLabel: []byte("TEST"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidEnvelope,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "empty array",
|
name: "empty array",
|
||||||
env: []byte(`[]`),
|
env: []byte(`[]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "empty envelope",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "label not a string",
|
name: "label not a string",
|
||||||
env: []byte(`[123,{"id":"abc123"}]`),
|
env: []byte(`[123,{"id":"abc123"}]`),
|
||||||
wantErr: errors.WrongFieldType,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "label is not a string",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// Package errors defines standard error types used throughout the roots-ws library.
|
||||||
|
package envelope
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Data Structure Errors
|
||||||
|
|
||||||
|
// ErrInvalidJSON indicates that a byte sequence could not be parsed as valid JSON.
|
||||||
|
// This is typically returned when unmarshaling fails during envelope processing.
|
||||||
|
ErrInvalidJSON = errors.New("invalid JSON")
|
||||||
|
|
||||||
|
// ErrMissingField indicates that a required field is absent from a data structure.
|
||||||
|
// This is returned when validating that all mandatory components are present.
|
||||||
|
ErrMissingField = errors.New("missing required field")
|
||||||
|
|
||||||
|
// ErrWrongFieldType indicates that a field's type does not match the expected type.
|
||||||
|
// This is returned when unmarshaling a specific value fails due to type mismatch.
|
||||||
|
ErrWrongFieldType = errors.New("wrong field type")
|
||||||
|
|
||||||
|
// Envelope Errors
|
||||||
|
|
||||||
|
// ErrInvalidEnvelope indicates that a message does not conform to the Nostr envelope structure.
|
||||||
|
// This typically occurs when an array has incorrect number of elements for its message type.
|
||||||
|
ErrInvalidEnvelope = errors.New("invalid envelope format")
|
||||||
|
|
||||||
|
// ErrWrongEnvelopeLabel indicates that an envelope's label does not match the expected type.
|
||||||
|
// This is returned when attempting to parse an envelope using a Find function that
|
||||||
|
// expects a different label than what was provided.
|
||||||
|
ErrWrongEnvelopeLabel = errors.New("wrong envelope label")
|
||||||
|
)
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// Package errors defines standard error types used throughout the roots-ws library.
|
|
||||||
package errors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Data Structure Errors
|
|
||||||
|
|
||||||
// InvalidJSON indicates that a byte sequence could not be parsed as valid JSON.
|
|
||||||
// This is typically returned when unmarshaling fails during envelope processing.
|
|
||||||
InvalidJSON = errors.New("invalid JSON")
|
|
||||||
|
|
||||||
// MissingField indicates that a required field is absent from a data structure.
|
|
||||||
// This is returned when validating that all mandatory components are present.
|
|
||||||
MissingField = errors.New("missing required field")
|
|
||||||
|
|
||||||
// WrongFieldType indicates that a field's type does not match the expected type.
|
|
||||||
// This is returned when unmarshaling a specific value fails due to type mismatch.
|
|
||||||
WrongFieldType = errors.New("wrong field type")
|
|
||||||
|
|
||||||
// Envelope Errors
|
|
||||||
|
|
||||||
// InvalidEnvelope indicates that a message does not conform to the Nostr envelope structure.
|
|
||||||
// This typically occurs when an array has incorrect number of elements for its message type.
|
|
||||||
InvalidEnvelope = errors.New("invalid envelope format")
|
|
||||||
|
|
||||||
// WrongEnvelopeLabel indicates that an envelope's label does not match the expected type.
|
|
||||||
// This is returned when attempting to parse an envelope using a Find function that
|
|
||||||
// expects a different label than what was provided.
|
|
||||||
WrongEnvelopeLabel = errors.New("wrong envelope label")
|
|
||||||
)
|
|
||||||
+13
-14
@@ -3,14 +3,13 @@ package envelope
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.wisehodl.dev/jay/go-roots-ws/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckArrayLength is a helper function that ensures the JSON array has at
|
// CheckArrayLength is a helper function that ensures the JSON array has at
|
||||||
// least the minimum length required
|
// least the minimum length required
|
||||||
func CheckArrayLength(arr []json.RawMessage, minLen int) error {
|
func CheckArrayLength(arr []json.RawMessage, minLen int) error {
|
||||||
if len(arr) < minLen {
|
if len(arr) < minLen {
|
||||||
return fmt.Errorf("%w: expected %d elements, got %d", errors.InvalidEnvelope, minLen, len(arr))
|
return fmt.Errorf("%w: expected %d elements, got %d", ErrInvalidEnvelope, minLen, len(arr))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -19,7 +18,7 @@ func CheckArrayLength(arr []json.RawMessage, minLen int) error {
|
|||||||
// matches the expected one
|
// matches the expected one
|
||||||
func CheckLabel(got, want string) error {
|
func CheckLabel(got, want string) error {
|
||||||
if got != want {
|
if got != want {
|
||||||
return fmt.Errorf("%w: expected %s, got %s", errors.WrongEnvelopeLabel, want, got)
|
return fmt.Errorf("%w: expected %s, got %s", ErrWrongEnvelopeLabel, want, got)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -28,7 +27,7 @@ func CheckLabel(got, want string) error {
|
|||||||
// provided value
|
// provided value
|
||||||
func ParseElement(element json.RawMessage, value interface{}, position string) error {
|
func ParseElement(element json.RawMessage, value interface{}, position string) error {
|
||||||
if err := json.Unmarshal(element, value); err != nil {
|
if err := json.Unmarshal(element, value); err != nil {
|
||||||
return fmt.Errorf("%w: %s is not the expected type", errors.WrongFieldType, position)
|
return fmt.Errorf("%w: %s is not the expected type", ErrWrongFieldType, position)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -38,7 +37,7 @@ func ParseElement(element json.RawMessage, value interface{}, position string) e
|
|||||||
func FindEvent(env Envelope) ([]byte, error) {
|
func FindEvent(env Envelope) ([]byte, error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err := json.Unmarshal(env, &arr); err != nil {
|
if err := json.Unmarshal(env, &arr); err != nil {
|
||||||
return nil, fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return nil, fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CheckArrayLength(arr, 2); err != nil {
|
if err := CheckArrayLength(arr, 2); err != nil {
|
||||||
@@ -62,7 +61,7 @@ func FindEvent(env Envelope) ([]byte, error) {
|
|||||||
func FindSubscriptionEvent(env Envelope) (subID string, event []byte, err error) {
|
func FindSubscriptionEvent(env Envelope) (subID string, event []byte, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", nil, fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", nil, fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 3); err != nil {
|
if err = CheckArrayLength(arr, 3); err != nil {
|
||||||
@@ -90,7 +89,7 @@ func FindSubscriptionEvent(env Envelope) (subID string, event []byte, err error)
|
|||||||
func FindOK(env Envelope) (eventID string, status bool, message string, err error) {
|
func FindOK(env Envelope) (eventID string, status bool, message string, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", false, "", fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", false, "", fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 4); err != nil {
|
if err = CheckArrayLength(arr, 4); err != nil {
|
||||||
@@ -126,7 +125,7 @@ func FindOK(env Envelope) (eventID string, status bool, message string, err erro
|
|||||||
func FindReq(env Envelope) (subID string, filters [][]byte, err error) {
|
func FindReq(env Envelope) (subID string, filters [][]byte, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", nil, fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", nil, fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 2); err != nil {
|
if err = CheckArrayLength(arr, 2); err != nil {
|
||||||
@@ -159,7 +158,7 @@ func FindReq(env Envelope) (subID string, filters [][]byte, err error) {
|
|||||||
func FindEOSE(env Envelope) (subID string, err error) {
|
func FindEOSE(env Envelope) (subID string, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 2); err != nil {
|
if err = CheckArrayLength(arr, 2); err != nil {
|
||||||
@@ -187,7 +186,7 @@ func FindEOSE(env Envelope) (subID string, err error) {
|
|||||||
func FindClose(env Envelope) (subID string, err error) {
|
func FindClose(env Envelope) (subID string, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 2); err != nil {
|
if err = CheckArrayLength(arr, 2); err != nil {
|
||||||
@@ -215,7 +214,7 @@ func FindClose(env Envelope) (subID string, err error) {
|
|||||||
func FindClosed(env Envelope) (subID string, message string, err error) {
|
func FindClosed(env Envelope) (subID string, message string, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", "", fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", "", fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 3); err != nil {
|
if err = CheckArrayLength(arr, 3); err != nil {
|
||||||
@@ -247,7 +246,7 @@ func FindClosed(env Envelope) (subID string, message string, err error) {
|
|||||||
func FindNotice(env Envelope) (message string, err error) {
|
func FindNotice(env Envelope) (message string, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 2); err != nil {
|
if err = CheckArrayLength(arr, 2); err != nil {
|
||||||
@@ -275,7 +274,7 @@ func FindNotice(env Envelope) (message string, err error) {
|
|||||||
func FindAuthChallenge(env Envelope) (challenge string, err error) {
|
func FindAuthChallenge(env Envelope) (challenge string, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return "", fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return "", fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 2); err != nil {
|
if err = CheckArrayLength(arr, 2); err != nil {
|
||||||
@@ -304,7 +303,7 @@ func FindAuthChallenge(env Envelope) (challenge string, err error) {
|
|||||||
func FindAuthResponse(env Envelope) (event []byte, err error) {
|
func FindAuthResponse(env Envelope) (event []byte, err error) {
|
||||||
var arr []json.RawMessage
|
var arr []json.RawMessage
|
||||||
if err = json.Unmarshal(env, &arr); err != nil {
|
if err = json.Unmarshal(env, &arr); err != nil {
|
||||||
return nil, fmt.Errorf("%w: %v", errors.InvalidJSON, err)
|
return nil, fmt.Errorf("%w: %v", ErrInvalidJSON, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CheckArrayLength(arr, 2); err != nil {
|
if err = CheckArrayLength(arr, 2); err != nil {
|
||||||
@@ -3,7 +3,6 @@ package envelope
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.wisehodl.dev/jay/go-roots-ws/errors"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,18 +22,18 @@ func TestFindEvent(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["REQ",{"id":"abc123","kind":1}]`),
|
env: []byte(`["REQ",{"id":"abc123","kind":1}]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected EVENT, got REQ",
|
wantErrText: "expected EVENT, got REQ",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["EVENT"]`),
|
env: []byte(`["EVENT"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 2 elements, got 1",
|
wantErrText: "expected 2 elements, got 1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -83,18 +82,18 @@ func TestFindSubscriptionEvent(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["REQ","sub1",{"id":"abc123","kind":1}]`),
|
env: []byte(`["REQ","sub1",{"id":"abc123","kind":1}]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected EVENT, got REQ",
|
wantErrText: "expected EVENT, got REQ",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["EVENT","sub1"]`),
|
env: []byte(`["EVENT","sub1"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 3 elements, got 2",
|
wantErrText: "expected 3 elements, got 2",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -154,24 +153,24 @@ func TestFindOK(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong status type",
|
name: "wrong status type",
|
||||||
env: []byte(`["OK","abc123","ok","Event accepted"]`),
|
env: []byte(`["OK","abc123","ok","Event accepted"]`),
|
||||||
wantErr: errors.WrongFieldType,
|
wantErr: ErrWrongFieldType,
|
||||||
wantErrText: "status is not the expected type",
|
wantErrText: "status is not the expected type",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT","abc123",true,"Event accepted"]`),
|
env: []byte(`["EVENT","abc123",true,"Event accepted"]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected OK, got EVENT",
|
wantErrText: "expected OK, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["OK","abc123",true]`),
|
env: []byte(`["OK","abc123",true]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 4 elements, got 3",
|
wantErrText: "expected 4 elements, got 3",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -239,18 +238,18 @@ func TestFindReq(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT","sub1",{"kinds":[1],"limit":10}]`),
|
env: []byte(`["EVENT","sub1",{"kinds":[1],"limit":10}]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected REQ, got EVENT",
|
wantErrText: "expected REQ, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["REQ"]`),
|
env: []byte(`["REQ"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 2 elements, got 1",
|
wantErrText: "expected 2 elements, got 1",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -293,18 +292,18 @@ func TestFindEOSE(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT","sub1"]`),
|
env: []byte(`["EVENT","sub1"]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected EOSE, got EVENT",
|
wantErrText: "expected EOSE, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["EOSE"]`),
|
env: []byte(`["EOSE"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 2 elements, got 1",
|
wantErrText: "expected 2 elements, got 1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -351,18 +350,18 @@ func TestFindClose(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT","sub1"]`),
|
env: []byte(`["EVENT","sub1"]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected CLOSE, got EVENT",
|
wantErrText: "expected CLOSE, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["CLOSE"]`),
|
env: []byte(`["CLOSE"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 2 elements, got 1",
|
wantErrText: "expected 2 elements, got 1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -411,18 +410,18 @@ func TestFindClosed(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT","sub1","Subscription complete"]`),
|
env: []byte(`["EVENT","sub1","Subscription complete"]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected CLOSED, got EVENT",
|
wantErrText: "expected CLOSED, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["CLOSED","sub1"]`),
|
env: []byte(`["CLOSED","sub1"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 3 elements, got 2",
|
wantErrText: "expected 3 elements, got 2",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -471,18 +470,18 @@ func TestFindNotice(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT","This is a notice"]`),
|
env: []byte(`["EVENT","This is a notice"]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected NOTICE, got EVENT",
|
wantErrText: "expected NOTICE, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["NOTICE"]`),
|
env: []byte(`["NOTICE"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 2 elements, got 1",
|
wantErrText: "expected 2 elements, got 1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -529,18 +528,18 @@ func TestFindAuthChallenge(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT","random-challenge-string"]`),
|
env: []byte(`["EVENT","random-challenge-string"]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected AUTH, got EVENT",
|
wantErrText: "expected AUTH, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["AUTH"]`),
|
env: []byte(`["AUTH"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 2 elements, got 1",
|
wantErrText: "expected 2 elements, got 1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -587,18 +586,18 @@ func TestFindAuthResponse(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "wrong label",
|
name: "wrong label",
|
||||||
env: []byte(`["EVENT",{"id":"abc123","kind":22242}]`),
|
env: []byte(`["EVENT",{"id":"abc123","kind":22242}]`),
|
||||||
wantErr: errors.WrongEnvelopeLabel,
|
wantErr: ErrWrongEnvelopeLabel,
|
||||||
wantErrText: "expected AUTH, got EVENT",
|
wantErrText: "expected AUTH, got EVENT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid json",
|
name: "invalid json",
|
||||||
env: []byte(`invalid`),
|
env: []byte(`invalid`),
|
||||||
wantErr: errors.InvalidJSON,
|
wantErr: ErrInvalidJSON,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing elements",
|
name: "missing elements",
|
||||||
env: []byte(`["AUTH"]`),
|
env: []byte(`["AUTH"]`),
|
||||||
wantErr: errors.InvalidEnvelope,
|
wantErr: ErrInvalidEnvelope,
|
||||||
wantErrText: "expected 2 elements, got 1",
|
wantErrText: "expected 2 elements, got 1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
package roots_ws
|
|
||||||
|
|
||||||
// ConnectionStatus represents the current state of a WebSocket connection.
|
|
||||||
type ConnectionStatus int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// StatusDisconnected indicates the connection is not active and no connection attempt is in progress.
|
|
||||||
StatusDisconnected ConnectionStatus = iota
|
|
||||||
|
|
||||||
// StatusConnecting indicates a connection attempt is currently in progress but not yet established.
|
|
||||||
StatusConnecting
|
|
||||||
|
|
||||||
// StatusConnected indicates the connection is active and ready for message exchange.
|
|
||||||
StatusConnected
|
|
||||||
|
|
||||||
// StatusClosing indicates the connection is in the process of shutting down gracefully.
|
|
||||||
StatusClosing
|
|
||||||
)
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package roots_ws
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestConnectionStatusConstants(t *testing.T) {
|
|
||||||
seen := make(map[ConnectionStatus]bool)
|
|
||||||
|
|
||||||
constants := []ConnectionStatus{
|
|
||||||
StatusDisconnected,
|
|
||||||
StatusConnecting,
|
|
||||||
StatusConnected,
|
|
||||||
StatusClosing,
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, status := range constants {
|
|
||||||
if seen[status] {
|
|
||||||
t.Errorf("Duplicate value found for constant at index %d: %d", i, status)
|
|
||||||
}
|
|
||||||
seen[status] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user