mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
search issue and search pr printed rows without a header, showed merged pull requests as closed and never said that more results exist. They now show REPO#ID TITLE STATE AUTHOR UPDATED under a context line that counts the matches and points at the next page, are also search issues and search prs, take -s -L -A -l -m and @me, and use --until for --before, which still works. Search results gain an author JSON field. Signed-off-by: bircni <bircni@icloud.com>
100 lines
5.0 KiB
Go
100 lines
5.0 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package app
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.dev/tea/internal/clierr"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestSearchIssueTeamFilter(t *testing.T) {
|
|
calls := 0
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
calls++
|
|
require.Equal(t, "/api/v1/repos/issues/search", r.URL.Path)
|
|
query := r.URL.Query()
|
|
require.Equal(t, "team-org", query.Get("owner"))
|
|
require.Equal(t, "devs", query.Get("team"))
|
|
require.Equal(t, "issues", query.Get("type"))
|
|
_, _ = w.Write([]byte(`[{"id":1,"number":2,"title":"Team issue","html_url":"https://instance/team-org/repo/issues/2","state":"open","repository":{"full_name":"team-org/repo"}}]`))
|
|
}))
|
|
defer server.Close()
|
|
deps, out, diagnostics := serverDeps(t, server.URL)
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"search", "issue", "--owner", "team-org", "--team", "devs", "--json=number,title,repository"}))
|
|
require.JSONEq(t, `[{"number":2,"title":"Team issue","repository":"team-org/repo"}]`, out.String())
|
|
require.Empty(t, diagnostics.String())
|
|
require.Equal(t, 1, calls)
|
|
|
|
require.Equal(t, clierr.Usage, clierr.ExitCode(Execute(context.Background(), deps, []string{"search", "issue", "--team", "devs"})))
|
|
require.Equal(t, clierr.Usage, clierr.ExitCode(Execute(context.Background(), deps, []string{"search", "issue", "-R", "team-org/repo", "--owner", "team-org", "--team", "devs"})))
|
|
require.Equal(t, 1, calls)
|
|
}
|
|
|
|
func TestSearchOwnerMatchesRepositoryCaseInsensitively(t *testing.T) {
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, "/api/v1/repos/Alice/project/issues", r.URL.Path)
|
|
require.Equal(t, "alice", r.URL.Query().Get("owner"))
|
|
_, _ = w.Write([]byte(`[]`))
|
|
}))
|
|
defer server.Close()
|
|
deps, _, _ := serverDeps(t, server.URL)
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"search", "issue", "-R", "Alice/project", "--owner", "alice", "--json"}))
|
|
err := Execute(context.Background(), deps, []string{"search", "issue", "-R", "Alice/project", "--owner", "bob", "--json"})
|
|
require.ErrorContains(t, err, "--owner conflicts with selected repository")
|
|
}
|
|
|
|
func TestSearchIssueAcceptsFlexibleTimeBounds(t *testing.T) {
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, "/api/v1/repos/issues/search", r.URL.Path)
|
|
query := r.URL.Query()
|
|
require.Equal(t, "2026-10-04T12:00:00Z", query.Get("since"))
|
|
require.Equal(t, "2026-10-05T12:00:00Z", query.Get("before"))
|
|
_, _ = w.Write([]byte(`[]`))
|
|
}))
|
|
defer server.Close()
|
|
deps, out, _ := serverDeps(t, server.URL)
|
|
deps.Now = func() time.Time { return time.Date(2026, 10, 5, 12, 0, 0, 0, time.UTC) }
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"search", "issue", "--since", "24h", "--before", "2026-10-05T12:00:00Z", "--json"}))
|
|
require.JSONEq(t, `[]`, out.String())
|
|
require.Equal(t, clierr.Usage, clierr.ExitCode(Execute(context.Background(), deps, []string{"search", "issue", "--since", "invalid"})))
|
|
}
|
|
|
|
func TestSearchTables(t *testing.T) {
|
|
var queries []string
|
|
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.Equal(t, "/api/v1/repos/issues/search", r.URL.Path)
|
|
queries = append(queries, r.URL.RawQuery)
|
|
if r.URL.Query().Get("q") == "nothing" {
|
|
_, _ = w.Write([]byte(`[]`))
|
|
return
|
|
}
|
|
w.Header().Set("X-Total-Count", "7")
|
|
_, _ = w.Write([]byte(`[{"number":14,"title":"Merged","state":"closed","pull_request":{"merged":true},"user":{"login":"bob"},"updated_at":"2026-10-11T18:00:00Z","repository":{"full_name":"alice/project"}},` +
|
|
`{"number":3,"title":"Open","state":"open","user":{"login":"alice"},"updated_at":"2026-10-10T20:00:00Z","repository":{"full_name":"acme/service"}}]`))
|
|
}))
|
|
defer server.Close()
|
|
deps, out, diagnostics := serverDeps(t, server.URL)
|
|
deps.Now = func() time.Time { return time.Date(2026, 10, 11, 20, 0, 0, 0, time.UTC) }
|
|
deps.Getenv = serverEnv(server.URL, map[string]string{"NO_COLOR": "1", "TEA_HYPERLINKS": "never"})
|
|
deps.Streams.OutTTY = true
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"search", "prs", "login", "-s", "all", "-L", "2", "--author", "@me"}))
|
|
host := strings.TrimPrefix(server.URL, "http://")
|
|
require.Equal(t, "Showing 2 of 7 pull requests matching \"login\" on "+host+" · next: --page 2\n\n"+
|
|
"REPO#ID TITLE STATE AUTHOR UPDATED\n"+
|
|
"alice/project#14 Merged merged bob about 2 hours ago\n"+
|
|
"acme/service#3 Open open alice about 1 day ago\n", out.String())
|
|
require.Contains(t, queries[0], "created_by=alice")
|
|
require.Contains(t, queries[0], "type=pulls")
|
|
out.Reset()
|
|
require.NoError(t, Execute(context.Background(), deps, []string{"search", "issues", "nothing"}))
|
|
require.Empty(t, out.String())
|
|
require.Equal(t, "no open issues matching \"nothing\" on "+host+"\n", diagnostics.String())
|
|
}
|