code.gitea.io/gitea@v1.21.7/tests/integration/api_packages_pub_test.go (about)

     1  // Copyright 2022 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"archive/tar"
     8  	"bytes"
     9  	"compress/gzip"
    10  	"fmt"
    11  	"io"
    12  	"mime/multipart"
    13  	"net/http"
    14  	"net/http/httptest"
    15  	"testing"
    16  	"time"
    17  
    18  	auth_model "code.gitea.io/gitea/models/auth"
    19  	"code.gitea.io/gitea/models/db"
    20  	"code.gitea.io/gitea/models/packages"
    21  	"code.gitea.io/gitea/models/unittest"
    22  	user_model "code.gitea.io/gitea/models/user"
    23  	pub_module "code.gitea.io/gitea/modules/packages/pub"
    24  	"code.gitea.io/gitea/tests"
    25  
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  func TestPackagePub(t *testing.T) {
    30  	defer tests.PrepareTestEnv(t)()
    31  
    32  	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
    33  
    34  	token := "Bearer " + getUserToken(t, user.Name, auth_model.AccessTokenScopeWritePackage)
    35  
    36  	packageName := "test_package"
    37  	packageVersion := "1.0.1"
    38  	packageDescription := "Test Description"
    39  
    40  	filename := fmt.Sprintf("%s.tar.gz", packageVersion)
    41  
    42  	pubspecContent := `name: ` + packageName + `
    43  version: ` + packageVersion + `
    44  description: ` + packageDescription
    45  
    46  	var buf bytes.Buffer
    47  	zw := gzip.NewWriter(&buf)
    48  	archive := tar.NewWriter(zw)
    49  	archive.WriteHeader(&tar.Header{
    50  		Name: "pubspec.yaml",
    51  		Mode: 0o600,
    52  		Size: int64(len(pubspecContent)),
    53  	})
    54  	archive.Write([]byte(pubspecContent))
    55  	archive.Close()
    56  	zw.Close()
    57  	content := buf.Bytes()
    58  
    59  	root := fmt.Sprintf("/api/packages/%s/pub", user.Name)
    60  
    61  	t.Run("Upload", func(t *testing.T) {
    62  		defer tests.PrintCurrentTest(t)()
    63  
    64  		uploadURL := root + "/api/packages/versions/new"
    65  
    66  		req := NewRequest(t, "GET", uploadURL)
    67  		MakeRequest(t, req, http.StatusUnauthorized)
    68  
    69  		req = NewRequest(t, "GET", uploadURL)
    70  		addTokenAuthHeader(req, token)
    71  		resp := MakeRequest(t, req, http.StatusOK)
    72  
    73  		type UploadRequest struct {
    74  			URL    string            `json:"url"`
    75  			Fields map[string]string `json:"fields"`
    76  		}
    77  
    78  		var result UploadRequest
    79  		DecodeJSON(t, resp, &result)
    80  
    81  		assert.Empty(t, result.Fields)
    82  
    83  		uploadFile := func(t *testing.T, url string, content []byte, expectedStatus int) *httptest.ResponseRecorder {
    84  			body := &bytes.Buffer{}
    85  			writer := multipart.NewWriter(body)
    86  			part, _ := writer.CreateFormFile("file", "dummy.tar.gz")
    87  			_, _ = io.Copy(part, bytes.NewReader(content))
    88  
    89  			_ = writer.Close()
    90  
    91  			req := NewRequestWithBody(t, "POST", url, body)
    92  			req.Header.Add("Content-Type", writer.FormDataContentType())
    93  			addTokenAuthHeader(req, token)
    94  			return MakeRequest(t, req, expectedStatus)
    95  		}
    96  
    97  		resp = uploadFile(t, result.URL, content, http.StatusNoContent)
    98  
    99  		req = NewRequest(t, "GET", resp.Header().Get("Location"))
   100  		addTokenAuthHeader(req, token)
   101  		MakeRequest(t, req, http.StatusOK)
   102  
   103  		pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypePub)
   104  		assert.NoError(t, err)
   105  		assert.Len(t, pvs, 1)
   106  
   107  		pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0])
   108  		assert.NoError(t, err)
   109  		assert.NotNil(t, pd.SemVer)
   110  		assert.IsType(t, &pub_module.Metadata{}, pd.Metadata)
   111  		assert.Equal(t, packageName, pd.Package.Name)
   112  		assert.Equal(t, packageVersion, pd.Version.Version)
   113  
   114  		pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
   115  		assert.NoError(t, err)
   116  		assert.Len(t, pfs, 1)
   117  		assert.Equal(t, filename, pfs[0].Name)
   118  		assert.True(t, pfs[0].IsLead)
   119  
   120  		pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID)
   121  		assert.NoError(t, err)
   122  		assert.Equal(t, int64(len(content)), pb.Size)
   123  
   124  		_ = uploadFile(t, result.URL, content, http.StatusBadRequest)
   125  	})
   126  
   127  	t.Run("Download", func(t *testing.T) {
   128  		defer tests.PrintCurrentTest(t)()
   129  
   130  		req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s/%s", root, packageName, packageVersion))
   131  		resp := MakeRequest(t, req, http.StatusOK)
   132  
   133  		type VersionMetadata struct {
   134  			Version    string    `json:"version"`
   135  			ArchiveURL string    `json:"archive_url"`
   136  			Published  time.Time `json:"published"`
   137  			Pubspec    any       `json:"pubspec,omitempty"`
   138  		}
   139  
   140  		var result VersionMetadata
   141  		DecodeJSON(t, resp, &result)
   142  
   143  		assert.Equal(t, packageVersion, result.Version)
   144  		assert.NotNil(t, result.Pubspec)
   145  
   146  		req = NewRequest(t, "GET", result.ArchiveURL)
   147  		resp = MakeRequest(t, req, http.StatusOK)
   148  
   149  		assert.Equal(t, content, resp.Body.Bytes())
   150  	})
   151  
   152  	t.Run("EnumeratePackageVersions", func(t *testing.T) {
   153  		defer tests.PrintCurrentTest(t)()
   154  
   155  		req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s", root, packageName))
   156  		resp := MakeRequest(t, req, http.StatusOK)
   157  
   158  		type VersionMetadata struct {
   159  			Version    string    `json:"version"`
   160  			ArchiveURL string    `json:"archive_url"`
   161  			Published  time.Time `json:"published"`
   162  			Pubspec    any       `json:"pubspec,omitempty"`
   163  		}
   164  
   165  		type PackageVersions struct {
   166  			Name     string             `json:"name"`
   167  			Latest   *VersionMetadata   `json:"latest"`
   168  			Versions []*VersionMetadata `json:"versions"`
   169  		}
   170  
   171  		var result PackageVersions
   172  		DecodeJSON(t, resp, &result)
   173  
   174  		assert.Equal(t, packageName, result.Name)
   175  		assert.NotNil(t, result.Latest)
   176  		assert.Len(t, result.Versions, 1)
   177  		assert.Equal(t, result.Latest.Version, result.Versions[0].Version)
   178  		assert.Equal(t, packageVersion, result.Latest.Version)
   179  		assert.NotNil(t, result.Latest.Pubspec)
   180  	})
   181  }