This repository has no description
0

Configure Feed

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

core / appview / repo / archive_test.go
4.1 kB 94 lines
1package repo 2 3import ( 4 "net/http" 5 "net/http/httptest" 6 "net/url" 7 "strings" 8 "testing" 9 10 "github.com/go-chi/chi/v5" 11 "tangled.org/core/appview/config" 12 "tangled.org/core/appview/models" 13 "tangled.org/core/gitutil" 14) 15 16const ( 17 testRepoDid = "did:plc:limpet" 18 testRepoOwner = "did:plc:boltless" 19 testRepoRkey = "3kzabcdefghij" 20 testRepoPath = "/boltless.dev/squid" 21) 22 23func TestParseArchiveRequest(t *testing.T) { 24 var ( 25 got gitutil.ArchiveParams 26 gotErr error 27 ) 28 router := chi.NewRouter() 29 router.Get("/{user}/{repo}"+archiveRoute, func(w http.ResponseWriter, r *http.Request) { 30 got, gotErr = parseArchiveRequest(r) 31 }) 32 33 resolvedParams := gitutil.ArchiveParams{ 34 Rev: "6f1d3a2b4c5d6e7f8091a2b3c4d5e6f708192a3b", 35 Format: gitutil.ArchiveZip, 36 Prefix: gitutil.ArchivePrefix("").OrDefault("squid", "refs/heads/feat/uni"), 37 } 38 rp := &Repo{config: &config.Config{Core: config.CoreConfig{Dev: true, AppviewHost: "tangled.org"}}} 39 immutable, err := url.Parse(rp.immutableArchiveURL( 40 &models.Repo{Did: testRepoOwner, Rkey: testRepoRkey, Name: "squid", RepoDid: testRepoDid}, 41 resolvedParams, 42 )) 43 if err != nil { 44 t.Fatalf("the immutable URL must parse: %v", err) 45 } 46 47 windows := "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" 48 targz, zip := gitutil.ArchiveTarGz, gitutil.ArchiveZip 49 cases := []struct { 50 name string 51 path string 52 userAgent string 53 want gitutil.ArchiveParams 54 wantErr bool 55 }{ 56 {"short ref", testRepoPath + "/archive/v1.0.0?format=tar.gz", "", gitutil.ArchiveParams{Rev: "v1.0.0", Format: targz}, false}, 57 {"full ref unescaped", testRepoPath + "/archive/refs/tags/v1.0.0?prefix=did:plc:boltless", "", gitutil.ArchiveParams{Rev: "refs/tags/v1.0.0", Format: targz, Prefix: "did:plc:boltless"}, false}, 58 {"full ref escaped", testRepoPath + "/archive/refs%2Ftags%2Fv1.0.0?prefix=did:plc:boltless", "", gitutil.ArchiveParams{Rev: "refs/tags/v1.0.0", Format: targz, Prefix: "did:plc:boltless"}, false}, 59 {"format from suffix", testRepoPath + "/archive/refs/tags/v1.0.0.zip", "", gitutil.ArchiveParams{Rev: "refs/tags/v1.0.0", Format: zip}, false}, 60 {"unknown format query with a zip suffix", testRepoPath + "/archive/refs/tags/v1.0.0.zip?format=tar.xz", "", gitutil.ArchiveParams{Rev: "refs/tags/v1.0.0", Format: zip}, false}, 61 {"zip for a windows user agent", testRepoPath + "/archive/main?format=tar.xz", windows, gitutil.ArchiveParams{Rev: "main", Format: zip}, false}, 62 {"percent in the ref itself", testRepoPath + "/archive/refs/tags/a%252Fb", "", gitutil.ArchiveParams{Rev: "refs/tags/a%2Fb", Format: targz}, false}, 63 {"prefix wrapped in slashes", testRepoPath + "/archive/main?prefix=/kelp/", "", gitutil.ArchiveParams{Rev: "main", Format: targz, Prefix: "kelp"}, false}, 64 {"traversal escaped", testRepoPath + "/archive/..%2F..%2Fetc", "", gitutil.ArchiveParams{Rev: "../../etc", Format: targz}, false}, 65 {"parse deletes a ref query", testRepoPath + "/archive/main?ref=other", "", gitutil.ArchiveParams{Rev: "main", Format: targz}, false}, 66 {"our own immutable URL", immutable.RequestURI(), "", resolvedParams, false}, 67 68 {"empty ref", testRepoPath + "/archive/", "", gitutil.ArchiveParams{}, true}, 69 {"escaped space", testRepoPath + "/archive/refs/tags/a%20b", "", gitutil.ArchiveParams{}, true}, 70 {"ref that git would read as an option", testRepoPath + "/archive/--output=%2Ftmp%2Fevil", "", gitutil.ArchiveParams{}, true}, 71 } 72 73 for _, tc := range cases { 74 t.Run(tc.name, func(t *testing.T) { 75 got, gotErr = gitutil.ArchiveParams{}, nil 76 path := tc.path 77 if rest, isRepoDid := strings.CutPrefix(path, "/"+testRepoDid); isRepoDid { 78 path = "/" + testRepoOwner + "/" + testRepoRkey + rest 79 } 80 81 req := httptest.NewRequest(http.MethodGet, path, nil) 82 req.Header.Set("User-Agent", tc.userAgent) 83 rec := httptest.NewRecorder() 84 router.ServeHTTP(rec, req) 85 86 if rec.Code != http.StatusOK { 87 t.Fatalf("%s: status = %d, want the archive route to match", path, rec.Code) 88 } 89 if got != tc.want || (gotErr != nil) != tc.wantErr { 90 t.Errorf("params = %+v with err %v, want %+v and rejected = %v", got, gotErr, tc.want, tc.wantErr) 91 } 92 }) 93 } 94}