tinyrelayfile
tinyrelay/internal/daemon/ux_contract_test.go/

internal/daemon/ux_contract_test.go raw
1package daemon
2
3import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "net/http"
8 "net/http/httptest"
9 "strings"
10 "testing"
11)
12
13// These are the exact argument shapes emitted by the guided Sync forms. The
14// test is deliberately service-level so it catches UI/backend drift without
15// depending on template markup.
16func TestGuidedSyncArgumentContracts(t *testing.T) {
17 ctx := context.Background()
18 _, tenant := testTenant(t)
19 filter := json.RawMessage(`{"kinds":[1],"limit":10}`)
20 if _, err := tenant.replication.ExecuteRaw(ctx, "pullfrom", []json.RawMessage{json.RawMessage(`"https://relay.example"`), filter}); err != nil {
21 t.Fatalf("pullfrom guided args: %v", err)
22 }
23 if _, err := tenant.replication.ExecuteRaw(ctx, "backfill", []json.RawMessage{json.RawMessage(`{"relays":["https://relay.example"]}`)}); err != nil {
24 t.Fatalf("backfill guided args: %v", err)
25 }
26 if _, err := tenant.community.Execute(ctx, tenant.Policy().Owner, "createinvite", []json.RawMessage{json.RawMessage(`259200`), json.RawMessage(`1`), json.RawMessage(`note`)}); err != nil {
27 t.Fatalf("createinvite guided args: %v", err)
28 }
29 if _, err := tenant.community.Execute(ctx, tenant.Policy().Owner, "setmember", []json.RawMessage{json.RawMessage(`"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"`), json.RawMessage(`{"name":"reader","note":"hello"}`)}); err != nil {
30 t.Fatalf("setmember guided args: %v", err)
31 }
32}
33
34func TestSignedManagementJourneys(t *testing.T) {
35 ctx := context.Background()
36 app, tenant := testTenant(t)
37 owner := tenant.Policy().Owner
38 call := func(method string, params ...any) map[string]any {
39 t.Helper()
40 rawParams := make([]json.RawMessage, len(params))
41 for i, value := range params {
42 raw, err := json.Marshal(value)
43 if err != nil {
44 t.Fatal(err)
45 }
46 rawParams[i] = raw
47 }
48 body, err := json.Marshal(map[string]any{"method": method, "params": rawParams})
49 if err != nil {
50 t.Fatal(err)
51 }
52 req := httptest.NewRequest(http.MethodPost, "http://relay.test/", bytes.NewReader(body))
53 req.Header.Set("Content-Type", "application/nostr+json+rpc")
54 signRequest(t, req, string(body))
55 res := httptest.NewRecorder()
56 tenant.ServeHTTP(res, req)
57 if res.Code != http.StatusOK {
58 t.Fatalf("%s status=%d body=%s", method, res.Code, res.Body.String())
59 }
60 var response map[string]any
61 if err := json.Unmarshal(res.Body.Bytes(), &response); err != nil {
62 t.Fatal(err)
63 }
64 return response
65 }
66 invite := call("createinvite", 3600, 1, "guided")
67 if invite["result"] == nil {
68 t.Fatal("createinvite returned no result")
69 }
70 call("listinvites")
71 member := strings.Repeat("2", 64)
72 call("setmember", member, map[string]any{"name": "reader", "note": "guided"})
73 call("banpubkey", member, "test")
74 call("allowpubkey", member, "restored")
75 call("blockip", "192.0.2.1", "test")
76 call("unblockip", "192.0.2.1")
77 call("setpolicy", map[string]any{"description": "guided"})
78 call("changerelayname", "guided relay")
79 call("changerelaydescription", "guided description")
80 call("publishview", "articles")
81 call("exportconfig")
82 call("forkrelay", map[string]any{"name": "guided-fork", "owner": owner, "people": true})
83 call("removemember", member)
84
85 // Deletion has its own tenant so it cannot invalidate the remaining journey.
86 meta, err := app.Create(ctx, CreateOptions{Name: "guided-delete", Owner: owner, Template: "default"})
87 if err != nil {
88 t.Fatal(err)
89 }
90 deleteTenant, err := app.tenant(ctx, meta, "http://relay.test/r/guided-delete")
91 if err != nil {
92 t.Fatal(err)
93 }
94 deleteBody, _ := json.Marshal(map[string]any{"method": "deleterelay", "params": []json.RawMessage{json.RawMessage(`"guided-delete"`)}})
95 deleteReq := httptest.NewRequest(http.MethodPost, "http://relay.test/", bytes.NewReader(deleteBody))
96 deleteReq.Header.Set("Content-Type", "application/nostr+json+rpc")
97 signRequest(t, deleteReq, string(deleteBody))
98 deleteRes := httptest.NewRecorder()
99 deleteTenant.ServeHTTP(deleteRes, deleteReq)
100 if deleteRes.Code != http.StatusOK {
101 t.Fatalf("deleterelay status=%d body=%s", deleteRes.Code, deleteRes.Body.String())
102 }
103}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

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

Refs