Monorepo for Tangled
tangled.org
1package reporesolver
2
3import (
4 "context"
5 "net/http"
6 "net/http/httptest"
7 "testing"
8
9 "github.com/bluesky-social/indigo/atproto/identity"
10 "github.com/bluesky-social/indigo/atproto/syntax"
11 "github.com/go-chi/chi/v5"
12 "tangled.org/core/appview/models"
13)
14
15func TestExtractCurrentDir(t *testing.T) {
16 tests := []struct {
17 path string
18 want string
19 }{
20 {"/@user/repo/blob/main/docs/README.md", "docs"},
21 {"/@user/repo/blob/main/README.md", "."},
22 {"/@user/repo/tree/main/docs", "docs"},
23 {"/@user/repo/tree/main/docs/", "docs"},
24 {"/@user/repo/tree/main", "."},
25 }
26
27 for _, tt := range tests {
28 if got := extractCurrentDir(tt.path); got != tt.want {
29 t.Errorf("extractCurrentDir(%q) = %q, want %q", tt.path, got, tt.want)
30 }
31 }
32}
33
34func TestCanonicalRepoPath(t *testing.T) {
35 cases := []struct {
36 name string
37 handle string
38 repo *models.Repo
39 want string
40 }{
41 {"name preferred", "boltless.dev", &models.Repo{Name: "anemone", Rkey: "3kabc"}, "boltless.dev/anemone"},
42 {"name equals rkey", "boltless.dev", &models.Repo{Name: "clam", Rkey: "clam"}, "boltless.dev/clam"},
43 {"empty name uses rkey", "akshay.dev", &models.Repo{Rkey: "limpet"}, "akshay.dev/limpet"},
44 }
45 for _, c := range cases {
46 t.Run(c.name, func(t *testing.T) {
47 if got := CanonicalRepoPath(c.handle, c.repo); got != c.want {
48 t.Errorf("CanonicalRepoPath = %q, want %q", got, c.want)
49 }
50 })
51 }
52}
53
54func reqWithChiParams(user, repo string) *http.Request {
55 r := httptest.NewRequest("GET", "/", nil)
56 rctx := chi.NewRouteContext()
57 rctx.URLParams.Add("user", user)
58 rctx.URLParams.Add("repo", repo)
59 return r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, rctx))
60}
61
62func TestGetBaseRepoPath_DoesNotVoluntaryRedirectToRepoDid(t *testing.T) {
63 r := reqWithChiParams("@boltless.dev", "anemone")
64 repo := &models.Repo{
65 Did: "did:plc:boltless",
66 Name: "anemone",
67 Rkey: "3kabcxyz",
68 RepoDid: "did:plc:anemone",
69 }
70 got := GetBaseRepoPath(r, repo)
71 want := "@boltless.dev/anemone"
72 if got != want {
73 t.Errorf("GetBaseRepoPath = %q, want %q", got, want)
74 }
75}
76
77func TestGetBaseRepoPath_HonorsUrlParams(t *testing.T) {
78 r := reqWithChiParams("did:plc:akshay", "limpet")
79 repo := &models.Repo{Did: "did:plc:akshay", Name: "limpet", Rkey: "limpet"}
80 if got, want := GetBaseRepoPath(r, repo), "did:plc:akshay/limpet"; got != want {
81 t.Errorf("GetBaseRepoPath = %q, want %q", got, want)
82 }
83}
84
85func TestGetBaseRepoPath_NoParamsPrefersName(t *testing.T) {
86 r := httptest.NewRequest("GET", "/", nil)
87 repo := &models.Repo{Did: "did:plc:akshay", Name: "scallop", Rkey: "3koldtid"}
88 got := GetBaseRepoPath(r, repo)
89 want := "did:plc:akshay/scallop"
90 if got != want {
91 t.Errorf("GetBaseRepoPath = %q, want %q", got, want)
92 }
93}
94
95func TestGetBaseRepoPath_NoParamsNoNameFallsToRepoIdentifier(t *testing.T) {
96 r := httptest.NewRequest("GET", "/", nil)
97 repo := &models.Repo{Did: "did:plc:akshay", Rkey: "3koldtid", RepoDid: "did:plc:scallop"}
98 if got, want := GetBaseRepoPath(r, repo), "did:plc:scallop"; got != want {
99 t.Errorf("GetBaseRepoPath = %q, want %q", got, want)
100 }
101}
102
103func reqWithResolvedId(handle, did string) *http.Request {
104 r := reqWithChiParams(did, "3koldtid")
105 id := identity.Identity{
106 DID: syntax.DID(did),
107 Handle: syntax.Handle(handle),
108 }
109 return r.WithContext(context.WithValue(r.Context(), "resolvedId", id))
110}
111
112func TestGetBaseRepoPath_PrefersResolvedHandleOverChiDid(t *testing.T) {
113 r := reqWithResolvedId("boltless.dev", "did:plc:boltless")
114 repo := &models.Repo{Did: "did:plc:boltless", Name: "anemone", Rkey: "3kabcxyz"}
115 got := GetBaseRepoPath(r, repo)
116 want := "boltless.dev/anemone"
117 if got != want {
118 t.Errorf("GetBaseRepoPath = %q, want %q", got, want)
119 }
120}
121
122func TestGetBaseRepoPath_InvalidHandleFallsThroughToChi(t *testing.T) {
123 r := reqWithChiParams("did:plc:boltless", "limpet")
124 id := identity.Identity{
125 DID: syntax.DID("did:plc:boltless"),
126 Handle: syntax.HandleInvalid,
127 }
128 r = r.WithContext(context.WithValue(r.Context(), "resolvedId", id))
129 repo := &models.Repo{Did: "did:plc:boltless", Name: "limpet", Rkey: "limpet"}
130 if got, want := GetBaseRepoPath(r, repo), "did:plc:boltless/limpet"; got != want {
131 t.Errorf("GetBaseRepoPath = %q, want %q", got, want)
132 }
133}