Add Validate func for Create/Edit Options (#370)

add TestLabels TEST

fix ...

impruve CreatePullReviewOptions Validate

some code refactor & reformat

add Validate functions where it make sence

add Validate() for CreateLabelOption

rm ToDo - not needed

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/go-sdk/pulls/370
Reviewed-by: techknowlogick <techknowlogick@gitea.io>
Reviewed-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
6543 2020-06-09 10:47:55 +00:00
parent 7f50d48c01
commit 5d880baff1
15 changed files with 348 additions and 40 deletions

40
gitea/Issue_label_test.go Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package gitea
import (
"log"
"testing"
"github.com/stretchr/testify/assert"
)
// TestLabels test label related func
func TestLabels(t *testing.T) {
log.Println("== TestLabels ==")
c := newTestClient()
repo, err := createTestRepo(t, "LabelTestsRepo", c)
assert.NoError(t, err)
createOpts := CreateLabelOption{
Name: " ",
Description: "",
Color: "",
}
err = createOpts.Validate()
assert.Error(t, err)
assert.EqualValues(t, "invalid color format", err.Error())
createOpts.Color = "12345f"
err = createOpts.Validate()
assert.Error(t, err)
assert.EqualValues(t, "empty name not allowed", err.Error())
createOpts.Name = "label one"
label1, err := c.CreateLabel(repo.Owner.UserName, repo.Name, createOpts)
assert.NoError(t, err)
assert.EqualValues(t, createOpts.Name, label1.Name)
assert.EqualValues(t, createOpts.Color, label1.Color)
}

View File

@ -35,8 +35,22 @@ type CreateUserOption struct {
SendNotify bool `json:"send_notify"`
}
// Validate the CreateUserOption struct
func (opt CreateUserOption) Validate() error {
if len(opt.Email) == 0 {
return fmt.Errorf("email is empty")
}
if len(opt.Username) == 0 {
return fmt.Errorf("username is empty")
}
return nil
}
// AdminCreateUser create a user
func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -64,8 +64,19 @@ type CreateHookOption struct {
Active bool `json:"active"`
}
// Validate the CreateHookOption struct
func (opt CreateHookOption) Validate() error {
if len(opt.Type) == 0 {
return fmt.Errorf("hook type needed")
}
return nil
}
// CreateOrgHook create one hook for an organization, with options
func (c *Client) CreateOrgHook(org string, opt CreateHookOption) (*Hook, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -174,8 +174,19 @@ type CreateIssueOption struct {
Closed bool `json:"closed"`
}
// Validate the CreateIssueOption struct
func (opt CreateIssueOption) Validate() error {
if len(strings.TrimSpace(opt.Title)) == 0 {
return fmt.Errorf("title is empty")
}
return nil
}
// CreateIssue create a new issue for a given repository
func (c *Client) CreateIssue(owner, repo string, opt CreateIssueOption) (*Issue, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -196,8 +207,19 @@ type EditIssueOption struct {
Deadline *time.Time `json:"due_date"`
}
// Validate the EditIssueOption struct
func (opt EditIssueOption) Validate() error {
if len(opt.Title) != 0 && len(strings.TrimSpace(opt.Title)) == 0 {
return fmt.Errorf("title is empty")
}
return nil
}
// EditIssue modify an existing issue for a given repository
func (c *Client) EditIssue(owner, repo string, index int64, opt EditIssueOption) (*Issue, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -77,8 +77,19 @@ type CreateIssueCommentOption struct {
Body string `json:"body"`
}
// Validate the CreateIssueCommentOption struct
func (opt CreateIssueCommentOption) Validate() error {
if len(opt.Body) == 0 {
return fmt.Errorf("body is empty")
}
return nil
}
// CreateIssueComment create comment on an issue.
func (c *Client) CreateIssueComment(owner, repo string, index int64, opt CreateIssueCommentOption) (*Comment, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -92,8 +103,19 @@ type EditIssueCommentOption struct {
Body string `json:"body"`
}
// Validate the EditIssueCommentOption struct
func (opt EditIssueCommentOption) Validate() error {
if len(opt.Body) == 0 {
return fmt.Errorf("body is empty")
}
return nil
}
// EditIssueComment edits an issue comment.
func (c *Client) EditIssueComment(owner, repo string, commentID int64, opt EditIssueCommentOption) (*Comment, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -8,6 +8,8 @@ import (
"bytes"
"encoding/json"
"fmt"
"regexp"
"strings"
)
// Label a label to an issue or a pr
@ -33,7 +35,6 @@ func (c *Client) ListRepoLabels(owner, repo string, opt ListLabelsOptions) ([]*L
}
// GetRepoLabel get one label of repository by repo it
// TODO: maybe we need get a label by name
func (c *Client) GetRepoLabel(owner, repo string, id int64) (*Label, error) {
label := new(Label)
return label, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil, label)
@ -47,8 +48,26 @@ type CreateLabelOption struct {
Description string `json:"description"`
}
// Validate the CreateLabelOption struct
func (opt CreateLabelOption) Validate() error {
aw, err := regexp.MatchString("^#?[0-9,a-f,A-F]{6}$", opt.Color)
if err != nil {
return err
}
if !aw {
return fmt.Errorf("invalid color format")
}
if len(strings.TrimSpace(opt.Name)) == 0 {
return fmt.Errorf("empty name not allowed")
}
return nil
}
// CreateLabel create one label of repository
func (c *Client) CreateLabel(owner, repo string, opt CreateLabelOption) (*Label, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
if len(opt.Color) == 6 {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
opt.Color = "#" + opt.Color
@ -70,8 +89,30 @@ type EditLabelOption struct {
Description *string `json:"description"`
}
// Validate the EditLabelOption struct
func (opt EditLabelOption) Validate() error {
if opt.Color != nil {
aw, err := regexp.MatchString("^#?[0-9,a-f,A-F]{6}$", *opt.Color)
if err != nil {
return err
}
if !aw {
return fmt.Errorf("invalid color format")
}
}
if opt.Name != nil {
if len(strings.TrimSpace(*opt.Name)) == 0 {
return fmt.Errorf("empty name not allowed")
}
}
return nil
}
// EditLabel modify one label with options
func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*Label, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -81,7 +122,6 @@ func (c *Client) EditLabel(owner, repo string, id int64, opt EditLabelOption) (*
}
// DeleteLabel delete one label of repository by id
// TODO: maybe we need delete by name
func (c *Client) DeleteLabel(owner, repo string, id int64) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/labels/%d", owner, repo, id), nil, nil)
return err

View File

@ -9,6 +9,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"strings"
"time"
)
@ -63,8 +64,19 @@ type CreateMilestoneOption struct {
Deadline *time.Time `json:"due_on"`
}
// Validate the CreateMilestoneOption struct
func (opt CreateMilestoneOption) Validate() error {
if len(strings.TrimSpace(opt.Title)) == 0 {
return fmt.Errorf("title is empty")
}
return nil
}
// CreateMilestone create one milestone with options
func (c *Client) CreateMilestone(owner, repo string, opt CreateMilestoneOption) (*Milestone, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -81,8 +93,19 @@ type EditMilestoneOption struct {
Deadline *time.Time `json:"due_on"`
}
// Validate the EditMilestoneOption struct
func (opt EditMilestoneOption) Validate() error {
if len(opt.Title) != 0 && len(strings.TrimSpace(opt.Title)) == 0 {
return fmt.Errorf("title is empty")
}
return nil
}
// EditMilestone modify milestone with options
func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOption) (*Milestone, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -46,15 +46,26 @@ func (c *Client) GetMyTrackedTimes() ([]*TrackedTime, error) {
// AddTimeOption options for adding time to an issue
type AddTimeOption struct {
// time in seconds
Time int64 `json:"time" binding:"Required"`
Time int64 `json:"time"`
// optional
Created time.Time `json:"created"`
// optional
User string `json:"user_name"`
}
// Validate the AddTimeOption struct
func (opt AddTimeOption) Validate() error {
if opt.Time == 0 {
return fmt.Errorf("no time to add")
}
return nil
}
// AddTime adds time to issue with the given index
func (c *Client) AddTime(owner, repo string, index int64, opt AddTimeOption) (*TrackedTime, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -56,12 +56,30 @@ type CreateOrgOption struct {
Website string `json:"website"`
Location string `json:"location"`
// possible values are `public` (default), `limited` or `private`
// enum: public,limited,private
Visibility string `json:"visibility"`
}
// checkVisibilityOpt check if mode exist
func checkVisibilityOpt(v string) bool {
return v == "public" || v == "limited" || v == "private"
}
// Validate the CreateOrgOption struct
func (opt CreateOrgOption) Validate() error {
if len(opt.UserName) == 0 {
return fmt.Errorf("empty org name")
}
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
return fmt.Errorf("infalid bisibility option")
}
return nil
}
// CreateOrg creates an organization
func (c *Client) CreateOrg(opt CreateOrgOption) (*Organization, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -77,12 +95,22 @@ type EditOrgOption struct {
Website string `json:"website"`
Location string `json:"location"`
// possible values are `public`, `limited` or `private`
// enum: public,limited,private
Visibility string `json:"visibility"`
}
// Validate the EditOrgOption struct
func (opt EditOrgOption) Validate() error {
if len(opt.Visibility) != 0 && !checkVisibilityOpt(opt.Visibility) {
return fmt.Errorf("infalid bisibility option")
}
return nil
}
// EditOrg modify one organization via options
func (c *Client) EditOrg(orgname string, opt EditOrgOption) error {
if err := opt.Validate(); err != nil {
return err
}
body, err := json.Marshal(&opt)
if err != nil {
return err
@ -93,6 +121,6 @@ func (c *Client) EditOrg(orgname string, opt EditOrgOption) error {
// DeleteOrg deletes an organization
func (c *Client) DeleteOrg(orgname string) error {
_, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s", orgname), nil, nil)
_, err := c.getResponse("DELETE", fmt.Sprintf("/orgs/%s", orgname), jsonHeader, nil)
return err
}

View File

@ -10,6 +10,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"strings"
"time"
)
@ -149,8 +150,24 @@ type EditPullRequestOption struct {
Deadline *time.Time `json:"due_date"`
}
// Validate the EditPullRequestOption struct
func (opt EditPullRequestOption) Validate(c *Client) error {
if len(opt.Title) != 0 && len(strings.TrimSpace(opt.Title)) == 0 {
return fmt.Errorf("title is empty")
}
if len(opt.Base) != 0 {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return fmt.Errorf("can not change base gitea to old")
}
}
return nil
}
// EditPullRequest modify pull request with PR id and options
func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRequestOption) (*PullRequest, error) {
if err := opt.Validate(c); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -167,13 +184,21 @@ type MergePullRequestOption struct {
Message string `json:"MergeMessageField"`
}
// MergePullRequest merge a PR to repository by PR id
func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePullRequestOption) (bool, error) {
// Validate the MergePullRequestOption struct
func (opt MergePullRequestOption) Validate(c *Client) error {
if opt.Style == MergeStyleSquash {
if err := c.CheckServerVersionConstraint(">=1.11.5"); err != nil {
return false, err
return err
}
}
return nil
}
// MergePullRequest merge a PR to repository by PR id
func (c *Client) MergePullRequest(owner, repo string, index int64, opt MergePullRequestOption) (bool, error) {
if err := opt.Validate(c); err != nil {
return false, err
}
body, err := json.Marshal(&opt)
if err != nil {
return false, err

View File

@ -9,6 +9,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"strings"
"time"
)
@ -40,8 +41,7 @@ type PullReview struct {
Stale bool `json:"stale"`
Official bool `json:"official"`
CodeCommentsCount int `json:"comments_count"`
// swagger:strfmt date-time
Submitted time.Time `json:"submitted_at"`
Submitted time.Time `json:"submitted_at"`
HTMLURL string `json:"html_url"`
HTMLPullURL string `json:"pull_request_url"`
@ -54,9 +54,7 @@ type PullReviewComment struct {
Reviewer *User `json:"user"`
ReviewID int64 `json:"pull_request_review_id"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
Path string `json:"path"`
@ -100,6 +98,38 @@ type ListPullReviewsOptions struct {
ListOptions
}
// Validate the CreatePullReviewOptions struct
func (opt CreatePullReviewOptions) Validate() error {
if opt.State != ReviewStateApproved && len(strings.TrimSpace(opt.Body)) == 0 {
return fmt.Errorf("body is empty")
}
for i := range opt.Comments {
if err := opt.Comments[i].Validate(); err != nil {
return err
}
}
return nil
}
// Validate the SubmitPullReviewOptions struct
func (opt SubmitPullReviewOptions) Validate() error {
if opt.State != ReviewStateApproved && len(strings.TrimSpace(opt.Body)) == 0 {
return fmt.Errorf("body is empty")
}
return nil
}
// Validate the CreatePullReviewComment struct
func (opt CreatePullReviewComment) Validate() error {
if len(strings.TrimSpace(opt.Body)) == 0 {
return fmt.Errorf("body is empty")
}
if opt.NewLineNum != 0 && opt.OldLineNum != 0 {
return fmt.Errorf("old and new line num are set, cant identify the code comment position")
}
return nil
}
// ListPullReviews lists all reviews of a pull request
func (c *Client) ListPullReviews(owner, repo string, index int64, opt ListPullReviewsOptions) ([]*PullReview, error) {
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
@ -158,6 +188,9 @@ func (c *Client) CreatePullReview(owner, repo string, index int64, opt CreatePul
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err
}
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -173,6 +206,9 @@ func (c *Client) SubmitPullReview(owner, repo string, index, id int64, opt Submi
if err := c.CheckServerVersionConstraint(">=1.12.0"); err != nil {
return nil, err
}
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -8,6 +8,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"strings"
"time"
)
@ -63,9 +64,20 @@ type CreateReleaseOption struct {
IsPrerelease bool `json:"prerelease"`
}
// Validate the CreateReleaseOption struct
func (opt CreateReleaseOption) Validate() error {
if len(strings.TrimSpace(opt.Title)) == 0 {
return fmt.Errorf("title is empty")
}
return nil
}
// CreateRelease create a release
func (c *Client) CreateRelease(user, repo string, form CreateReleaseOption) (*Release, error) {
body, err := json.Marshal(form)
func (c *Client) CreateRelease(user, repo string, opt CreateReleaseOption) (*Release, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(opt)
if err != nil {
return nil, err
}

View File

@ -9,6 +9,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"strings"
"time"
)
@ -161,7 +162,6 @@ func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, error) {
// CreateRepoOption options when creating repository
type CreateRepoOption struct {
// Name of the repository to create
//
Name string `json:"name"`
// Description of the repository to create
Description string `json:"description"`
@ -181,8 +181,19 @@ type CreateRepoOption struct {
DefaultBranch string `json:"default_branch"`
}
// Validate the CreateRepoOption struct
func (opt CreateRepoOption) Validate() error {
if len(strings.TrimSpace(opt.Name)) == 0 {
return fmt.Errorf("name is empty")
}
return nil
}
// CreateRepo creates a repository for authenticated user.
func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err
@ -193,6 +204,9 @@ func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, error) {
// CreateOrgRepo creates an organization repository for authenticated user.
func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, error) {
if err := opt.Validate(); err != nil {
return nil, err
}
body, err := json.Marshal(&opt)
if err != nil {
return nil, err

View File

@ -14,30 +14,28 @@ import (
// BranchProtection represents a branch protection for a repository
type BranchProtection struct {
BranchName string `json:"branch_name"`
EnablePush bool `json:"enable_push"`
EnablePushWhitelist bool `json:"enable_push_whitelist"`
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
PushWhitelistTeams []string `json:"push_whitelist_teams"`
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
EnableStatusCheck bool `json:"enable_status_check"`
StatusCheckContexts []string `json:"status_check_contexts"`
RequiredApprovals int64 `json:"required_approvals"`
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
RequireSignedCommits bool `json:"require_signed_commits"`
ProtectedFilePatterns string `json:"protected_file_patterns"`
// swagger:strfmt date-time
Created time.Time `json:"created_at"`
// swagger:strfmt date-time
Updated time.Time `json:"updated_at"`
BranchName string `json:"branch_name"`
EnablePush bool `json:"enable_push"`
EnablePushWhitelist bool `json:"enable_push_whitelist"`
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
PushWhitelistTeams []string `json:"push_whitelist_teams"`
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
MergeWhitelistTeams []string `json:"merge_whitelist_teams"`
EnableStatusCheck bool `json:"enable_status_check"`
StatusCheckContexts []string `json:"status_check_contexts"`
RequiredApprovals int64 `json:"required_approvals"`
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"`
BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"`
BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"`
DismissStaleApprovals bool `json:"dismiss_stale_approvals"`
RequireSignedCommits bool `json:"require_signed_commits"`
ProtectedFilePatterns string `json:"protected_file_patterns"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
}
// CreateBranchProtectionOption options for creating a branch protection

View File

@ -41,8 +41,20 @@ type AddCollaboratorOption struct {
Permission *string `json:"permission"`
}
// Validate the AddCollaboratorOption struct
func (opt AddCollaboratorOption) Validate() error {
if opt.Permission != nil &&
*opt.Permission != "read" && *opt.Permission != "write" && *opt.Permission != "admin" {
return fmt.Errorf("permission mode invalid")
}
return nil
}
// AddCollaborator add some user as a collaborator of a repository
func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollaboratorOption) error {
if err := opt.Validate(); err != nil {
return err
}
body, err := json.Marshal(&opt)
if err != nil {
return err