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  }