mirror of
https://gitea.com/gitea/tea.git
synced 2026-09-10 07:26:33 -04:00
Adds a top-level 'tea deploy-keys' command under ENTITIES, providing
list, create, delete, and detail-by-id operations over the existing
Gitea REST API at /repos/{owner}/{repo}/keys.
- New CmdDeployKeys registered alongside tea webhooks/branches/etc.
- Subcommands: list (with pagination + --fingerprint filter),
create (<title> --key|--key-file [--read-only|--read-write]),
delete (<key-id> --confirm|-y), and a default <key-id> detail view.
- The Gitea API has no edit endpoint; 'change' is documented as
delete+create. No update subcommand is added.
- modules/print/deploy_key.go: DeployKeysList and DeployKeyDetails.
- Unit tests covering command metadata, flag wiring, key-material
resolution (--key vs --key-file, mutual exclusion, missing file),
delete confirmation logic, key-id parsing, and prompt formatting.
- README/CHANGELOG/CLI.md updated.
All four Gitea SDK methods used (CreateDeployKey, DeleteDeployKey,
GetDeployKey, ListDeployKeys) are already present in
code.gitea.io/sdk/gitea v0.23.2; no go.mod changes.
Refs #1066.
Signed-off-by: Ross Golder <ross@golder.org>
(cherry picked from commit 384540c91f9703d1e1b37dd6a8e51f502cc5f216)
113 lines
2.9 KiB
Go
113 lines
2.9 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package deploykeys
|
|
|
|
import (
|
|
"strconv"
|
|
"testing"
|
|
|
|
"gitea.dev/sdk"
|
|
"gitea.dev/tea/modules/utils"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/urfave/cli/v3"
|
|
)
|
|
|
|
func TestDeleteCommandMetadata(t *testing.T) {
|
|
cmd := &CmdDeployKeysDelete
|
|
|
|
assert.Equal(t, "delete", cmd.Name)
|
|
assert.Contains(t, cmd.Aliases, "rm")
|
|
assert.Equal(t, "Delete a deploy key", cmd.Usage)
|
|
assert.Equal(t, "Delete a deploy key by ID from a repository", cmd.Description)
|
|
assert.Equal(t, "<key-id>", cmd.ArgsUsage)
|
|
assert.NotNil(t, cmd.Action)
|
|
}
|
|
|
|
func TestDeleteCommandFlags(t *testing.T) {
|
|
cmd := &CmdDeployKeysDelete
|
|
|
|
var confirmFlag *cli.BoolFlag
|
|
for _, flag := range cmd.Flags {
|
|
if flag.Names()[0] == "confirm" {
|
|
confirmFlag, _ = flag.(*cli.BoolFlag)
|
|
break
|
|
}
|
|
}
|
|
assert.NotNil(t, confirmFlag, "confirm flag should exist")
|
|
assert.Contains(t, confirmFlag.Aliases, "y")
|
|
}
|
|
|
|
func TestDeleteConfirmationLogic(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
confirmFlag bool
|
|
userResponse string
|
|
shouldDelete bool
|
|
}{
|
|
{"--confirm set", true, "", true},
|
|
{"user says y", false, "y", true},
|
|
{"user says Y", false, "Y", true},
|
|
{"user says yes", false, "yes", true},
|
|
{"user says n", false, "n", false},
|
|
{"user says N", false, "N", false},
|
|
{"user says no", false, "no", false},
|
|
{"empty response", false, "", false},
|
|
{"unknown response", false, "maybe", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
shouldDelete := tt.confirmFlag
|
|
if !tt.confirmFlag {
|
|
r := tt.userResponse
|
|
shouldDelete = r == "y" || r == "Y" || r == "yes"
|
|
}
|
|
assert.Equal(t, tt.shouldDelete, shouldDelete)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteKeyIDParsing(t *testing.T) {
|
|
// Mirrors utils.ArgToIndex behavior, exercised through the same parsing
|
|
// the command would receive.
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantID int64
|
|
expectErr bool
|
|
}{
|
|
{"single digit", "1", 1, false},
|
|
{"multi digit", "123", 123, false},
|
|
{"with hash prefix", "#42", 42, false},
|
|
{"zero", "0", 0, false},
|
|
{"negative", "-1", -1, false},
|
|
{"non-numeric", "abc", 0, true},
|
|
{"float", "12.5", 0, true},
|
|
{"empty", "", 0, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
id, err := utils.ArgToIndex(tt.input)
|
|
if tt.expectErr {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.wantID, id)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeletePromptMessage(t *testing.T) {
|
|
key := &gitea.DeployKey{ID: 7, Title: "ci-runner"}
|
|
|
|
// The prompt must include both the ID and the title so the user can
|
|
// confirm which key is being deleted.
|
|
msg := "Are you sure you want to delete deploy key " + strconv.FormatInt(key.ID, 10) + " (" + key.Title + ")? [y/N] "
|
|
assert.Contains(t, msg, "7")
|
|
assert.Contains(t, msg, "ci-runner")
|
|
assert.Contains(t, msg, "[y/N]")
|
|
}
|