Files
gitea/tests/integration/api_packages_pypi_test.go
T
silverwind 8abda62312 test: consolidate Go tests (#39962)
Consolidate all Go tests. Coverage is identical to before. Go tests are
around 5% faster while being 7% smaller. No non-test code is touched.
2026-10-24 13:48:19 +00:00

232 lines
6.8 KiB
Go

// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"regexp"
"strings"
"testing"
"gitea.dev/models/packages"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"gitea.dev/modules/packages/pypi"
"gitea.dev/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPackagePyPI(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "test-package"
packageVersion := "1!1.0.1+r1234"
packageAuthor := "KN4CK3R"
packageDescription := "Test Description"
projectURL := "https://example.com"
content := "test"
hashSHA256 := "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
root := fmt.Sprintf("/api/packages/%s/pypi", user.Name)
createBasicMultipartFile := func(filename, packageName, content string) (body *bytes.Buffer, writer *multipart.Writer, closer func() error) {
body = &bytes.Buffer{}
writer = multipart.NewWriter(body)
part, _ := writer.CreateFormFile("content", filename)
_, _ = io.Copy(part, strings.NewReader(content))
writer.WriteField("name", packageName)
writer.WriteField("version", packageVersion)
writer.WriteField("author", packageAuthor)
writer.WriteField("summary", packageDescription)
writer.WriteField("description", packageDescription)
writer.WriteField("sha256_digest", hashSHA256)
writer.WriteField("requires_python", "3.6")
return body, writer, writer.Close
}
uploadHelper := func(t *testing.T, body *bytes.Buffer, contentType string, expectedStatus int) {
req := NewRequestWithBody(t, "POST", root, body).
SetHeader("Content-Type", contentType).
AddBasicAuth(user.Name)
MakeRequest(t, req, expectedStatus)
}
uploadFile := func(t *testing.T, filename, content string, expectedStatus int) {
body, writer, closeFunc := createBasicMultipartFile(filename, packageName, content)
writer.WriteField("project_urls", "DOCUMENTATION , https://readthedocs.org")
writer.WriteField("project_urls", "Home-page, "+projectURL)
_ = closeFunc()
uploadHelper(t, body, writer.FormDataContentType(), expectedStatus)
}
for _, upload := range []struct {
name string
filename string
fileCount int
}{
{"Upload", "test.whl", 1},
{"UploadAddFile", "test.tar.gz", 2},
} {
t.Run(upload.name, func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
uploadFile(t, upload.filename, content, http.StatusCreated)
pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypePyPI)
assert.NoError(t, err)
assert.Len(t, pvs, 1)
pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
assert.NoError(t, err)
assert.Nil(t, pd.SemVer)
if upload.fileCount == 1 {
metadata, ok := pd.Metadata.(*pypi.Metadata)
require.True(t, ok)
assert.Equal(t, projectURL, metadata.ProjectURL)
} else {
assert.IsType(t, &pypi.Metadata{}, pd.Metadata)
}
assert.Equal(t, packageName, pd.Package.Name)
assert.Equal(t, packageVersion, pd.Version.Version)
pfs, err := packages.GetFilesByVersionID(t.Context(), pvs[0].ID)
assert.NoError(t, err)
assert.Len(t, pfs, upload.fileCount)
var pf *packages.PackageFile
if upload.fileCount == 1 {
pf = pfs[0]
} else {
pf, err = packages.GetFileForVersionByName(t.Context(), pvs[0].ID, upload.filename, packages.EmptyFileKey)
assert.NoError(t, err)
}
assert.Equal(t, upload.filename, pf.Name)
assert.True(t, pf.IsLead)
pb, err := packages.GetBlobByID(t.Context(), pf.BlobID)
assert.NoError(t, err)
assert.Equal(t, int64(4), pb.Size)
})
}
t.Run("UploadHashMismatch", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
filename := "test2.whl"
uploadFile(t, filename, "dummy", http.StatusBadRequest)
})
t.Run("UploadExists", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
uploadFile(t, "test.whl", content, http.StatusConflict)
uploadFile(t, "test.tar.gz", content, http.StatusConflict)
})
t.Run("UploadUsingDeprecatedHomepageMetadata", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
pkgName := "homepage-package"
body, writer, closeFunc := createBasicMultipartFile("test.whl", pkgName, content)
writer.WriteField("home_page", projectURL)
_ = closeFunc()
uploadHelper(t, body, writer.FormDataContentType(), http.StatusCreated)
pvs, err := packages.GetVersionsByPackageName(t.Context(), user.ID, packages.TypePyPI, pkgName)
assert.NoError(t, err)
assert.Len(t, pvs, 1)
pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
assert.NoError(t, err)
metadata, ok := pd.Metadata.(*pypi.Metadata)
require.True(t, ok)
assert.Equal(t, projectURL, metadata.ProjectURL)
})
t.Run("UploadWithoutAnyHomepageURLMetadata", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
pkgName := "no-project-url-or-homepage-package"
body, writer, closeFunc := createBasicMultipartFile("test.whl", pkgName, content)
_ = closeFunc()
uploadHelper(t, body, writer.FormDataContentType(), http.StatusCreated)
pvs, err := packages.GetVersionsByPackageName(t.Context(), user.ID, packages.TypePyPI, pkgName)
assert.NoError(t, err)
assert.Len(t, pvs, 1)
pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
assert.NoError(t, err)
metadata, ok := pd.Metadata.(*pypi.Metadata)
require.True(t, ok)
assert.Empty(t, metadata.ProjectURL)
})
t.Run("Download", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
downloadFile := func(filename string) {
req := NewRequest(t, "GET", fmt.Sprintf("%s/files/%s/%s/%s", root, packageName, packageVersion, filename)).
AddBasicAuth(user.Name)
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, []byte(content), resp.Body.Bytes())
}
downloadFile("test.whl")
downloadFile("test.tar.gz")
pvs, err := packages.GetVersionsByPackageName(t.Context(), user.ID, packages.TypePyPI, packageName)
assert.NoError(t, err)
assert.Len(t, pvs, 1)
assert.Equal(t, int64(2), pvs[0].DownloadCount)
})
t.Run("PackageMetadata", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
req := NewRequest(t, "GET", fmt.Sprintf("%s/simple/%s", root, packageName)).
AddBasicAuth(user.Name)
resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
nodes := htmlDoc.doc.Find("a").Nodes
assert.Len(t, nodes, 2)
hrefMatcher := regexp.MustCompile(fmt.Sprintf(`%s/files/%s/%s/test\..+#sha256=%s`, root, regexp.QuoteMeta(packageName), regexp.QuoteMeta(packageVersion), hashSHA256))
for _, a := range nodes {
for _, att := range a.Attr {
switch att.Key {
case "href":
assert.Regexp(t, hrefMatcher, att.Val)
case "data-requires-python":
assert.Equal(t, "3.6", att.Val)
default:
t.Fail()
}
}
}
})
}