tinyrelayfile
tinyrelay/internal/domains/domains_test.go/

internal/domains/domains_test.go raw
1package domains
2
3import (
4 "context"
5 "encoding/json"
6 "errors"
7 "net"
8 "net/http"
9 "net/http/httptest"
10 "strings"
11 "testing"
12
13 "github.com/FelineStateMachine/tinyrelay/internal/catalog"
14)
15
16const domainOwner = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
17
18func testService(t *testing.T) (*Service, *catalog.Catalog, string) {
19 t.Helper()
20 cat, err := catalog.Open(context.Background(), t.TempDir())
21 if err != nil {
22 t.Fatal(err)
23 }
24 t.Cleanup(func() { _ = cat.Close() })
25 tenant, err := cat.Create(context.Background(), catalog.CreateOptions{Name: "relay", Owner: domainOwner})
26 if err != nil {
27 t.Fatal(err)
28 }
29 returnMust := func() *Service {
30 s, newErr := New(Config{Catalog: cat, TenantID: tenant.ID, BaseHost: "tiny.example", RelayURL: "https://tiny.example/relay", Owner: func(actor string) bool { return actor == domainOwner }, ResolveDNS: func(context.Context, string) ([]net.IP, error) { return []net.IP{net.ParseIP("203.0.113.7")}, nil }})
31 if newErr != nil {
32 t.Fatal(newErr)
33 }
34 return s
35 }
36 return returnMust(), cat, tenant.ID
37}
38
39func TestDomainManagementUsesExplicitLocalMapping(t *testing.T) {
40 s, cat, tenantID := testService(t)
41 ctx := context.Background()
42 view, err := s.Execute(ctx, domainOwner, "adddomain", raws(`"relay.alice.example"`, `null`))
43 if err != nil {
44 t.Fatal(err)
45 }
46 if view.(View).Status != "configured" || !view.(View).Ready {
47 t.Fatalf("add view = %+v", view)
48 }
49 resolved, err := cat.ResolveHost(ctx, "relay.alice.example")
50 if err != nil || resolved.ID != tenantID {
51 t.Fatalf("resolved = %+v, err=%v", resolved, err)
52 }
53 checked, err := s.Execute(ctx, domainOwner, "checkdomain", raws(`"relay.alice.example"`))
54 if err != nil || len(checked.(View).Addresses) != 1 {
55 t.Fatalf("check = %+v, err=%v", checked, err)
56 }
57 if _, err := s.Execute(ctx, "not-owner", "adddomain", raws(`"other.example"`)); err == nil {
58 t.Fatal("non-owner domain mutation succeeded")
59 }
60 if _, err := s.Execute(ctx, domainOwner, "adddomain", raws(`"*.example"`)); err == nil {
61 t.Fatal("wildcard accepted")
62 }
63 if _, err := s.Execute(ctx, domainOwner, "adddomain", raws(`"relay.tiny.example"`)); err == nil {
64 t.Fatal("base-host child accepted")
65 }
66 if err := s.Remove(ctx, "relay.alice.example"); err != nil {
67 t.Fatal(err)
68 }
69 if _, err := cat.ResolveHostMapping(ctx, "relay.alice.example"); !errors.Is(err, catalog.ErrHostMappingNotFound) {
70 t.Fatalf("removed mapping err=%v", err)
71 }
72}
73
74func TestWebAddressDiscoveryValidationAndResponse(t *testing.T) {
75 h := WebAddressHandler(AddressConfig{RelayURL: "wss://relay.example", Authorized: func(*http.Request) bool { return true }, Lookup: func(context.Context, string) (map[string]any, bool, error) {
76 return map[string]any{"ids": []string{"abc"}}, true, nil
77 }})
78 req := httptest.NewRequest(http.MethodGet, "https://relay.example/.well-known/nostr.json?path=%2Fe%2Fabc", nil)
79 resp := httptest.NewRecorder()
80 h.ServeHTTP(resp, req)
81 if resp.Code != http.StatusOK || !strings.Contains(resp.Body.String(), `"/e/abc"`) || !strings.Contains(resp.Body.String(), `wss://relay.example`) {
82 t.Fatalf("response %d %s", resp.Code, resp.Body.String())
83 }
84 bad := httptest.NewRecorder()
85 h.ServeHTTP(bad, httptest.NewRequest(http.MethodGet, "https://relay.example/.well-known/nostr.json?path=%2F..%2Fx", nil))
86 if bad.Code != http.StatusBadRequest {
87 t.Fatalf("bad path status = %d", bad.Code)
88 }
89 unauth := WebAddressHandler(AddressConfig{Authorized: func(*http.Request) bool { return false }})
90 got := httptest.NewRecorder()
91 unauth.ServeHTTP(got, httptest.NewRequest(http.MethodGet, "https://relay.example/.well-known/nostr.json?path=%2F", nil))
92 if got.Code != http.StatusUnauthorized {
93 t.Fatalf("unauthorized status = %d", got.Code)
94 }
95}
96
97func raws(values ...string) []json.RawMessage {
98 out := make([]json.RawMessage, len(values))
99 for i, value := range values {
100 out[i] = json.RawMessage(value)
101 }
102 return out
103}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs