code.gitea.io/gitea@v1.21.7/tests/integration/api_packages_generic_test.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "bytes" 8 "fmt" 9 "io" 10 "net/http" 11 "testing" 12 13 "code.gitea.io/gitea/models/db" 14 "code.gitea.io/gitea/models/packages" 15 "code.gitea.io/gitea/models/unittest" 16 user_model "code.gitea.io/gitea/models/user" 17 "code.gitea.io/gitea/modules/setting" 18 "code.gitea.io/gitea/tests" 19 20 "github.com/stretchr/testify/assert" 21 ) 22 23 func TestPackageGeneric(t *testing.T) { 24 defer tests.PrepareTestEnv(t)() 25 26 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 27 28 packageName := "te-st_pac.kage" 29 packageVersion := "1.0.3-te st" 30 filename := "fi-le_na.me" 31 content := []byte{1, 2, 3} 32 33 url := fmt.Sprintf("/api/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion) 34 35 t.Run("Upload", func(t *testing.T) { 36 defer tests.PrintCurrentTest(t)() 37 38 req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)) 39 AddBasicAuthHeader(req, user.Name) 40 MakeRequest(t, req, http.StatusCreated) 41 42 pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) 43 assert.NoError(t, err) 44 assert.Len(t, pvs, 1) 45 46 pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0]) 47 assert.NoError(t, err) 48 assert.Nil(t, pd.Metadata) 49 assert.Equal(t, packageName, pd.Package.Name) 50 assert.Equal(t, packageVersion, pd.Version.Version) 51 52 pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) 53 assert.NoError(t, err) 54 assert.Len(t, pfs, 1) 55 assert.Equal(t, filename, pfs[0].Name) 56 assert.True(t, pfs[0].IsLead) 57 58 pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID) 59 assert.NoError(t, err) 60 assert.Equal(t, int64(len(content)), pb.Size) 61 62 t.Run("Exists", func(t *testing.T) { 63 defer tests.PrintCurrentTest(t)() 64 65 req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)) 66 AddBasicAuthHeader(req, user.Name) 67 MakeRequest(t, req, http.StatusConflict) 68 }) 69 70 t.Run("Additional", func(t *testing.T) { 71 defer tests.PrintCurrentTest(t)() 72 73 req := NewRequestWithBody(t, "PUT", url+"/dummy.bin", bytes.NewReader(content)) 74 AddBasicAuthHeader(req, user.Name) 75 MakeRequest(t, req, http.StatusCreated) 76 77 // Check deduplication 78 pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) 79 assert.NoError(t, err) 80 assert.Len(t, pfs, 2) 81 assert.Equal(t, pfs[0].BlobID, pfs[1].BlobID) 82 }) 83 84 t.Run("InvalidParameter", func(t *testing.T) { 85 defer tests.PrintCurrentTest(t)() 86 87 req := NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, "invalid+package name", packageVersion, filename), bytes.NewReader(content)) 88 AddBasicAuthHeader(req, user.Name) 89 MakeRequest(t, req, http.StatusBadRequest) 90 91 req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, "%20test ", filename), bytes.NewReader(content)) 92 AddBasicAuthHeader(req, user.Name) 93 MakeRequest(t, req, http.StatusBadRequest) 94 95 req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, "inval+id.na me"), bytes.NewReader(content)) 96 AddBasicAuthHeader(req, user.Name) 97 MakeRequest(t, req, http.StatusBadRequest) 98 }) 99 }) 100 101 t.Run("Download", func(t *testing.T) { 102 defer tests.PrintCurrentTest(t)() 103 104 checkDownloadCount := func(count int64) { 105 pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) 106 assert.NoError(t, err) 107 assert.Len(t, pvs, 1) 108 assert.Equal(t, count, pvs[0].DownloadCount) 109 } 110 111 checkDownloadCount(0) 112 113 req := NewRequest(t, "GET", url+"/"+filename) 114 resp := MakeRequest(t, req, http.StatusOK) 115 116 assert.Equal(t, content, resp.Body.Bytes()) 117 118 checkDownloadCount(1) 119 120 req = NewRequest(t, "GET", url+"/dummy.bin") 121 MakeRequest(t, req, http.StatusOK) 122 123 checkDownloadCount(2) 124 125 t.Run("NotExists", func(t *testing.T) { 126 defer tests.PrintCurrentTest(t)() 127 128 req := NewRequest(t, "GET", url+"/not.found") 129 MakeRequest(t, req, http.StatusNotFound) 130 }) 131 132 t.Run("RequireSignInView", func(t *testing.T) { 133 defer tests.PrintCurrentTest(t)() 134 135 setting.Service.RequireSignInView = true 136 defer func() { 137 setting.Service.RequireSignInView = false 138 }() 139 140 req = NewRequest(t, "GET", url+"/dummy.bin") 141 MakeRequest(t, req, http.StatusUnauthorized) 142 }) 143 144 t.Run("ServeDirect", func(t *testing.T) { 145 defer tests.PrintCurrentTest(t)() 146 147 if setting.Packages.Storage.Type != setting.MinioStorageType { 148 t.Skip("Test skipped for non-Minio-storage.") 149 return 150 } 151 152 if !setting.Packages.Storage.MinioConfig.ServeDirect { 153 old := setting.Packages.Storage.MinioConfig.ServeDirect 154 defer func() { 155 setting.Packages.Storage.MinioConfig.ServeDirect = old 156 }() 157 158 setting.Packages.Storage.MinioConfig.ServeDirect = true 159 } 160 161 req := NewRequest(t, "GET", url+"/"+filename) 162 resp := MakeRequest(t, req, http.StatusSeeOther) 163 164 checkDownloadCount(3) 165 166 location := resp.Header().Get("Location") 167 assert.NotEmpty(t, location) 168 169 resp2, err := (&http.Client{}).Get(location) 170 assert.NoError(t, err) 171 assert.Equal(t, http.StatusOK, resp2.StatusCode) 172 173 body, err := io.ReadAll(resp2.Body) 174 assert.NoError(t, err) 175 assert.Equal(t, content, body) 176 177 checkDownloadCount(3) 178 }) 179 }) 180 181 t.Run("Delete", func(t *testing.T) { 182 defer tests.PrintCurrentTest(t)() 183 184 t.Run("File", func(t *testing.T) { 185 defer tests.PrintCurrentTest(t)() 186 187 req := NewRequest(t, "DELETE", url+"/"+filename) 188 MakeRequest(t, req, http.StatusUnauthorized) 189 190 req = NewRequest(t, "DELETE", url+"/"+filename) 191 AddBasicAuthHeader(req, user.Name) 192 MakeRequest(t, req, http.StatusNoContent) 193 194 req = NewRequest(t, "GET", url+"/"+filename) 195 MakeRequest(t, req, http.StatusNotFound) 196 197 req = NewRequest(t, "DELETE", url+"/"+filename) 198 AddBasicAuthHeader(req, user.Name) 199 MakeRequest(t, req, http.StatusNotFound) 200 201 pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) 202 assert.NoError(t, err) 203 assert.Len(t, pvs, 1) 204 205 t.Run("RemovesVersion", func(t *testing.T) { 206 defer tests.PrintCurrentTest(t)() 207 208 req = NewRequest(t, "DELETE", url+"/dummy.bin") 209 AddBasicAuthHeader(req, user.Name) 210 MakeRequest(t, req, http.StatusNoContent) 211 212 pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) 213 assert.NoError(t, err) 214 assert.Empty(t, pvs) 215 }) 216 }) 217 218 t.Run("Version", func(t *testing.T) { 219 defer tests.PrintCurrentTest(t)() 220 221 req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)) 222 AddBasicAuthHeader(req, user.Name) 223 MakeRequest(t, req, http.StatusCreated) 224 225 req = NewRequest(t, "DELETE", url) 226 MakeRequest(t, req, http.StatusUnauthorized) 227 228 req = NewRequest(t, "DELETE", url) 229 AddBasicAuthHeader(req, user.Name) 230 MakeRequest(t, req, http.StatusNoContent) 231 232 pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) 233 assert.NoError(t, err) 234 assert.Empty(t, pvs) 235 236 req = NewRequest(t, "GET", url+"/"+filename) 237 MakeRequest(t, req, http.StatusNotFound) 238 239 req = NewRequest(t, "DELETE", url) 240 AddBasicAuthHeader(req, user.Name) 241 MakeRequest(t, req, http.StatusNotFound) 242 }) 243 }) 244 }