code.gitea.io/gitea@v1.22.3/tests/integration/api_packages_cran_test.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "archive/tar" 8 "archive/zip" 9 "bytes" 10 "compress/gzip" 11 "fmt" 12 "net/http" 13 "testing" 14 15 "code.gitea.io/gitea/models/db" 16 "code.gitea.io/gitea/models/packages" 17 "code.gitea.io/gitea/models/unittest" 18 user_model "code.gitea.io/gitea/models/user" 19 cran_module "code.gitea.io/gitea/modules/packages/cran" 20 "code.gitea.io/gitea/tests" 21 22 "github.com/stretchr/testify/assert" 23 ) 24 25 func TestPackageCran(t *testing.T) { 26 defer tests.PrepareTestEnv(t)() 27 28 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 29 30 packageName := "test.package" 31 packageVersion := "1.0.3" 32 packageAuthor := "KN4CK3R" 33 packageDescription := "Gitea Test Package" 34 35 createDescription := func(name, version string) []byte { 36 var buf bytes.Buffer 37 fmt.Fprintln(&buf, "Package:", name) 38 fmt.Fprintln(&buf, "Version:", version) 39 fmt.Fprintln(&buf, "Description:", packageDescription) 40 fmt.Fprintln(&buf, "Imports: abc,\n123") 41 fmt.Fprintln(&buf, "NeedsCompilation: yes") 42 fmt.Fprintln(&buf, "License: MIT") 43 fmt.Fprintln(&buf, "Author:", packageAuthor) 44 return buf.Bytes() 45 } 46 47 url := fmt.Sprintf("/api/packages/%s/cran", user.Name) 48 49 t.Run("Source", func(t *testing.T) { 50 createArchive := func(filename string, content []byte) *bytes.Buffer { 51 var buf bytes.Buffer 52 gw := gzip.NewWriter(&buf) 53 tw := tar.NewWriter(gw) 54 hdr := &tar.Header{ 55 Name: filename, 56 Mode: 0o600, 57 Size: int64(len(content)), 58 } 59 tw.WriteHeader(hdr) 60 tw.Write(content) 61 tw.Close() 62 gw.Close() 63 return &buf 64 } 65 66 t.Run("Upload", func(t *testing.T) { 67 defer tests.PrintCurrentTest(t)() 68 69 uploadURL := url + "/src" 70 71 req := NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) 72 MakeRequest(t, req, http.StatusUnauthorized) 73 74 req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( 75 "dummy.txt", 76 []byte{}, 77 )).AddBasicAuth(user.Name) 78 MakeRequest(t, req, http.StatusBadRequest) 79 80 req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( 81 "package/DESCRIPTION", 82 createDescription(packageName, packageVersion), 83 )).AddBasicAuth(user.Name) 84 MakeRequest(t, req, http.StatusCreated) 85 86 pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeCran) 87 assert.NoError(t, err) 88 assert.Len(t, pvs, 1) 89 90 pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) 91 assert.NoError(t, err) 92 assert.Nil(t, pd.SemVer) 93 assert.IsType(t, &cran_module.Metadata{}, pd.Metadata) 94 assert.Equal(t, packageName, pd.Package.Name) 95 assert.Equal(t, packageVersion, pd.Version.Version) 96 97 pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) 98 assert.NoError(t, err) 99 assert.Len(t, pfs, 1) 100 assert.Equal(t, fmt.Sprintf("%s_%s.tar.gz", packageName, packageVersion), pfs[0].Name) 101 assert.True(t, pfs[0].IsLead) 102 103 req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( 104 "package/DESCRIPTION", 105 createDescription(packageName, packageVersion), 106 )).AddBasicAuth(user.Name) 107 MakeRequest(t, req, http.StatusConflict) 108 }) 109 110 t.Run("Download", func(t *testing.T) { 111 defer tests.PrintCurrentTest(t)() 112 113 req := NewRequest(t, "GET", fmt.Sprintf("%s/src/contrib/%s_%s.tar.gz", url, packageName, packageVersion)). 114 AddBasicAuth(user.Name) 115 MakeRequest(t, req, http.StatusOK) 116 }) 117 118 t.Run("Enumerate", func(t *testing.T) { 119 defer tests.PrintCurrentTest(t)() 120 121 req := NewRequest(t, "GET", url+"/src/contrib/PACKAGES"). 122 AddBasicAuth(user.Name) 123 resp := MakeRequest(t, req, http.StatusOK) 124 125 assert.Contains(t, resp.Header().Get("Content-Type"), "text/plain") 126 127 body := resp.Body.String() 128 assert.Contains(t, body, fmt.Sprintf("Package: %s", packageName)) 129 assert.Contains(t, body, fmt.Sprintf("Version: %s", packageVersion)) 130 131 req = NewRequest(t, "GET", url+"/src/contrib/PACKAGES.gz"). 132 AddBasicAuth(user.Name) 133 resp = MakeRequest(t, req, http.StatusOK) 134 135 assert.Contains(t, resp.Header().Get("Content-Type"), "application/x-gzip") 136 }) 137 }) 138 139 t.Run("Binary", func(t *testing.T) { 140 createArchive := func(filename string, content []byte) *bytes.Buffer { 141 var buf bytes.Buffer 142 archive := zip.NewWriter(&buf) 143 w, _ := archive.Create(filename) 144 w.Write(content) 145 archive.Close() 146 return &buf 147 } 148 149 t.Run("Upload", func(t *testing.T) { 150 defer tests.PrintCurrentTest(t)() 151 152 uploadURL := url + "/bin" 153 154 req := NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) 155 MakeRequest(t, req, http.StatusUnauthorized) 156 157 req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( 158 "dummy.txt", 159 []byte{}, 160 )).AddBasicAuth(user.Name) 161 MakeRequest(t, req, http.StatusBadRequest) 162 163 req = NewRequestWithBody(t, "PUT", uploadURL+"?platform=&rversion=", createArchive( 164 "package/DESCRIPTION", 165 createDescription(packageName, packageVersion), 166 )).AddBasicAuth(user.Name) 167 MakeRequest(t, req, http.StatusBadRequest) 168 169 uploadURL += "?platform=windows&rversion=4.2" 170 171 req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( 172 "package/DESCRIPTION", 173 createDescription(packageName, packageVersion), 174 )).AddBasicAuth(user.Name) 175 MakeRequest(t, req, http.StatusCreated) 176 177 pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeCran) 178 assert.NoError(t, err) 179 assert.Len(t, pvs, 1) 180 181 pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) 182 assert.NoError(t, err) 183 assert.Len(t, pfs, 2) 184 185 req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( 186 "package/DESCRIPTION", 187 createDescription(packageName, packageVersion), 188 )).AddBasicAuth(user.Name) 189 MakeRequest(t, req, http.StatusConflict) 190 }) 191 192 t.Run("Download", func(t *testing.T) { 193 defer tests.PrintCurrentTest(t)() 194 195 cases := []struct { 196 Platform string 197 RVersion string 198 ExpectedStatus int 199 }{ 200 {"osx", "4.2", http.StatusNotFound}, 201 {"windows", "4.1", http.StatusNotFound}, 202 {"windows", "4.2", http.StatusOK}, 203 } 204 205 for _, c := range cases { 206 req := NewRequest(t, "GET", fmt.Sprintf("%s/bin/%s/contrib/%s/%s_%s.zip", url, c.Platform, c.RVersion, packageName, packageVersion)). 207 AddBasicAuth(user.Name) 208 MakeRequest(t, req, c.ExpectedStatus) 209 } 210 }) 211 212 t.Run("Enumerate", func(t *testing.T) { 213 defer tests.PrintCurrentTest(t)() 214 215 req := NewRequest(t, "GET", url+"/bin/windows/contrib/4.1/PACKAGES") 216 MakeRequest(t, req, http.StatusNotFound) 217 218 req = NewRequest(t, "GET", url+"/bin/windows/contrib/4.2/PACKAGES"). 219 AddBasicAuth(user.Name) 220 resp := MakeRequest(t, req, http.StatusOK) 221 222 assert.Contains(t, resp.Header().Get("Content-Type"), "text/plain") 223 224 body := resp.Body.String() 225 assert.Contains(t, body, fmt.Sprintf("Package: %s", packageName)) 226 assert.Contains(t, body, fmt.Sprintf("Version: %s", packageVersion)) 227 228 req = NewRequest(t, "GET", url+"/bin/windows/contrib/4.2/PACKAGES.gz"). 229 AddBasicAuth(user.Name) 230 resp = MakeRequest(t, req, http.StatusOK) 231 232 assert.Contains(t, resp.Header().Get("Content-Type"), "application/x-gzip") 233 }) 234 }) 235 }