initial public relay build repo
ci / build (push) Successful in 2m3s
ci / image (push) Successful in 1m4s

This commit is contained in:
2026-07-24 13:11:06 -04:00
commit 294616642f
24 changed files with 2957 additions and 0 deletions
+215
View File
@@ -0,0 +1,215 @@
package federation
import (
"context"
"sync"
"testing"
"fiatjaf.com/nostr"
)
func TestParseConfig(t *testing.T) {
t.Run("empty spec disables federation", func(t *testing.T) {
cfg, warnings := ParseConfig("")
if cfg.Enabled() {
t.Fatal("expected federation disabled for empty spec")
}
if len(warnings) != 0 {
t.Fatalf("unexpected warnings: %v", warnings)
}
})
t.Run("bare url defaults to mirror all channels", func(t *testing.T) {
cfg, _ := ParseConfig("wss://a.example")
if len(cfg.Peers) != 1 {
t.Fatalf("expected 1 peer, got %d", len(cfg.Peers))
}
p := cfg.Peers[0]
if p.Mode != ModeMirror {
t.Errorf("expected mirror mode, got %s", p.Mode)
}
if !p.AllChans {
t.Error("expected AllChans=true for bare url")
}
if !p.wants("anything") {
t.Error("bare url should federate every channel")
}
})
t.Run("explicit mode and channels", func(t *testing.T) {
cfg, _ := ParseConfig("wss://a.example|ingest:general,dev")
p := cfg.Peers[0]
if p.Mode != ModeIngest {
t.Errorf("expected ingest, got %s", p.Mode)
}
if p.AllChans {
t.Error("expected scoped channels, got AllChans")
}
if !p.wants("general") || !p.wants("dev") {
t.Error("should federate listed channels")
}
if p.wants("secret") {
t.Error("should NOT federate unlisted channel")
}
})
t.Run("multiple peers separated by semicolons", func(t *testing.T) {
cfg, _ := ParseConfig("wss://a.example|mirror:general; wss://b.example|ingest:*")
if len(cfg.Peers) != 2 {
t.Fatalf("expected 2 peers, got %d", len(cfg.Peers))
}
if cfg.Peers[0].Mode != ModeMirror || cfg.Peers[1].Mode != ModeIngest {
t.Error("modes parsed incorrectly")
}
if !cfg.Peers[1].AllChans {
t.Error("ingest:* should mean all channels")
}
})
t.Run("channel names tolerate a leading #", func(t *testing.T) {
cfg, _ := ParseConfig("wss://a.example|mirror:#general")
if !cfg.Peers[0].wants("general") {
t.Error("should strip leading # from channel names")
}
})
t.Run("invalid url is skipped with a warning", func(t *testing.T) {
cfg, warnings := ParseConfig("http://not-websocket.example")
if cfg.Enabled() {
t.Error("non-ws url should be skipped")
}
if len(warnings) == 0 {
t.Error("expected a warning for invalid url")
}
})
t.Run("explicit but empty channel list is skipped", func(t *testing.T) {
cfg, warnings := ParseConfig("wss://a.example|mirror:,")
if cfg.Enabled() {
t.Error("empty channel list should skip the peer")
}
if len(warnings) == 0 {
t.Error("expected a warning for empty channel list")
}
})
t.Run("unknown mode falls back to mirror with a warning", func(t *testing.T) {
cfg, warnings := ParseConfig("wss://a.example|bogus:general")
if cfg.Peers[0].Mode != ModeMirror {
t.Error("unknown mode should fall back to mirror")
}
if len(warnings) == 0 {
t.Error("expected a warning for unknown mode")
}
})
}
func TestFederatesChannel(t *testing.T) {
cfg, _ := ParseConfig("wss://a.example|mirror:general;wss://b.example|ingest:dev")
if !cfg.FederatesChannel("general") {
t.Error("general federates via peer a")
}
if !cfg.FederatesChannel("dev") {
t.Error("dev federates via peer b")
}
if cfg.FederatesChannel("private") {
t.Error("private federates with nobody")
}
}
// TestReceiveLoopPrevention proves the loop guard: an event injected twice is
// only stored (and thus only forwardable) once, because the injector reports the
// second sight as not-newly-stored. This mirrors AddEvent's ErrDupEvent path.
func TestReceiveLoopPrevention(t *testing.T) {
seen := map[nostr.ID]bool{}
var mu sync.Mutex
injectCount := 0
storedCount := 0
inject := func(_ context.Context, evt nostr.Event) bool {
mu.Lock()
defer mu.Unlock()
injectCount++
if seen[evt.ID] {
return false // duplicate: not newly stored (the loop breaker)
}
seen[evt.ID] = true
storedCount++
return true
}
cfg, _ := ParseConfig("wss://peer.example|mirror:general")
f := NewFederator(cfg, inject)
peer := cfg.Peers[0]
sk := nostr.Generate()
evt := nostr.Event{
Kind: nostr.KindSimpleGroupChatMessage,
CreatedAt: nostr.Now(),
Content: "hello federation",
Tags: nostr.Tags{{"h", "general"}},
}
if err := evt.Sign(sk); err != nil {
t.Fatalf("sign: %v", err)
}
// Same event received twice (e.g. A→B then echoed B→A→B).
f.receive(peer, evt)
f.receive(peer, evt)
if injectCount != 2 {
t.Errorf("expected 2 inject attempts, got %d", injectCount)
}
if storedCount != 1 {
t.Errorf("loop guard failed: event stored %d times, want 1", storedCount)
}
}
// TestReceiveDropsBadSignature ensures a peer can't inject forged events.
func TestReceiveDropsBadSignature(t *testing.T) {
injected := false
inject := func(_ context.Context, _ nostr.Event) bool {
injected = true
return true
}
cfg, _ := ParseConfig("wss://peer.example|mirror:general")
f := NewFederator(cfg, inject)
// Unsigned (invalid) event tagged for a federated channel.
evt := nostr.Event{
Kind: nostr.KindSimpleGroupChatMessage,
CreatedAt: nostr.Now(),
Content: "forged",
Tags: nostr.Tags{{"h", "general"}},
}
f.receive(cfg.Peers[0], evt)
if injected {
t.Error("event with an invalid signature must not be injected")
}
}
// TestReceiveIgnoresUnfederatedChannel ensures scope is enforced on ingress.
func TestReceiveIgnoresUnfederatedChannel(t *testing.T) {
injected := false
inject := func(_ context.Context, _ nostr.Event) bool {
injected = true
return true
}
cfg, _ := ParseConfig("wss://peer.example|mirror:general")
f := NewFederator(cfg, inject)
sk := nostr.Generate()
evt := nostr.Event{
Kind: nostr.KindSimpleGroupChatMessage,
CreatedAt: nostr.Now(),
Content: "off-topic",
Tags: nostr.Tags{{"h", "other-channel"}},
}
if err := evt.Sign(sk); err != nil {
t.Fatalf("sign: %v", err)
}
f.receive(cfg.Peers[0], evt)
if injected {
t.Error("chat for an unfederated channel must not be injected")
}
}