tinyrelayfile
tinyrelay/tinygit/server_test.go/

tinygit/server_test.go raw
1package tinygit_test
2
3import (
4 "bytes"
5 "context"
6 "encoding/json"
7 "net/http"
8 "net/http/httptest"
9 "strings"
10 "testing"
11
12 "github.com/FelineStateMachine/tinyrelay/internal/event"
13 "github.com/FelineStateMachine/tinyrelay/tinygit"
14)
15
16func signedAnnouncement(t *testing.T, secret string, tags ...[]string) tinygit.Event {
17 t.Helper()
18 e := tinygit.Event{Kind: 30617, CreatedAt: 100, Tags: append([][]string{{"d", "demo"}}, tags...)}
19 if err := event.Sign(&e, secret); err != nil {
20 t.Fatal(err)
21 }
22 return e
23}
24
25func postEvent(t *testing.T, s http.Handler, e tinygit.Event) *httptest.ResponseRecorder {
26 t.Helper()
27 body, err := json.Marshal(e)
28 if err != nil {
29 t.Fatal(err)
30 }
31 w := httptest.NewRecorder()
32 s.ServeHTTP(w, httptest.NewRequest(http.MethodPost, "/events", bytes.NewReader(body)))
33 return w
34}
35
36func TestStandaloneServerPersistsSignedAnnouncement(t *testing.T) {
37 e := signedAnnouncement(t, strings.Repeat("0", 63)+"1")
38 cfg := tinygit.ServerConfig{DataDir: t.TempDir(), Owner: e.PubKey}
39 s, err := tinygit.OpenServer(context.Background(), cfg)
40 if err != nil {
41 t.Fatal(err)
42 }
43 w := postEvent(t, s, e)
44 if w.Code != http.StatusOK {
45 t.Fatalf("publish = %d %s", w.Code, w.Body.String())
46 }
47 // Retrying a signed event is safe even if the caller lost the first response.
48 if w := postEvent(t, s, e); w.Code != http.StatusOK {
49 t.Fatalf("retry = %d %s", w.Code, w.Body.String())
50 }
51 if err := s.Close(); err != nil {
52 t.Fatal(err)
53 }
54 s, err = tinygit.OpenServer(context.Background(), cfg)
55 if err != nil {
56 t.Fatal(err)
57 }
58 defer s.Close()
59 // Bech32 public key for the test's secret scalar 1.
60 npub := "npub10xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqpkge6d"
61 w = httptest.NewRecorder()
62 s.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/"+npub+"/demo.git/info/refs?service=git-upload-pack", nil))
63 if w.Code != http.StatusOK || !strings.Contains(w.Header().Get("Content-Type"), "git-upload-pack-advertisement") {
64 t.Fatalf("reopened Git discovery = %d %s", w.Code, w.Body.String())
65 }
66}
67
68func TestStandaloneServerRestrictsRepositoryAdmission(t *testing.T) {
69 ownerEvent := signedAnnouncement(t, strings.Repeat("0", 63)+"1")
70 s, err := tinygit.OpenServer(context.Background(), tinygit.ServerConfig{DataDir: t.TempDir(), Owner: ownerEvent.PubKey})
71 if err != nil {
72 t.Fatal(err)
73 }
74 defer s.Close()
75 for _, tc := range []struct {
76 name string
77 e tinygit.Event
78 }{
79 {"foreign owner", signedAnnouncement(t, strings.Repeat("0", 63)+"2")},
80 {"private repository", signedAnnouncement(t, strings.Repeat("0", 63)+"1", []string{"private", "true"})},
81 } {
82 t.Run(tc.name, func(t *testing.T) {
83 if w := postEvent(t, s, tc.e); w.Code != http.StatusForbidden {
84 t.Fatalf("admission = %d %s", w.Code, w.Body.String())
85 }
86 })
87 }
88 if w := postEvent(t, s, ownerEvent); w.Code != http.StatusOK {
89 t.Fatalf("owner's public announcement = %d %s", w.Code, w.Body.String())
90 }
91}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

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

Refs