| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- // Copyright 2021 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package integration
-
- import (
- "archive/tar"
- "bytes"
- "compress/gzip"
- "crypto/sha256"
- "crypto/sha512"
- "encoding/base64"
- "fmt"
- "mime/multipart"
- "net/http"
- "testing"
-
- "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/packages/rubygems"
- "code.gitea.io/gitea/tests"
-
- "github.com/stretchr/testify/assert"
- )
-
- type tarFile struct {
- Name string
- Data []byte
- }
-
- func makeArchiveFileTar(files []*tarFile) []byte {
- buf := new(bytes.Buffer)
- tarWriter := tar.NewWriter(buf)
- for _, file := range files {
- _ = tarWriter.WriteHeader(&tar.Header{
- Typeflag: tar.TypeReg,
- Name: file.Name,
- Mode: 0o644,
- Size: int64(len(file.Data)),
- })
- _, _ = tarWriter.Write(file.Data)
- }
- _ = tarWriter.Close()
- return buf.Bytes()
- }
-
- func makeArchiveFileGz(data []byte) []byte {
- buf := new(bytes.Buffer)
- gzWriter, _ := gzip.NewWriterLevel(buf, gzip.NoCompression)
- _, _ = gzWriter.Write(data)
- _ = gzWriter.Close()
- return buf.Bytes()
- }
-
- func makeRubyGem(name, version string) []byte {
- metadataContent := fmt.Sprintf(`--- !ruby/object:Gem::Specification
- name: %s
- version: !ruby/object:Gem::Version
- version: %s
- platform: ruby
- authors:
- - Gitea
- autorequire:
- bindir: bin
- cert_chain: []
- date: 2021-08-23 00:00:00.000000000 Z
- dependencies:
- - !ruby/object:Gem::Dependency
- name: runtime-dep
- requirement: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: 1.2.0
- - - "<"
- - !ruby/object:Gem::Version
- version: '2.0'
- type: :runtime
- prerelease: false
- version_requirements: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: 1.2.0
- - - "<"
- - !ruby/object:Gem::Version
- version: '2.0'
- - !ruby/object:Gem::Dependency
- name: dev-dep
- requirement: !ruby/object:Gem::Requirement
- requirements:
- - - "~>"
- - !ruby/object:Gem::Version
- version: '5.2'
- type: :development
- prerelease: false
- version_requirements: !ruby/object:Gem::Requirement
- requirements:
- - - "~>"
- - !ruby/object:Gem::Version
- version: '5.2'
- description: RubyGems package test
- email: rubygems@gitea.io
- executables: []
- extensions: []
- extra_rdoc_files: []
- files:
- - lib/gitea.rb
- homepage: https://gitea.io/
- licenses:
- - MIT
- metadata: {}
- post_install_message:
- rdoc_options: []
- require_paths:
- - lib
- required_ruby_version: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: 2.3.0
- required_rubygems_version: !ruby/object:Gem::Requirement
- requirements:
- - - ">="
- - !ruby/object:Gem::Version
- version: '1.0'
- requirements: []
- rubyforge_project:
- rubygems_version: 2.7.6.2
- signing_key:
- specification_version: 4
- summary: Gitea package
- test_files: []
- `, name, version)
-
- metadataGz := makeArchiveFileGz([]byte(metadataContent))
- dataTarGz := makeArchiveFileGz(makeArchiveFileTar([]*tarFile{
- {
- Name: "lib/gitea.rb",
- Data: []byte("class Gitea\nend"),
- },
- }))
-
- checksumsYaml := fmt.Sprintf(`---
- SHA256:
- metadata.gz: %x
- data.tar.gz: %x
- SHA512:
- metadata.gz: %x
- data.tar.gz: %x
- `, sha256.Sum256(metadataGz), sha256.Sum256(dataTarGz), sha512.Sum512(metadataGz), sha512.Sum512(dataTarGz))
-
- files := []*tarFile{
- {
- Name: "data.tar.gz",
- Data: dataTarGz,
- },
- {
- Name: "metadata.gz",
- Data: metadataGz,
- },
- {
- Name: "checksums.yaml.gz",
- Data: makeArchiveFileGz([]byte(checksumsYaml)),
- },
- }
- return makeArchiveFileTar(files)
- }
-
- func TestPackageRubyGems(t *testing.T) {
- defer tests.PrepareTestEnv(t)()
-
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
-
- testGemName := "gitea"
- testGemVersion := "1.0.5"
- testGemContent := makeRubyGem(testGemName, testGemVersion)
- testGemContentChecksum := fmt.Sprintf("%x", sha256.Sum256(testGemContent))
-
- testAnotherGemName := "gitea-another"
- testAnotherGemVersion := "0.99"
-
- root := fmt.Sprintf("/api/packages/%s/rubygems", user.Name)
-
- uploadFile := func(t *testing.T, content []byte, expectedStatus int) {
- req := NewRequestWithBody(t, "POST", root+"/api/v1/gems", bytes.NewReader(content)).
- AddBasicAuth(user.Name)
- MakeRequest(t, req, expectedStatus)
- }
-
- t.Run("Upload", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- uploadFile(t, testGemContent, http.StatusCreated)
-
- pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeRubyGems)
- assert.NoError(t, err)
- assert.Len(t, pvs, 1)
-
- pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
- assert.NoError(t, err)
- assert.NotNil(t, pd.SemVer)
- assert.IsType(t, &rubygems.Metadata{}, pd.Metadata)
- assert.Equal(t, testGemName, pd.Package.Name)
- assert.Equal(t, testGemVersion, pd.Version.Version)
-
- pfs, err := packages.GetFilesByVersionID(t.Context(), pvs[0].ID)
- assert.NoError(t, err)
- assert.Len(t, pfs, 1)
- assert.Equal(t, fmt.Sprintf("%s-%s.gem", testGemName, testGemVersion), pfs[0].Name)
- assert.True(t, pfs[0].IsLead)
-
- pb, err := packages.GetBlobByID(t.Context(), pfs[0].BlobID)
- assert.NoError(t, err)
- assert.EqualValues(t, len(testGemContent), pb.Size)
- })
-
- t.Run("UploadExists", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- uploadFile(t, testGemContent, http.StatusConflict)
- })
-
- t.Run("Download", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", fmt.Sprintf("%s/gems/%s-%s.gem", root, testGemName, testGemVersion)).
- AddBasicAuth(user.Name)
- resp := MakeRequest(t, req, http.StatusOK)
-
- assert.Equal(t, testGemContent, resp.Body.Bytes())
-
- pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeRubyGems)
- assert.NoError(t, err)
- assert.Len(t, pvs, 1)
- assert.Equal(t, int64(1), pvs[0].DownloadCount)
- })
-
- t.Run("DownloadGemspec", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", fmt.Sprintf("%s/quick/Marshal.4.8/%s-%s.gemspec.rz", root, testGemName, testGemVersion)).
- AddBasicAuth(user.Name)
- resp := MakeRequest(t, req, http.StatusOK)
-
- b, _ := base64.StdEncoding.DecodeString(`eJxi4Si1EndPzbWyCi5ITc5My0xOLMnMz2M8zMIRLeGpxGWsZ6RnzGbF5hqSyempxJWeWZKayGbN
- EBJqJQjWFZZaVJyZnxfN5qnEZahnoGcKkjTwVBJyB6lUKEhMzk5MTwULGngqcRaVJlWCONEMBp5K
- DGAWSKc7zFhPJamg0qRK99TcYphehZLU4hKInFhGSUlBsZW+PtgZepn5+iDxECRzDUDGcfh6hoA4
- gAAAAP//MS06Gw==`)
- assert.Equal(t, b, resp.Body.Bytes())
-
- pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeRubyGems)
- assert.NoError(t, err)
- assert.Len(t, pvs, 1)
- assert.Equal(t, int64(1), pvs[0].DownloadCount)
- })
-
- t.Run("EnumeratePackages", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- enumeratePackages := func(t *testing.T, endpoint string, expectedContent []byte) {
- req := NewRequest(t, "GET", fmt.Sprintf("%s/%s", root, endpoint)).
- AddBasicAuth(user.Name)
- resp := MakeRequest(t, req, http.StatusOK)
-
- assert.Equal(t, expectedContent, resp.Body.Bytes())
- }
-
- b, _ := base64.StdEncoding.DecodeString(`H4sICAAAAAAA/3NwZWNzLjQuOABi4Yhmi+bwVOJKzyxJTWSzYnMNCbUSdE/NtbIKSy0qzszPi2bzVOIy1DPQM2WzZgjxVOIsKk2qBDEBAQAA///xOEYKOwAAAA==`)
- enumeratePackages(t, "specs.4.8.gz", b)
- b, _ = base64.StdEncoding.DecodeString(`H4sICAAAAAAA/2xhdGVzdF9zcGVjcy40LjgAYuGIZovm8FTiSs8sSU1ks2JzDQm1EnRPzbWyCkstKs7Mz4tm81TiMtQz0DNls2YI8VTiLCpNqgQxAQEAAP//8ThGCjsAAAA=`)
- enumeratePackages(t, "latest_specs.4.8.gz", b)
- b, _ = base64.StdEncoding.DecodeString(`H4sICAAAAAAA/3ByZXJlbGVhc2Vfc3BlY3MuNC44AGLhiGYABAAA//9snXr5BAAAAA==`)
- enumeratePackages(t, "prerelease_specs.4.8.gz", b)
- })
-
- t.Run("UploadAnother", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- uploadFile(t, makeRubyGem(testAnotherGemName, testAnotherGemVersion), http.StatusCreated)
- })
-
- t.Run("PackageInfo", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
-
- req := NewRequest(t, "GET", fmt.Sprintf("%s/info/%s", root, testGemName)).AddBasicAuth(user.Name)
- resp := MakeRequest(t, req, http.StatusOK)
- expected := fmt.Sprintf(`---
- 1.0.5 runtime-dep:>= 1.2.0&< 2.0|checksum:%s,ruby:>= 2.3.0,rubygems:>= 1.0
- `, testGemContentChecksum)
- assert.Equal(t, expected, resp.Body.String())
- })
-
- t.Run("Versions", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", root+"/versions").AddBasicAuth(user.Name)
- resp := MakeRequest(t, req, http.StatusOK)
- assert.Equal(t, `---
- gitea 1.0.5 08843c2dd0ea19910e6b056b98e38f1c
- gitea-another 0.99 8b639e4048d282941485368ec42609be
- `, resp.Body.String())
- })
-
- deleteGemPackage := func(t *testing.T, packageName, packageVersion string) {
- body := bytes.Buffer{}
- writer := multipart.NewWriter(&body)
- _ = writer.WriteField("gem_name", packageName)
- _ = writer.WriteField("version", packageVersion)
- _ = writer.Close()
- req := NewRequestWithBody(t, "DELETE", root+"/api/v1/gems/yank", &body).
- SetHeader("Content-Type", writer.FormDataContentType()).
- AddBasicAuth(user.Name)
- MakeRequest(t, req, http.StatusOK)
- }
-
- t.Run("DeleteAll", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- deleteGemPackage(t, testGemName, testGemVersion)
- deleteGemPackage(t, testAnotherGemName, testAnotherGemVersion)
- pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeRubyGems)
- assert.NoError(t, err)
- assert.Empty(t, pvs)
- })
-
- t.Run("PackageInfoAfterDelete", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", fmt.Sprintf("%s/info/%s", root, testGemName)).AddBasicAuth(user.Name)
- MakeRequest(t, req, http.StatusNotFound)
- })
-
- t.Run("VersionsAfterDelete", func(t *testing.T) {
- defer tests.PrintCurrentTest(t)()
- req := NewRequest(t, "GET", root+"/versions").AddBasicAuth(user.Name)
- resp := MakeRequest(t, req, http.StatusOK)
- assert.Equal(t, "---\n", resp.Body.String())
- })
- }
|