Files
gitea-tea/internal/app/status_test.go
T
bircni 78f2ef5280 feat(status): show the current branch's pull request, mentions and runs from the clone
tea pr status starts with the pull request of the checked-out branch,
"[feat/one] - Checks: 2 pending · Review: Approved", then lists the
pull requests created by you, assigned to you and requesting your
review under bold headings, as linked #N or OWNER/REPO#N refs with
truncated titles instead of URL columns, and "Nothing here" for an
empty section. Its JSON adds current_branch.

tea status uses the same layout, adds a Mentions section (open issues
and pull requests that mention you; JSON "mentions"), and lists the
failing runs of the clone's repository without -R, naming the remote
it came from. Piped output keeps the URLs.

Signed-off-by: bircni <bircni@icloud.com>
2026-10-11 23:55:13 +02:00

117 lines
4.7 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package app
import (
"context"
"net/http"
"strings"
"testing"
"gitea.dev/tea/internal/clierr"
"github.com/stretchr/testify/require"
)
func TestStatusJSONAndActionsScope(t *testing.T) {
runs := 0
actionsEnabled := true
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.URL.Path == "/api/v1/repos/alice/project":
if actionsEnabled {
_, _ = w.Write([]byte(`{"has_actions":true}`))
} else {
_, _ = w.Write([]byte(`{"has_actions":false}`))
}
case strings.HasSuffix(r.URL.Path, "/actions/runs"):
runs++
require.Equal(t, "/api/v1/repos/alice/project/actions/runs", r.URL.Path)
require.Equal(t, []string{"failure", "timed_out"}, r.URL.Query()["status"])
_, _ = w.Write([]byte(`{"workflow_runs":[{"id":7,"display_title":"Broken build","status":"completed","conclusion":"failure"}]}`))
case strings.HasSuffix(r.URL.Path, "/issues") || strings.HasSuffix(r.URL.Path, "/search"):
_, _ = w.Write([]byte(`[]`))
default:
t.Fatalf("unexpected path %s", r.URL.Path)
}
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
require.NoError(t, Execute(context.Background(), deps, []string{"status", "-R", "alice/project", "--json=user,pull_requests,runs_included,failing_runs", "--jq", "{user, pull_requests, runs_included, run_ids: [.failing_runs[].id]}"}))
require.JSONEq(t, `{"user":"alice","pull_requests":{"current_branch":null,"authored":[],"assigned":[],"review_requested":[]},"runs_included":true,"run_ids":[7]}`, out.String())
require.Empty(t, diagnostics.String())
require.Equal(t, 1, runs)
actionsEnabled = false
for _, args := range [][]string{
{"status", "--json=runs_included,failing_runs"},
{"status", "-R", "alice/project", "--json=runs_included,failing_runs"},
{"status", "-R", "alice/project", "--runs=false", "--json=runs_included,failing_runs"},
{"pr", "status", "-R", "alice/project", "--json"},
} {
out.Reset()
require.NoError(t, Execute(context.Background(), deps, args))
if args[0] == "pr" {
require.JSONEq(t, `{"current_branch":null,"authored":[],"assigned":[],"review_requested":[]}`, out.String())
} else {
require.JSONEq(t, `{"runs_included":false,"failing_runs":[]}`, out.String())
}
require.Equal(t, 1, runs)
}
}
func TestStatusFailureDoesNotPublishPartialJSON(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("created") == "true" {
_, _ = w.Write([]byte(`[{"id":1,"number":1,"title":"Authored PR","repository":{"full_name":"alice/project"}}]`))
return
}
w.WriteHeader(http.StatusForbidden)
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
err := Execute(context.Background(), deps, []string{"pr", "status", "--json"})
require.Error(t, err)
require.Equal(t, clierr.Failure, clierr.ExitCode(err))
require.Empty(t, out.String())
require.Empty(t, diagnostics.String())
}
func TestPullStatusShowsTheCurrentBranch(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.URL.Path == "/api/v1/repos/alice/project/pulls/1":
_, _ = w.Write([]byte(`{"number":1,"title":"Add one.txt","state":"open","head":{"ref":"feat/one","sha":"abc"},"html_url":"http://gitea/alice/project/pulls/1"}`))
case r.URL.Query().Get("page") != "" && r.URL.Query().Get("page") != "1":
_, _ = w.Write([]byte(`[]`))
case r.URL.Path == "/api/v1/repos/alice/project/pulls/1/reviews":
_, _ = w.Write([]byte(`[{"id":5,"state":"APPROVED","user":{"login":"bob"}}]`))
case r.URL.Path == "/api/v1/repos/alice/project/statuses/abc":
_, _ = w.Write([]byte(`[{"id":1,"context":"ci","status":"pending"},{"id":2,"context":"lint","status":"pending"}]`))
case r.URL.Query().Get("created_by") == "alice":
_, _ = w.Write([]byte(`[{"id":1,"number":1,"title":"Add one.txt","repository":{"full_name":"alice/project"},"html_url":"http://gitea/alice/project/pulls/1"}]`))
default:
_, _ = w.Write([]byte(`[]`))
}
}))
defer server.Close()
deps, out, _ := serverDeps(t, server.URL)
plainTTY(&deps, server.URL)
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1", "TEA_REPO": "alice/project"})
deps.Git = &fakeGit{results: map[string]string{"symbolic-ref --short HEAD": "feat/one", "config --get branch.feat/one.tea-pr": "1"}}
require.NoError(t, Execute(context.Background(), deps, []string{"pr", "status"}))
require.Equal(t, `Current branch
#1 Add one.txt [feat/one]
- Checks: 2 pending · Review: Approved
Created by you
#1 Add one.txt
Assigned to you
Nothing here
Requesting a code review from you
Nothing here
`, stripLinks(out.String()))
}