This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / reporesolver / resolver_test.go
5.1 kB 156 lines
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 TestCanonicalRedirectTargetKeepsTheTailEscaped(t *testing.T) { 55 cases := []struct { 56 name string 57 path string 58 want string 59 }{ 60 {"plain tail", "/boltless.dev/limpet/tree/main", "/akshay.dev/anemone/tree/main"}, 61 {"space in a blob path", "/boltless.dev/limpet/blob/main/a%20b.txt", "/akshay.dev/anemone/blob/main/a%20b.txt"}, 62 {"escaped slash in a ref", "/boltless.dev/limpet/archive/refs%2Fheads%2Fmain", "/akshay.dev/anemone/archive/refs%2Fheads%2Fmain"}, 63 {"hash in a filename", "/boltless.dev/limpet/raw/main/c%23.cs", "/akshay.dev/anemone/raw/main/c%23.cs"}, 64 {"repo root", "/boltless.dev/limpet", "/akshay.dev/anemone"}, 65 } 66 67 for _, c := range cases { 68 t.Run(c.name, func(t *testing.T) { 69 req := httptest.NewRequest("GET", c.path, nil) 70 if got := CanonicalRedirectTarget(req, "akshay.dev/anemone"); got != c.want { 71 t.Errorf("CanonicalRedirectTarget = %q, want %q", got, c.want) 72 } 73 }) 74 } 75} 76 77func reqWithChiParams(user, repo string) *http.Request { 78 r := httptest.NewRequest("GET", "/", nil) 79 rctx := chi.NewRouteContext() 80 rctx.URLParams.Add("user", user) 81 rctx.URLParams.Add("repo", repo) 82 return r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, rctx)) 83} 84 85func TestGetBaseRepoPath_DoesNotVoluntaryRedirectToRepoDid(t *testing.T) { 86 r := reqWithChiParams("@boltless.dev", "anemone") 87 repo := &models.Repo{ 88 Did: "did:plc:boltless", 89 Name: "anemone", 90 Rkey: "3kabcxyz", 91 RepoDid: "did:plc:anemone", 92 } 93 got := GetBaseRepoPath(r, repo) 94 want := "@boltless.dev/anemone" 95 if got != want { 96 t.Errorf("GetBaseRepoPath = %q, want %q", got, want) 97 } 98} 99 100func TestGetBaseRepoPath_HonorsUrlParams(t *testing.T) { 101 r := reqWithChiParams("did:plc:akshay", "limpet") 102 repo := &models.Repo{Did: "did:plc:akshay", Name: "limpet", Rkey: "limpet"} 103 if got, want := GetBaseRepoPath(r, repo), "did:plc:akshay/limpet"; got != want { 104 t.Errorf("GetBaseRepoPath = %q, want %q", got, want) 105 } 106} 107 108func TestGetBaseRepoPath_NoParamsPrefersName(t *testing.T) { 109 r := httptest.NewRequest("GET", "/", nil) 110 repo := &models.Repo{Did: "did:plc:akshay", Name: "scallop", Rkey: "3koldtid"} 111 got := GetBaseRepoPath(r, repo) 112 want := "did:plc:akshay/scallop" 113 if got != want { 114 t.Errorf("GetBaseRepoPath = %q, want %q", got, want) 115 } 116} 117 118func TestGetBaseRepoPath_NoParamsNoNameFallsToRepoIdentifier(t *testing.T) { 119 r := httptest.NewRequest("GET", "/", nil) 120 repo := &models.Repo{Did: "did:plc:akshay", Rkey: "3koldtid", RepoDid: "did:plc:scallop"} 121 if got, want := GetBaseRepoPath(r, repo), "did:plc:scallop"; got != want { 122 t.Errorf("GetBaseRepoPath = %q, want %q", got, want) 123 } 124} 125 126func reqWithResolvedId(handle, did string) *http.Request { 127 r := reqWithChiParams(did, "3koldtid") 128 id := identity.Identity{ 129 DID: syntax.DID(did), 130 Handle: syntax.Handle(handle), 131 } 132 return r.WithContext(context.WithValue(r.Context(), "resolvedId", id)) 133} 134 135func TestGetBaseRepoPath_PrefersResolvedHandleOverChiDid(t *testing.T) { 136 r := reqWithResolvedId("boltless.dev", "did:plc:boltless") 137 repo := &models.Repo{Did: "did:plc:boltless", Name: "anemone", Rkey: "3kabcxyz"} 138 got := GetBaseRepoPath(r, repo) 139 want := "boltless.dev/anemone" 140 if got != want { 141 t.Errorf("GetBaseRepoPath = %q, want %q", got, want) 142 } 143} 144 145func TestGetBaseRepoPath_InvalidHandleFallsThroughToChi(t *testing.T) { 146 r := reqWithChiParams("did:plc:boltless", "limpet") 147 id := identity.Identity{ 148 DID: syntax.DID("did:plc:boltless"), 149 Handle: syntax.HandleInvalid, 150 } 151 r = r.WithContext(context.WithValue(r.Context(), "resolvedId", id)) 152 repo := &models.Repo{Did: "did:plc:boltless", Name: "limpet", Rkey: "limpet"} 153 if got, want := GetBaseRepoPath(r, repo), "did:plc:boltless/limpet"; got != want { 154 t.Errorf("GetBaseRepoPath = %q, want %q", got, want) 155 } 156}