routing_test.go raw

   1  package routing
   2  
   3  import (
   4  	"errors"
   5  	"testing"
   6  
   7  	"next.orly.dev/pkg/nostr/encoders/event"
   8  )
   9  
  10  func TestNew(t *testing.T) {
  11  	r := New()
  12  	if r == nil {
  13  		t.Fatal("New() returned nil")
  14  	}
  15  	if r.handlers == nil {
  16  		t.Fatal("handlers map is nil")
  17  	}
  18  	if r.kindChecks == nil {
  19  		t.Fatal("kindChecks slice is nil")
  20  	}
  21  }
  22  
  23  func TestResultConstructors(t *testing.T) {
  24  	// ContinueResult
  25  	r := ContinueResult()
  26  	if r.Action != Continue {
  27  		t.Error("ContinueResult should have Action=Continue")
  28  	}
  29  
  30  	// HandledResult
  31  	r = HandledResult("success")
  32  	if r.Action != Handled {
  33  		t.Error("HandledResult should have Action=Handled")
  34  	}
  35  	if r.Message != "success" {
  36  		t.Error("HandledResult should preserve message")
  37  	}
  38  
  39  	// ErrorResult
  40  	err := errors.New("test error")
  41  	r = ErrorResult(err)
  42  	if r.Action != Error {
  43  		t.Error("ErrorResult should have Action=Error")
  44  	}
  45  	if r.Error != err {
  46  		t.Error("ErrorResult should preserve error")
  47  	}
  48  }
  49  
  50  func TestDefaultRouter_Register(t *testing.T) {
  51  	r := New()
  52  
  53  	called := false
  54  	handler := func(ev *event.E, authedPubkey []byte) Result {
  55  		called = true
  56  		return HandledResult("handled")
  57  	}
  58  
  59  	r.Register(1, handler)
  60  
  61  	ev := event.New()
  62  	ev.Kind = 1
  63  
  64  	result := r.Route(ev, nil)
  65  	if !called {
  66  		t.Error("handler should have been called")
  67  	}
  68  	if result.Action != Handled {
  69  		t.Error("result should be Handled")
  70  	}
  71  }
  72  
  73  func TestDefaultRouter_RegisterKindCheck(t *testing.T) {
  74  	r := New()
  75  
  76  	called := false
  77  	handler := func(ev *event.E, authedPubkey []byte) Result {
  78  		called = true
  79  		return HandledResult("ephemeral")
  80  	}
  81  
  82  	// Register handler for ephemeral events (20000-29999)
  83  	r.RegisterKindCheck("ephemeral", func(k uint16) bool {
  84  		return k >= 20000 && k < 30000
  85  	}, handler)
  86  
  87  	ev := event.New()
  88  	ev.Kind = 20001
  89  
  90  	result := r.Route(ev, nil)
  91  	if !called {
  92  		t.Error("kind check handler should have been called")
  93  	}
  94  	if result.Action != Handled {
  95  		t.Error("result should be Handled")
  96  	}
  97  }
  98  
  99  func TestDefaultRouter_NoMatch(t *testing.T) {
 100  	r := New()
 101  
 102  	// Register handler for kind 1
 103  	r.Register(1, func(ev *event.E, authedPubkey []byte) Result {
 104  		return HandledResult("kind 1")
 105  	})
 106  
 107  	ev := event.New()
 108  	ev.Kind = 2 // Different kind
 109  
 110  	result := r.Route(ev, nil)
 111  	if result.Action != Continue {
 112  		t.Error("unmatched kind should return Continue")
 113  	}
 114  }
 115  
 116  func TestDefaultRouter_ExactMatchPriority(t *testing.T) {
 117  	r := New()
 118  
 119  	exactCalled := false
 120  	checkCalled := false
 121  
 122  	// Register exact match for kind 20001
 123  	r.Register(20001, func(ev *event.E, authedPubkey []byte) Result {
 124  		exactCalled = true
 125  		return HandledResult("exact")
 126  	})
 127  
 128  	// Register kind check for ephemeral (also matches 20001)
 129  	r.RegisterKindCheck("ephemeral", func(k uint16) bool {
 130  		return k >= 20000 && k < 30000
 131  	}, func(ev *event.E, authedPubkey []byte) Result {
 132  		checkCalled = true
 133  		return HandledResult("check")
 134  	})
 135  
 136  	ev := event.New()
 137  	ev.Kind = 20001
 138  
 139  	result := r.Route(ev, nil)
 140  	if !exactCalled {
 141  		t.Error("exact match should be called")
 142  	}
 143  	if checkCalled {
 144  		t.Error("kind check should not be called when exact match exists")
 145  	}
 146  	if result.Message != "exact" {
 147  		t.Errorf("expected 'exact', got '%s'", result.Message)
 148  	}
 149  }
 150  
 151  func TestDefaultRouter_HasHandler(t *testing.T) {
 152  	r := New()
 153  
 154  	// Initially no handlers
 155  	if r.HasHandler(1) {
 156  		t.Error("should not have handler for kind 1 yet")
 157  	}
 158  
 159  	// Register exact handler
 160  	r.Register(1, func(ev *event.E, authedPubkey []byte) Result {
 161  		return HandledResult("")
 162  	})
 163  
 164  	if !r.HasHandler(1) {
 165  		t.Error("should have handler for kind 1")
 166  	}
 167  
 168  	// Register kind check for ephemeral
 169  	r.RegisterKindCheck("ephemeral", func(k uint16) bool {
 170  		return k >= 20000 && k < 30000
 171  	}, func(ev *event.E, authedPubkey []byte) Result {
 172  		return HandledResult("")
 173  	})
 174  
 175  	if !r.HasHandler(20001) {
 176  		t.Error("should have handler for ephemeral kind 20001")
 177  	}
 178  
 179  	if r.HasHandler(19999) {
 180  		t.Error("should not have handler for kind 19999")
 181  	}
 182  }
 183  
 184  func TestDefaultRouter_PassesPubkey(t *testing.T) {
 185  	r := New()
 186  
 187  	var receivedPubkey []byte
 188  	r.Register(1, func(ev *event.E, authedPubkey []byte) Result {
 189  		receivedPubkey = authedPubkey
 190  		return HandledResult("")
 191  	})
 192  
 193  	testPubkey := []byte("testpubkey12345")
 194  	ev := event.New()
 195  	ev.Kind = 1
 196  
 197  	r.Route(ev, testPubkey)
 198  
 199  	if string(receivedPubkey) != string(testPubkey) {
 200  		t.Error("handler should receive the authed pubkey")
 201  	}
 202  }
 203  
 204  func TestDefaultRouter_MultipleKindChecks(t *testing.T) {
 205  	r := New()
 206  
 207  	firstCalled := false
 208  	secondCalled := false
 209  
 210  	// First check matches 10000-19999
 211  	r.RegisterKindCheck("first", func(k uint16) bool {
 212  		return k >= 10000 && k < 20000
 213  	}, func(ev *event.E, authedPubkey []byte) Result {
 214  		firstCalled = true
 215  		return HandledResult("first")
 216  	})
 217  
 218  	// Second check matches 15000-25000 (overlaps)
 219  	r.RegisterKindCheck("second", func(k uint16) bool {
 220  		return k >= 15000 && k < 25000
 221  	}, func(ev *event.E, authedPubkey []byte) Result {
 222  		secondCalled = true
 223  		return HandledResult("second")
 224  	})
 225  
 226  	// Kind 15000 matches both - first registered wins
 227  	ev := event.New()
 228  	ev.Kind = 15000
 229  
 230  	result := r.Route(ev, nil)
 231  	if !firstCalled {
 232  		t.Error("first check should be called")
 233  	}
 234  	if secondCalled {
 235  		t.Error("second check should not be called")
 236  	}
 237  	if result.Message != "first" {
 238  		t.Errorf("expected 'first', got '%s'", result.Message)
 239  	}
 240  }
 241