feat(gitea): add issue mutation helpers
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
5a561690be
commit
9a0a1f4435
3 changed files with 254 additions and 8 deletions
|
|
@ -133,6 +133,41 @@ func (c *Client) CreateIssue(owner, repo string, opts gitea.CreateIssueOption) (
|
|||
return issue, nil
|
||||
}
|
||||
|
||||
// EditIssue edits an existing issue.
|
||||
// Usage: EditIssue(...)
|
||||
func (c *Client) EditIssue(owner, repo string, number int64, opts gitea.EditIssueOption) (*gitea.Issue, error) {
|
||||
issue, _, err := c.api.EditIssue(owner, repo, number, opts)
|
||||
if err != nil {
|
||||
return nil, log.E("gitea.EditIssue", "failed to edit issue", err)
|
||||
}
|
||||
|
||||
return issue, nil
|
||||
}
|
||||
|
||||
// AssignIssue assigns an issue to the specified users.
|
||||
// Usage: AssignIssue(...)
|
||||
func (c *Client) AssignIssue(owner, repo string, number int64, assignees []string) error {
|
||||
_, _, err := c.api.EditIssue(owner, repo, number, gitea.EditIssueOption{
|
||||
Assignees: assignees,
|
||||
})
|
||||
if err != nil {
|
||||
return log.E("gitea.AssignIssue", "failed to assign issue", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateIssueComment posts a comment on an issue or pull request.
|
||||
// Usage: CreateIssueComment(...)
|
||||
func (c *Client) CreateIssueComment(owner, repo string, issue int64, body string) error {
|
||||
_, _, err := c.api.CreateIssueComment(owner, repo, issue, gitea.CreateIssueCommentOption{
|
||||
Body: body,
|
||||
})
|
||||
if err != nil {
|
||||
return log.E("gitea.CreateIssueComment", "failed to create comment", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListIssueComments returns all comments for an issue.
|
||||
// Usage: ListIssueComments(...)
|
||||
func (c *Client) ListIssueComments(owner, repo string, number int64) ([]*gitea.Comment, error) {
|
||||
|
|
@ -253,6 +288,52 @@ func (c *Client) ListIssueCommentsIter(owner, repo string, number int64) iter.Se
|
|||
}
|
||||
}
|
||||
|
||||
// GetIssueLabels returns the labels currently attached to an issue.
|
||||
// Usage: GetIssueLabels(...)
|
||||
func (c *Client) GetIssueLabels(owner, repo string, number int64) ([]*gitea.Label, error) {
|
||||
labels, _, err := c.api.GetIssueLabels(owner, repo, number, gitea.ListLabelsOptions{})
|
||||
if err != nil {
|
||||
return nil, log.E("gitea.GetIssueLabels", "failed to get issue labels", err)
|
||||
}
|
||||
|
||||
return labels, nil
|
||||
}
|
||||
|
||||
// AddIssueLabels adds labels to an issue.
|
||||
// Usage: AddIssueLabels(...)
|
||||
func (c *Client) AddIssueLabels(owner, repo string, number int64, labelIDs []int64) error {
|
||||
_, _, err := c.api.AddIssueLabels(owner, repo, number, gitea.IssueLabelsOption{
|
||||
Labels: labelIDs,
|
||||
})
|
||||
if err != nil {
|
||||
return log.E("gitea.AddIssueLabels", "failed to add labels to issue", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveIssueLabel removes a label from an issue.
|
||||
// Usage: RemoveIssueLabel(...)
|
||||
func (c *Client) RemoveIssueLabel(owner, repo string, number, labelID int64) error {
|
||||
_, err := c.api.DeleteIssueLabel(owner, repo, number, labelID)
|
||||
if err != nil {
|
||||
return log.E("gitea.RemoveIssueLabel", "failed to remove label from issue", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseIssue closes an issue by setting its state to closed.
|
||||
// Usage: CloseIssue(...)
|
||||
func (c *Client) CloseIssue(owner, repo string, number int64) error {
|
||||
closed := gitea.StateClosed
|
||||
_, _, err := c.api.EditIssue(owner, repo, number, gitea.EditIssueOption{
|
||||
State: &closed,
|
||||
})
|
||||
if err != nil {
|
||||
return log.E("gitea.CloseIssue", "failed to close issue", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPullRequest returns a single pull request by number.
|
||||
// Usage: GetPullRequest(...)
|
||||
func (c *Client) GetPullRequest(owner, repo string, number int64) (*gitea.PullRequest, error) {
|
||||
|
|
|
|||
|
|
@ -234,6 +234,132 @@ func TestClient_CreateIssue_Bad_ServerError_Good(t *testing.T) {
|
|||
assert.Contains(t, err.Error(), "failed to create issue")
|
||||
}
|
||||
|
||||
func TestClient_EditIssue_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
issue, err := client.EditIssue("test-org", "org-repo", 1, giteaSDK.EditIssueOption{
|
||||
Title: "Updated Title",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, issue)
|
||||
}
|
||||
|
||||
func TestClient_EditIssue_Bad_ServerError_Good(t *testing.T) {
|
||||
client, srv := newErrorServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
_, err := client.EditIssue("test-org", "org-repo", 1, giteaSDK.EditIssueOption{
|
||||
Title: "Updated Title",
|
||||
})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to edit issue")
|
||||
}
|
||||
|
||||
func TestClient_AssignIssue_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.AssignIssue("test-org", "org-repo", 1, []string{"dev1", "dev2"})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_AssignIssue_Bad_ServerError_Good(t *testing.T) {
|
||||
client, srv := newErrorServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.AssignIssue("test-org", "org-repo", 1, []string{"dev1"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to assign issue")
|
||||
}
|
||||
|
||||
func TestClient_CreateIssueComment_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.CreateIssueComment("test-org", "org-repo", 1, "LGTM")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_CreateIssueComment_Bad_ServerError_Good(t *testing.T) {
|
||||
client, srv := newErrorServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.CreateIssueComment("test-org", "org-repo", 1, "LGTM")
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to create comment")
|
||||
}
|
||||
|
||||
func TestClient_GetIssueLabels_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
labels, err := client.GetIssueLabels("test-org", "org-repo", 1)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, labels, 1)
|
||||
assert.Equal(t, "bug", labels[0].Name)
|
||||
}
|
||||
|
||||
func TestClient_GetIssueLabels_Bad_ServerError_Good(t *testing.T) {
|
||||
client, srv := newErrorServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
_, err := client.GetIssueLabels("test-org", "org-repo", 1)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to get issue labels")
|
||||
}
|
||||
|
||||
func TestClient_AddIssueLabels_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.AddIssueLabels("test-org", "org-repo", 1, []int64{1})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_AddIssueLabels_Bad_ServerError_Good(t *testing.T) {
|
||||
client, srv := newErrorServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.AddIssueLabels("test-org", "org-repo", 1, []int64{1})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to add labels to issue")
|
||||
}
|
||||
|
||||
func TestClient_RemoveIssueLabel_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.RemoveIssueLabel("test-org", "org-repo", 1, 1)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_RemoveIssueLabel_Bad_ServerError_Good(t *testing.T) {
|
||||
client, srv := newErrorServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.RemoveIssueLabel("test-org", "org-repo", 1, 1)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to remove label from issue")
|
||||
}
|
||||
|
||||
func TestClient_CloseIssue_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.CloseIssue("test-org", "org-repo", 1)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_CloseIssue_Bad_ServerError_Good(t *testing.T) {
|
||||
client, srv := newErrorServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
err := client.CloseIssue("test-org", "org-repo", 1)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to close issue")
|
||||
}
|
||||
|
||||
func TestClient_ListPullRequests_Good(t *testing.T) {
|
||||
client, srv := newTestClient(t)
|
||||
defer srv.Close()
|
||||
|
|
|
|||
|
|
@ -85,18 +85,57 @@ func newGiteaMux() *http.ServeMux {
|
|||
|
||||
// Single issue.
|
||||
mux.HandleFunc("/api/v1/repos/test-org/org-repo/issues/1", func(w http.ResponseWriter, r *http.Request) {
|
||||
jsonResponse(w, map[string]any{
|
||||
"id": 1, "number": 1, "title": "Issue 1", "state": "open",
|
||||
"body": "First issue body",
|
||||
})
|
||||
switch r.Method {
|
||||
case http.MethodPatch:
|
||||
jsonResponse(w, map[string]any{
|
||||
"id": 1, "number": 1, "title": "Issue 1", "state": "closed",
|
||||
"body": "First issue body",
|
||||
})
|
||||
default:
|
||||
jsonResponse(w, map[string]any{
|
||||
"id": 1, "number": 1, "title": "Issue 1", "state": "open",
|
||||
"body": "First issue body",
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Issue comments.
|
||||
mux.HandleFunc("/api/v1/repos/test-org/org-repo/issues/1/comments", func(w http.ResponseWriter, r *http.Request) {
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 100, "body": "comment 1", "user": map[string]any{"login": "user1"}, "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z"},
|
||||
{"id": 101, "body": "comment 2", "user": map[string]any{"login": "user2"}, "created_at": "2026-01-02T00:00:00Z", "updated_at": "2026-01-02T00:00:00Z"},
|
||||
})
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
jsonResponse(w, map[string]any{
|
||||
"id": 100, "body": "test comment",
|
||||
"user": map[string]any{"login": "test-user"},
|
||||
})
|
||||
default:
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 100, "body": "comment 1", "user": map[string]any{"login": "user1"}, "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z"},
|
||||
{"id": 101, "body": "comment 2", "user": map[string]any{"login": "user2"}, "created_at": "2026-01-02T00:00:00Z", "updated_at": "2026-01-02T00:00:00Z"},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Issue labels.
|
||||
mux.HandleFunc("/api/v1/repos/test-org/org-repo/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 1, "name": "bug", "color": "#ff0000"},
|
||||
})
|
||||
default:
|
||||
jsonResponse(w, []map[string]any{
|
||||
{"id": 1, "name": "bug", "color": "#ff0000"},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Remove issue label.
|
||||
mux.HandleFunc("/api/v1/repos/test-org/org-repo/issues/1/labels/1", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodDelete {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
// Pull requests.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue