Files
gitea-tea/internal/services/issues_test.go
T
2026-10-18 17:41:33 +02:00

119 lines
5.2 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package services
import (
"context"
"encoding/json"
"net/http"
"net/url"
"testing"
"time"
gitea "gitea.dev/sdk"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIssueListSendsTypePageSizeAndFilters(t *testing.T) {
var queries []url.Values
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/api/v1/repos/alice/project/issues", r.URL.Path)
queries = append(queries, r.URL.Query())
_, _ = w.Write([]byte(`[{"id":1,"number":2,"title":"Bug","user":{"login":"bob"}}]`))
}))
service := Issues{Client: client, Repository: "alice/project"}
items, more, err := service.List(context.Background(), ListOptions{State: "open", Limit: 1, Page: 3})
require.NoError(t, err)
require.False(t, more)
require.Equal(t, []Issue{{Author: "bob", ID: 1, Number: 2, Kind: KindIssue, Title: "Bug", Labels: []Label{}, Assignees: []string{}}}, items)
since := time.Date(2026, 10, 1, 8, 0, 0, 0, time.UTC)
_, _, err = service.List(context.Background(), ListOptions{
Kind: "all", Limit: 30, Page: 1, Search: "crash", Assignee: "carol", Labels: "bug,ui", Milestones: "v1",
Author: "dave", Mentions: "erin", Since: &since,
})
require.NoError(t, err)
require.Equal(t, []url.Values{
{"state": {"open"}, "type": {"issues"}, "limit": {"1"}, "page": {"3"}},
{
"type": {"all"}, "limit": {"30"}, "page": {"1"}, "q": {"crash"}, "assigned_by": {"carol"}, "labels": {"bug,ui"},
"milestones": {"v1"}, "created_by": {"dave"}, "mentioned_by": {"erin"}, "since": {"2026-10-01T08:00:00Z"},
},
}, queries)
}
func TestIssueDependenciesMapReferencesAndTreatMissingSupportAsNone(t *testing.T) {
missing := false
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if missing {
w.WriteHeader(http.StatusNotFound)
return
}
assert.Equal(t, "50", r.URL.Query().Get("limit"))
if r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`[]`))
return
}
switch r.URL.Path {
case "/api/v1/repos/alice/project/issues/7/dependencies":
_, _ = w.Write([]byte(`[{"number":3,"repository":{"full_name":"alice/other"}},{"number":0,"repository":null}]`))
case "/api/v1/repos/alice/project/issues/7/blocks":
_, _ = w.Write([]byte(`[{"number":9,"repository":{"full_name":"alice/project"}}]`))
default:
t.Errorf("unexpected path %s", r.URL.Path)
}
}))
service := Issues{Client: client, Repository: "alice/project"}
dependencies, err := service.Dependencies(context.Background(), 7)
require.NoError(t, err)
require.Equal(t, IssueDependencies{
BlockedBy: []IssueReference{{Repository: "alice/other", Number: 3}, {}},
Blocks: []IssueReference{{Repository: "alice/project", Number: 9}},
}, dependencies)
missing = true
dependencies, err = service.Dependencies(context.Background(), 7)
require.NoError(t, err)
require.Equal(t, IssueDependencies{}, dependencies)
}
func TestDiscussionsTellPullRequestsAndMergesApart(t *testing.T) {
list := `[{"number":1,"state":"open"},{"number":2,"state":"closed","pull_request":{"merged":false}},` +
`{"number":3,"state":"closed","pull_request":{"merged":true}},{"number":4,"state":"open","pull_request":{"merged":false}}]`
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(list))
}))
want := []struct{ kind, state string }{{KindIssue, "open"}, {KindPull, "closed"}, {KindPull, "merged"}, {KindPull, "open"}}
issues, _, err := (Issues{Client: client, Repository: "alice/project"}).List(context.Background(), ListOptions{Kind: "all", State: "all", Limit: 30, Page: 1})
require.NoError(t, err)
found, err := (Issues{Client: client, Repository: "alice/project"}).Search(context.Background(), DiscussionSearchOptions{State: "all", Limit: 30, Page: 1})
require.NoError(t, err)
require.Len(t, issues, len(want))
for i, item := range want {
require.Equal(t, item.kind, issues[i].Kind, issues[i].Number)
require.Equal(t, item.state, issues[i].State, issues[i].Number)
require.Equal(t, item.state, found[i].State, found[i].Number)
}
}
func TestIssueTemplatesAcceptCheckboxOptionObjects(t *testing.T) {
body := `[{"name":"Form","body":[{"type":"checkboxes","attributes":{"options":[{"label":"I searched","required":true}]}}]}]`
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte(body))
}))
templates, err := (Issues{Client: client, Repository: "alice/project"}).IssueTemplates(context.Background())
require.NoError(t, err)
require.Equal(t, []IssueTemplate{{Name: "Form", Form: true}}, templates)
var sdkTemplates []*gitea.IssueTemplate
require.Error(t, json.Unmarshal([]byte(body), &sdkTemplates), "remove the raw request once the SDK decodes checkbox options")
}
func TestIssueCreateInMissingRepositoryReportsTheRepository(t *testing.T) {
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusNotFound)
_, _ = w.Write([]byte(`{"message":"not found"}`))
}))
_, err := (Issues{Client: client, Repository: "alice/projetc"}).Create(context.Background(), IssueOptions{Title: "x"})
require.EqualError(t, err, "repository alice/projetc not found")
}