// 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, 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 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") }