tinyrelayfile
tinyrelay/internal/daemon/creation_test.go/

internal/daemon/creation_test.go raw
1package daemon
2
3import (
4 "context"
5 "strings"
6 "testing"
7
8 "github.com/FelineStateMachine/tinyrelay/internal/catalog"
9 "github.com/FelineStateMachine/tinyrelay/internal/storage"
10)
11
12const creationOwner = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
13
14func TestAfterCreateSeedsRecurringSourceBeforeReady(t *testing.T) {
15 ctx := context.Background()
16 app, err := New(ctx, Config{DataDir: t.TempDir(), DefaultTenant: "main"})
17 if err != nil {
18 t.Fatal(err)
19 }
20 defer app.Close(ctx)
21 meta, err := app.Catalog().Create(ctx, catalog.CreateOptions{Name: "search", Owner: creationOwner, Template: "search", Source: "wss://source.example"})
22 if err != nil {
23 t.Fatal(err)
24 }
25 if err := app.AfterCreate(ctx, meta, CreateOptions{}); err != nil {
26 t.Fatal(err)
27 }
28 var state, payload string
29 store, err := openCreationStore(ctx, meta)
30 if err != nil {
31 t.Fatal(err)
32 }
33 defer store.Close()
34 if err := store.DB().QueryRow("SELECT state,payload FROM replication_jobs WHERE id=?", "source-"+meta.ID).Scan(&state, &payload); err != nil {
35 t.Fatal(err)
36 }
37 if state != "pending" || payload == "" {
38 t.Fatalf("source job = %q %q", state, payload)
39 }
40 if err := app.Catalog().MarkReady(ctx, meta.ID); err != nil {
41 t.Fatal(err)
42 }
43}
44
45func TestAfterCreateRequiresSearchSourceAndRecoveryLeavesItCreating(t *testing.T) {
46 ctx := context.Background()
47 app, err := New(ctx, Config{DataDir: t.TempDir(), DefaultTenant: "main"})
48 if err != nil {
49 t.Fatal(err)
50 }
51 defer app.Close(ctx)
52 meta, err := app.Catalog().Create(ctx, catalog.CreateOptions{Name: "search", Owner: creationOwner, Template: "search"})
53 if err != nil {
54 t.Fatal(err)
55 }
56 if err := app.RecoverCreating(ctx); err == nil {
57 t.Fatal("recovery accepted missing required source")
58 }
59 got, err := app.Catalog().GetByID(ctx, meta.ID)
60 if err != nil {
61 t.Fatal(err)
62 }
63 if got.Status != catalog.StatusCreating {
64 t.Fatalf("status = %q, want creating", got.Status)
65 }
66}
67
68func TestInboxSourceFollowsOwnerWithHourlyPull(t *testing.T) {
69 ctx := context.Background()
70 app, err := New(ctx, Config{DataDir: t.TempDir(), DefaultTenant: "main"})
71 if err != nil {
72 t.Fatal(err)
73 }
74 defer app.Close(ctx)
75 meta, err := app.Catalog().Create(ctx, catalog.CreateOptions{Name: "inbox", Owner: creationOwner, Template: "inbox", Source: "https://upstream.example/relay"})
76 if err != nil {
77 t.Fatal(err)
78 }
79 if err := app.AfterCreate(ctx, meta, CreateOptions{}); err != nil {
80 t.Fatal(err)
81 }
82 store, err := openCreationStore(ctx, meta)
83 if err != nil {
84 t.Fatal(err)
85 }
86 defer store.Close()
87 var payload string
88 if err := store.DB().QueryRow("SELECT payload FROM replication_jobs WHERE id=?", "source-"+meta.ID).Scan(&payload); err != nil {
89 t.Fatal(err)
90 }
91 if !strings.Contains(payload, `"every":1`) || !strings.Contains(payload, "#p") || !strings.Contains(payload, creationOwner) {
92 t.Fatalf("inbox source job payload = %s", payload)
93 }
94 if strings.Contains(payload, "https://") || !strings.Contains(payload, "wss://upstream.example/relay") {
95 t.Fatalf("inbox source URL was not converted: %s", payload)
96 }
97}
98
99func TestInboxWithoutSourceSeedsDormantOwnerReadRelayDiscovery(t *testing.T) {
100 ctx := context.Background()
101 app, err := New(ctx, Config{DataDir: t.TempDir(), DefaultTenant: "main"})
102 if err != nil {
103 t.Fatal(err)
104 }
105 defer app.Close(ctx)
106 meta, err := app.Catalog().Create(ctx, catalog.CreateOptions{Name: "inbox", Owner: creationOwner, Template: "inbox"})
107 if err != nil {
108 t.Fatal(err)
109 }
110 if err := app.AfterCreate(ctx, meta, CreateOptions{}); err != nil {
111 t.Fatal(err)
112 }
113 store, err := openCreationStore(ctx, meta)
114 if err != nil {
115 t.Fatal(err)
116 }
117 defer store.Close()
118 var payload string
119 if err := store.DB().QueryRow("SELECT payload FROM replication_jobs WHERE id=?", "source-"+meta.ID).Scan(&payload); err != nil {
120 t.Fatal(err)
121 }
122 if !strings.Contains(payload, `"discoverPubKey":"`+creationOwner+`"`) || !strings.Contains(payload, `"every":1`) || strings.Contains(payload, `"relays"`) {
123 t.Fatalf("inbox discovery job payload = %s", payload)
124 }
125}
126
127func TestInboxWithoutSourceJobUsesRuntimeDiscoverySeeds(t *testing.T) {
128 ctx := context.Background()
129 app, err := New(ctx, Config{DataDir: t.TempDir(), DefaultTenant: "main"})
130 if err != nil {
131 t.Fatal(err)
132 }
133 defer app.Close(ctx)
134 meta, err := app.Catalog().Create(ctx, catalog.CreateOptions{Name: "inbox", Owner: creationOwner, Template: "inbox"})
135 if err != nil {
136 t.Fatal(err)
137 }
138 if err := app.AfterCreate(ctx, meta, CreateOptions{}); err != nil {
139 t.Fatal(err)
140 }
141 store, err := openCreationStore(ctx, meta)
142 if err != nil {
143 t.Fatal(err)
144 }
145 defer store.Close()
146 var state, payload string
147 if err := store.DB().QueryRow("SELECT state,payload FROM replication_jobs WHERE id=?", "source-"+meta.ID).Scan(&state, &payload); err != nil {
148 t.Fatal(err)
149 }
150 if state != "pending" || !strings.Contains(payload, `"discoverPubKey":"`+creationOwner+`"`) {
151 t.Fatalf("runtime discovery job = %q %s", state, payload)
152 }
153}
154
155func openCreationStore(ctx context.Context, meta catalog.Tenant) (*storage.Store, error) {
156 return storage.Open(ctx, meta.Paths.Database)
157}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

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

Refs