diff --git a/cmd/repos/settings_test.go b/cmd/repos/settings_test.go new file mode 100644 index 00000000..d7f4b67d --- /dev/null +++ b/cmd/repos/settings_test.go @@ -0,0 +1,141 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repos + +import ( + "testing" + + gitea "gitea.dev/sdk" + "github.com/stretchr/testify/assert" +) + +func TestSettingsCommandMetadata(t *testing.T) { + cmd := &CmdReposSettings + + assert.Equal(t, "settings", cmd.Name) + assert.Contains(t, cmd.Aliases, "config") + assert.Equal(t, "Manage repository feature toggles and merge policy", cmd.Usage) + assert.NotNil(t, cmd.Action) +} + +func TestSettingsCommandFlags(t *testing.T) { + cmd := &CmdReposSettings + + expectedFlags := []string{ + // Feature toggles + "enable-issues", "disable-issues", + "enable-wiki", "disable-wiki", + "enable-pull-requests", "disable-pull-requests", + "enable-projects", "disable-projects", + "enable-releases", "disable-releases", + "enable-packages", "disable-packages", + "enable-actions", "disable-actions", + // Merge policy + "default-merge-style", + "allow-merge-commits", "disallow-merge-commits", + "allow-rebase", "disallow-rebase", + "allow-squash", "disallow-squash", + } + + have := make(map[string]bool, len(cmd.Flags)) + for _, flag := range cmd.Flags { + have[flag.Names()[0]] = true + } + for _, name := range expectedFlags { + assert.True(t, have[name], "expected flag %q not found", name) + } +} + +func TestSettingsDoesNotDuplicateEditFlags(t *testing.T) { + // 'repos settings' must NOT overlap with 'repos edit' which already + // handles name/description/website/private/template/archived/default-branch. + // Including any of those here would conflict with PR #928. + cmd := &CmdReposSettings + have := make(map[string]bool, len(cmd.Flags)) + for _, flag := range cmd.Flags { + have[flag.Names()[0]] = true + } + for _, name := range []string{"name", "description", "website", "private", "template", "archived", "default-branch"} { + assert.False(t, have[name], "--%s belongs to 'repos edit', not 'repos settings'", name) + } +} + +func TestSettingsFeatureTogglePairs(t *testing.T) { + // Each feature must have both an enable and disable flag. + pairs := []struct{ enable, disable string }{ + {"enable-issues", "disable-issues"}, + {"enable-wiki", "disable-wiki"}, + {"enable-pull-requests", "disable-pull-requests"}, + {"enable-projects", "disable-projects"}, + {"enable-releases", "disable-releases"}, + {"enable-packages", "disable-packages"}, + {"enable-actions", "disable-actions"}, + {"allow-merge-commits", "disallow-merge-commits"}, + {"allow-rebase", "disallow-rebase"}, + {"allow-squash", "disallow-squash"}, + } + have := make(map[string]bool) + for _, flag := range CmdReposSettings.Flags { + have[flag.Names()[0]] = true + } + for _, p := range pairs { + assert.True(t, have[p.enable], "missing enable flag %q", p.enable) + assert.True(t, have[p.disable], "missing disable flag %q", p.disable) + } +} + +func TestSetBool(t *testing.T) { + // Tests the setBool helper that drives the toggle pair logic. + cmd := &struct{}{} // unused, see below + _ = cmd + + // Direct logic test: enable wins over disable when both somehow set + // (cli.Bool returns true if the flag was set, but we treat --enable-X + // first; the helper is deterministic). + var field *bool + set := setBoolHelper(true, false, &field) + assert.True(t, set) + assert.NotNil(t, field) + assert.True(t, *field) + + field = nil + set = setBoolHelper(false, true, &field) + assert.True(t, set) + assert.NotNil(t, field) + assert.False(t, *field) + + field = nil + set = setBoolHelper(false, false, &field) + assert.False(t, set) + assert.Nil(t, field) +} + +func TestMergeStyleValues(t *testing.T) { + // The default-merge-style flag accepts one of these MergeStyle values. + valid := []gitea.MergeStyle{ + gitea.MergeStyleMerge, + gitea.MergeStyleRebase, + gitea.MergeStyleRebaseMerge, + gitea.MergeStyleSquash, + } + for _, m := range valid { + assert.NotEmpty(t, string(m)) + } +} + +// setBoolHelper exposes setBool's decision logic for testing without +// requiring a fully-built *cli.Command. +func setBoolHelper(enableSet, disableSet bool, field **bool) bool { + if enableSet { + v := true + *field = &v + return true + } + if disableSet { + v := false + *field = &v + return true + } + return false +}