mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-08 14:33:54 +02:00
add api endpoint and test
co-authored-by: gemini3-flash
This commit is contained in:
parent
d9834bee25
commit
55c66356c1
@ -1580,10 +1580,11 @@ func Routes() *web.Router {
|
||||
m.Group("/packages/{username}", func() {
|
||||
m.Group("/{type}/{name}", func() {
|
||||
m.Get("/", packages.ListPackageVersions)
|
||||
m.Delete("", reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage)
|
||||
|
||||
m.Group("/{version}", func() {
|
||||
m.Get("", packages.GetPackage)
|
||||
m.Delete("", reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage)
|
||||
m.Delete("", reqPackageAccess(perm.AccessModeWrite), packages.DeletePackageVersion)
|
||||
m.Get("/files", packages.ListPackageFiles)
|
||||
})
|
||||
|
||||
|
||||
@ -118,7 +118,7 @@ func GetPackage(ctx *context.APIContext) {
|
||||
|
||||
// DeletePackage deletes a package
|
||||
func DeletePackage(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /packages/{owner}/{type}/{name}/{version} package deletePackage
|
||||
// swagger:operation DELETE /packages/{owner}/{type}/{name} package deletePackage
|
||||
// ---
|
||||
// summary: Delete a package
|
||||
// parameters:
|
||||
@ -137,6 +137,41 @@ func DeletePackage(ctx *context.APIContext) {
|
||||
// description: name of the package
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
err := packages_service.RemovePackage(ctx, ctx.Doer, ctx.Package.Descriptor.Package)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// DeletePackageVersion deletes a package version
|
||||
func DeletePackageVersion(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /packages/{owner}/{type}/{name}/{version} package deletePackageVersion
|
||||
// ---
|
||||
// summary: Delete a package version
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the package
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: type
|
||||
// in: path
|
||||
// description: type of the package
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: name
|
||||
// in: path
|
||||
// description: name of the package
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: version
|
||||
// in: path
|
||||
// description: version of the package
|
||||
|
||||
42
templates/swagger/v1_json.tmpl
generated
42
templates/swagger/v1_json.tmpl
generated
@ -3914,6 +3914,44 @@
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": [
|
||||
"package"
|
||||
],
|
||||
"summary": "Delete a package",
|
||||
"operationId": "deletePackage",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "owner of the package",
|
||||
"name": "owner",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "type of the package",
|
||||
"name": "type",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "name of the package",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"$ref": "#/responses/empty"
|
||||
},
|
||||
"404": {
|
||||
"$ref": "#/responses/notFound"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/packages/{owner}/{type}/{name}/-/latest": {
|
||||
@ -4099,8 +4137,8 @@
|
||||
"tags": [
|
||||
"package"
|
||||
],
|
||||
"summary": "Delete a package",
|
||||
"operationId": "deletePackage",
|
||||
"summary": "Delete a package version",
|
||||
"operationId": "deletePackageVersion",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
|
||||
@ -85,6 +85,50 @@ func TestPackageAPI(t *testing.T) {
|
||||
assert.Equal(t, user.Name, p.Creator.UserName)
|
||||
})
|
||||
|
||||
t.Run("DeleteEntirePackage", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
packageName := "test-package-entire-delete"
|
||||
for _, version := range []string{"1.0.1", "1.0.2"} {
|
||||
url := fmt.Sprintf("/api/packages/%s/generic/%s/%s/file.bin", user.Name, packageName, version)
|
||||
req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{1})).
|
||||
AddBasicAuth(user.Name)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
}
|
||||
|
||||
req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/generic/%s", user.Name, packageName)).
|
||||
AddTokenAuth(tokenWritePackage)
|
||||
MakeRequest(t, req, http.StatusNoContent)
|
||||
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s", user.Name, packageName)).
|
||||
AddTokenAuth(tokenReadPackage)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
})
|
||||
|
||||
t.Run("DeletePackageVersion", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
packageName := "test-package-version-delete"
|
||||
for _, version := range []string{"1.0.1", "1.0.2"} {
|
||||
url := fmt.Sprintf("/api/packages/%s/generic/%s/%s/file.bin", user.Name, packageName, version)
|
||||
req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{1})).
|
||||
AddBasicAuth(user.Name)
|
||||
MakeRequest(t, req, http.StatusCreated)
|
||||
}
|
||||
|
||||
req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/generic/%s/1.0.1", user.Name, packageName)).
|
||||
AddTokenAuth(tokenWritePackage)
|
||||
MakeRequest(t, req, http.StatusNoContent)
|
||||
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/1.0.1", user.Name, packageName)).
|
||||
AddTokenAuth(tokenReadPackage)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/1.0.2", user.Name, packageName)).
|
||||
AddTokenAuth(tokenReadPackage)
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("ListPackageVersions", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
|
||||
118
tests/integration/packages_service_test.go
Normal file
118
tests/integration/packages_service_test.go
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
packages_module "code.gitea.io/gitea/modules/packages"
|
||||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
"code.gitea.io/gitea/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRemovePackage(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
|
||||
// 1. Setup: Create two packages with properties at all levels
|
||||
createPackage := func(name string) (*packages_model.Package, *packages_model.PackageVersion, *packages_model.PackageFile) {
|
||||
data, _ := packages_module.CreateHashedBufferFromReader(bytes.NewReader([]byte{1}))
|
||||
pv, pf, err := packages_service.CreatePackageOrAddFileToExisting(t.Context(), &packages_service.PackageCreationInfo{
|
||||
PackageInfo: packages_service.PackageInfo{
|
||||
Owner: user,
|
||||
PackageType: packages_model.TypeGeneric,
|
||||
Name: name,
|
||||
Version: "1.0.0",
|
||||
},
|
||||
Creator: user,
|
||||
PackageProperties: map[string]string{"pkg_prop": "val"},
|
||||
VersionProperties: map[string]string{"ver_prop": "val"},
|
||||
}, &packages_service.PackageFileCreationInfo{
|
||||
PackageFileInfo: packages_service.PackageFileInfo{Filename: "file.bin"},
|
||||
Creator: user,
|
||||
Data: data,
|
||||
Properties: map[string]string{"file_prop": "val"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
p, err := packages_model.GetPackageByID(t.Context(), pv.PackageID)
|
||||
require.NoError(t, err)
|
||||
|
||||
return p, pv, pf
|
||||
}
|
||||
|
||||
p1, pv1, pf1 := createPackage("package-1")
|
||||
p2, pv2, pf2 := createPackage("package-2")
|
||||
|
||||
// Verify properties exist before deletion
|
||||
checkProps := func(p *packages_model.Package, pv *packages_model.PackageVersion, pf *packages_model.PackageFile, shouldExist bool) {
|
||||
pps, err := packages_model.GetProperties(t.Context(), packages_model.PropertyTypePackage, p.ID)
|
||||
require.NoError(t, err)
|
||||
if shouldExist {
|
||||
assert.NotEmpty(t, pps)
|
||||
} else {
|
||||
assert.Empty(t, pps)
|
||||
}
|
||||
|
||||
pps, err = packages_model.GetProperties(t.Context(), packages_model.PropertyTypeVersion, pv.ID)
|
||||
require.NoError(t, err)
|
||||
if shouldExist {
|
||||
assert.NotEmpty(t, pps)
|
||||
} else {
|
||||
assert.Empty(t, pps)
|
||||
}
|
||||
|
||||
pps, err = packages_model.GetProperties(t.Context(), packages_model.PropertyTypeFile, pf.ID)
|
||||
require.NoError(t, err)
|
||||
if shouldExist {
|
||||
assert.NotEmpty(t, pps)
|
||||
} else {
|
||||
assert.Empty(t, pps)
|
||||
}
|
||||
}
|
||||
|
||||
checkProps(p1, pv1, pf1, true)
|
||||
checkProps(p2, pv2, pf2, true)
|
||||
|
||||
// 2. Act: Remove package 1
|
||||
err := packages_service.RemovePackage(t.Context(), user, p1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 3. Assert: Package 1 is gone, Package 2 is untouched
|
||||
|
||||
// Check P1
|
||||
_, err = packages_model.GetPackageByID(t.Context(), p1.ID)
|
||||
assert.ErrorIs(t, err, packages_model.ErrPackageNotExist)
|
||||
|
||||
_, err = packages_model.GetVersionByID(t.Context(), pv1.ID)
|
||||
assert.ErrorIs(t, err, packages_model.ErrPackageNotExist)
|
||||
|
||||
_, err = packages_model.GetFileForVersionByID(t.Context(), pv1.ID, pf1.ID)
|
||||
assert.ErrorIs(t, err, packages_model.ErrPackageFileNotExist)
|
||||
|
||||
checkProps(p1, pv1, pf1, false)
|
||||
|
||||
// Check P2
|
||||
p2_after, err := packages_model.GetPackageByID(t.Context(), p2.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, p2_after)
|
||||
|
||||
pv2_after, err := packages_model.GetVersionByID(t.Context(), pv2.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, pv2_after)
|
||||
|
||||
pf2_after, err := packages_model.GetFileForVersionByID(t.Context(), pv2.ID, pf2.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, pf2_after)
|
||||
|
||||
checkProps(p2, pv2, pf2, true)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user