Files
next.orly.dev/pkg/protocol/nwc/nwc_test.go

177 lines
4.3 KiB
Go

package nwc_test
import (
"context"
"testing"
"time"
"next.orly.dev/pkg/protocol/nwc"
"next.orly.dev/pkg/protocol/ws"
)
func TestNWCClientCreation(t *testing.T) {
uri := "nostr+walletconnect://816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b?relay=wss://relay.getalby.com/v1&secret=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
c, err := nwc.NewClient(uri)
if err != nil {
t.Fatal(err)
}
if c == nil {
t.Fatal("client should not be nil")
}
}
func TestNWCInvalidURI(t *testing.T) {
invalidURIs := []string{
"invalid://test",
"nostr+walletconnect://",
"nostr+walletconnect://invalid",
"nostr+walletconnect://816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b",
"nostr+walletconnect://816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b?relay=invalid",
}
for _, uri := range invalidURIs {
_, err := nwc.NewClient(uri)
if err == nil {
t.Fatalf("expected error for invalid URI: %s", uri)
}
}
}
func TestNWCRelayConnection(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), 5*time.Second)
defer cancel()
rc, err := ws.RelayConnect(ctx, "wss://relay.getalby.com/v1")
if err != nil {
t.Fatalf("relay connection failed: %v", err)
}
defer rc.Close()
t.Log("relay connection successful")
}
func TestNWCRequestTimeout(t *testing.T) {
uri := "nostr+walletconnect://816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b?relay=wss://relay.getalby.com/v1&secret=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
c, err := nwc.NewClient(uri)
if err != nil {
t.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.TODO(), 2*time.Second)
defer cancel()
var r map[string]any
err = c.Request(ctx, "get_info", nil, &r)
if err == nil {
t.Log("wallet responded")
return
}
expectedErrors := []string{
"no response from wallet",
"subscription closed",
"timeout waiting for response",
"context deadline exceeded",
}
errorFound := false
for _, expected := range expectedErrors {
if contains(err.Error(), expected) {
errorFound = true
break
}
}
if !errorFound {
t.Fatalf("unexpected error: %v", err)
}
t.Logf("proper timeout handling: %v", err)
}
func contains(s, substr string) bool {
return len(s) >= len(substr) && (s == substr || (len(s) > len(substr) &&
(s[:len(substr)] == substr || s[len(s)-len(substr):] == substr ||
findInString(s, substr))))
}
func findInString(s, substr string) bool {
for i := 0; i <= len(s)-len(substr); i++ {
if s[i:i+len(substr)] == substr {
return true
}
}
return false
}
func TestNWCEncryption(t *testing.T) {
uri := "nostr+walletconnect://816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b?relay=wss://relay.getalby.com/v1&secret=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
c, err := nwc.NewClient(uri)
if err != nil {
t.Fatal(err)
}
// We can't directly access private fields, but we can test the client creation
// check conversation key generation
if c == nil {
t.Fatal("client creation should succeed with valid URI")
}
// Test passed
}
func TestNWCEventFormat(t *testing.T) {
uri := "nostr+walletconnect://816fd7f1d000ae81a3da251c91866fc47f4bcd6ce36921e6d46773c32f1d548b?relay=wss://relay.getalby.com/v1&secret=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
c, err := nwc.NewClient(uri)
if err != nil {
t.Fatal(err)
}
// Test client creation
// The Request method will create proper NWC events with:
// - Kind 23194 for requests
// - Proper encryption tag
// - Signed with client key
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
defer cancel()
var r map[string]any
err = c.Request(ctx, "get_info", nil, &r)
// We expect this to fail due to inactive connection, but it should fail
// after creating and sending NWC event
if err == nil {
t.Log("wallet responded")
return
}
// Verify it failed for the right reason (connection/response issue, not formatting)
validFailures := []string{
"subscription closed",
"no response from wallet",
"context deadline exceeded",
"timeout waiting for response",
}
validFailure := false
for _, failure := range validFailures {
if contains(err.Error(), failure) {
validFailure = true
break
}
}
if !validFailure {
t.Fatalf("unexpected error type (suggests formatting issue): %v", err)
}
// Test passed
}