diff --git a/repos.go b/repos.go index 99333ac..6f7976e 100644 --- a/repos.go +++ b/repos.go @@ -374,6 +374,26 @@ func (s *RepoService) ListIssueTemplates(ctx context.Context, owner, repo string return ListAll[types.IssueTemplate](ctx, s.client, path, nil) } +// GetIssueConfig returns the issue config for a repository. +func (s *RepoService) GetIssueConfig(ctx context.Context, owner, repo string) (*types.IssueConfig, error) { + path := ResolvePath("/api/v1/repos/{owner}/{repo}/issue_config", pathParams("owner", owner, "repo", repo)) + var out types.IssueConfig + if err := s.client.Get(ctx, path, &out); err != nil { + return nil, err + } + return &out, nil +} + +// ValidateIssueConfig returns the validation information for a repository's issue config. +func (s *RepoService) ValidateIssueConfig(ctx context.Context, owner, repo string) (*types.IssueConfigValidation, error) { + path := ResolvePath("/api/v1/repos/{owner}/{repo}/issue_config/validate", pathParams("owner", owner, "repo", repo)) + var out types.IssueConfigValidation + if err := s.client.Get(ctx, path, &out); err != nil { + return nil, err + } + return &out, nil +} + // ListActivityFeeds returns the repository's activity feed entries. func (s *RepoService) ListActivityFeeds(ctx context.Context, owner, repo string, filters ...ActivityFeedListOptions) ([]types.Activity, error) { path := ResolvePath("/api/v1/repos/{owner}/{repo}/activities/feeds", pathParams("owner", owner, "repo", repo)) diff --git a/repos_test.go b/repos_test.go index 81208bc..c9aaa36 100644 --- a/repos_test.go +++ b/repos_test.go @@ -837,6 +837,67 @@ func TestRepoService_ListIssueTemplates_Good(t *testing.T) { } } +func TestRepoService_GetIssueConfig_Good(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Errorf("expected GET, got %s", r.Method) + } + if r.URL.Path != "/api/v1/repos/core/go-forge/issue_config" { + t.Errorf("wrong path: %s", r.URL.Path) + http.NotFound(w, r) + return + } + json.NewEncoder(w).Encode(types.IssueConfig{ + BlankIssuesEnabled: true, + ContactLinks: []*types.IssueConfigContactLink{{ + Name: "Security", + URL: "https://example.com/security", + About: "Report a vulnerability", + }}, + }) + })) + defer srv.Close() + + f := NewForge(srv.URL, "tok") + cfg, err := f.Repos.GetIssueConfig(context.Background(), "core", "go-forge") + if err != nil { + t.Fatal(err) + } + if !cfg.BlankIssuesEnabled { + t.Fatalf("expected blank issues to be enabled, got %#v", cfg) + } + if len(cfg.ContactLinks) != 1 || cfg.ContactLinks[0].Name != "Security" { + t.Fatalf("got %#v", cfg.ContactLinks) + } +} + +func TestRepoService_ValidateIssueConfig_Good(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Errorf("expected GET, got %s", r.Method) + } + if r.URL.Path != "/api/v1/repos/core/go-forge/issue_config/validate" { + t.Errorf("wrong path: %s", r.URL.Path) + http.NotFound(w, r) + return + } + json.NewEncoder(w).Encode(types.IssueConfigValidation{ + Valid: false, + Message: "invalid contact link URL", + }) + })) + defer srv.Close() + + f := NewForge(srv.URL, "tok") + result, err := f.Repos.ValidateIssueConfig(context.Background(), "core", "go-forge") + if err != nil { + t.Fatal(err) + } + if result.Valid || result.Message != "invalid contact link URL" { + t.Fatalf("got %#v", result) + } +} + func TestRepoService_GetNewPinAllowed_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet {