mirror of
https://gitea.com/gitea/tea.git
synced 2026-09-10 07:26:33 -04:00
Follow-up to 5d3db5d (#571). No user-visible CLI changes.
- Replace tautological metadata unit tests with httptest-based e2e
tests that exercise runRequestReview, runCancelReview, and
runReviewersList against a mock Gitea API; each test captures
method, path, and request body.
- Add tests/integration/pulls_reviewers_test.go covering create-time
--reviewer/--team-reviewer, request-review add, cancel-review by
user and by team, validation error, and bad-PR error against a
real Gitea instance.
- Extract parseReviewRequestArgs in cmd/pulls/review_helpers.go so
runRequestReview and runCancelReview share one validation/parsing
path; both now route through task.ApplyReviewerChanges instead of
inlining the SDK call.
- Extend task.ApplyReviewerChanges to accept teamAdd/teamRm and use
it from request-review, cancel-review, and the existing edit flow.
- Replace task.CreatePull 8-positional-arg signature with a
CreatePullOptions struct; update cmd/pulls/create.go and
modules/interact/pull_create.go call sites.
- Defensively filter empty CSV entries in parseReviewRequestArgs via
nonEmptyValues so the validation is correct regardless of whether
the underlying CsvFlag trims empty entries (kept independent of
the separate CsvFlag bugfix PR).
Verification:
make fmt fmt-check vet lint test docs docs-check build
90 lines
2.6 KiB
Go
90 lines
2.6 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package pulls
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
gitea "gitea.dev/sdk"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/urfave/cli/v3"
|
|
|
|
"gitea.dev/tea/modules/config"
|
|
)
|
|
|
|
// withMockServer spins up a minimal Gitea API stub and configures tea to
|
|
// use it as the default login. The handler is called once for the version
|
|
// probe (InitCommand → login.Client) and once per assertion the test wants
|
|
// to make on the API path under test.
|
|
func withMockServer(t *testing.T, handler http.HandlerFunc) string {
|
|
t.Helper()
|
|
|
|
server := httptest.NewServer(handler)
|
|
t.Cleanup(server.Close)
|
|
|
|
configPath := filepath.Join(t.TempDir(), "config.yml")
|
|
config.SetConfigPathForTesting(configPath)
|
|
t.Cleanup(func() {
|
|
config.SetConfigPathForTesting("")
|
|
})
|
|
config.SetConfigForTesting(config.LocalConfig{
|
|
Logins: []config.Login{{
|
|
Name: "test",
|
|
URL: server.URL,
|
|
Token: "token",
|
|
User: "user1",
|
|
Default: true,
|
|
}},
|
|
})
|
|
return server.URL
|
|
}
|
|
|
|
// runAction constructs a cli.Command that has the action replaced with a
|
|
// no-op, then runs it through urfave/cli with the given arg list so flag
|
|
// values and positional args are populated. The returned *cli.Command is
|
|
// then passed to the real action function under test. This works around
|
|
// urfave/cli's behavior where cmd.Run calls the action, which we don't
|
|
// want — we want to inspect the parsed cmd, then call the real action
|
|
// ourselves.
|
|
//
|
|
// All cross-cutting flags (--login, --repo, --output) must be passed via
|
|
// `args` along with the command-specific ones.
|
|
func runAction(t *testing.T, src cli.Command, args []string) *cli.Command {
|
|
t.Helper()
|
|
probe := src
|
|
probe.Action = func(_ context.Context, _ *cli.Command) error { return nil }
|
|
probe.Reader = bytes.NewReader(nil)
|
|
probe.Writer = io.Discard
|
|
probe.ErrWriter = io.Discard
|
|
|
|
fullArgs := append([]string{"test"}, args...)
|
|
require.NoError(t, probe.Run(t.Context(), fullArgs))
|
|
return &probe
|
|
}
|
|
|
|
// expectJSONBody asserts that the recorded request body decodes into the
|
|
// expected value.
|
|
func expectJSONBody(t *testing.T, raw []byte, want gitea.PullReviewRequestOptions) {
|
|
t.Helper()
|
|
var got gitea.PullReviewRequestOptions
|
|
require.NoError(t, json.Unmarshal(raw, &got))
|
|
require.Equal(t, want, got)
|
|
}
|
|
|
|
// flagNames returns the primary name of each cli.Flag in order.
|
|
func flagNames(flags []cli.Flag) []string {
|
|
names := make([]string, 0, len(flags))
|
|
for _, f := range flags {
|
|
names = append(names, f.Names()[0])
|
|
}
|
|
return names
|
|
}
|