diff --git a/modules/structs/activity.go b/modules/structs/activity.go index 9085495593a8e..b896adfed529f 100644 --- a/modules/structs/activity.go +++ b/modules/structs/activity.go @@ -12,7 +12,7 @@ type Activity struct { UserID int64 `json:"user_id"` // Receiver user // the type of action // - // enum: create_repo,rename_repo,star_repo,watch_repo,commit_repo,create_issue,create_pull_request,transfer_repo,push_tag,comment_issue,merge_pull_request,close_issue,reopen_issue,close_pull_request,reopen_pull_request,delete_tag,delete_branch,mirror_sync_push,mirror_sync_create,mirror_sync_delete,approve_pull_request,reject_pull_request,comment_pull,publish_release,pull_review_dismissed,pull_request_ready_for_review,auto_merge_pull_request + // enum: ["create_repo","rename_repo","star_repo","watch_repo","commit_repo","create_issue","create_pull_request","transfer_repo","push_tag","comment_issue","merge_pull_request","close_issue","reopen_issue","close_pull_request","reopen_pull_request","delete_tag","delete_branch","mirror_sync_push","mirror_sync_create","mirror_sync_delete","approve_pull_request","reject_pull_request","comment_pull","publish_release","pull_review_dismissed","pull_request_ready_for_review","auto_merge_pull_request"] OpType string `json:"op_type"` // The ID of the user who performed the action ActUserID int64 `json:"act_user_id"` diff --git a/modules/structs/hook.go b/modules/structs/hook.go index 57af38464a2f3..931589696a6ce 100644 --- a/modules/structs/hook.go +++ b/modules/structs/hook.go @@ -51,7 +51,7 @@ type CreateHookOptionConfig map[string]string // CreateHookOption options when create a hook type CreateHookOption struct { // required: true - // enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist + // enum: ["dingtalk","discord","gitea","gogs","msteams","slack","telegram","feishu","wechatwork","packagist"] // The type of the webhook to create Type string `json:"type" binding:"Required"` // required: true diff --git a/modules/structs/issue.go b/modules/structs/issue.go index 2540481d0ffcc..1efe3334ca300 100644 --- a/modules/structs/issue.go +++ b/modules/structs/issue.go @@ -14,6 +14,8 @@ import ( ) // StateType issue state type +// +// swagger:enum StateType type StateType string const ( @@ -21,10 +23,11 @@ const ( StateOpen StateType = "open" // StateClosed pr is closed StateClosed StateType = "closed" - // StateAll is all - StateAll StateType = "all" ) +// StateAll is a query parameter filter value, not a valid object state. +const StateAll = "all" + // PullRequestMeta PR info if an issue is a PR type PullRequestMeta struct { HasMerged bool `json:"merged"` @@ -58,15 +61,11 @@ type Issue struct { Labels []*Label `json:"labels"` Milestone *Milestone `json:"milestone"` // deprecated - Assignee *User `json:"assignee"` - Assignees []*User `json:"assignees"` - // Whether the issue is open or closed - // - // type: string - // enum: open,closed - State StateType `json:"state"` - IsLocked bool `json:"is_locked"` - Comments int `json:"comments"` + Assignee *User `json:"assignee"` + Assignees []*User `json:"assignees"` + State StateType `json:"state"` + IsLocked bool `json:"is_locked"` + Comments int `json:"comments"` // swagger:strfmt date-time Created time.Time `json:"created_at"` // swagger:strfmt date-time @@ -132,6 +131,8 @@ type IssueDeadline struct { } // IssueFormFieldType defines issue form field type, can be "markdown", "textarea", "input", "dropdown" or "checkboxes" +// +// swagger:enum IssueFormFieldType type IssueFormFieldType string const ( @@ -168,7 +169,8 @@ func (iff IssueFormField) VisibleInContent() bool { } // IssueFormFieldVisible defines issue form field visible -// swagger:model +// +// swagger:enum IssueFormFieldVisible type IssueFormFieldVisible string const ( diff --git a/modules/structs/issue_milestone.go b/modules/structs/issue_milestone.go index 226c613d47be6..dd8bdc6cda741 100644 --- a/modules/structs/issue_milestone.go +++ b/modules/structs/issue_milestone.go @@ -40,7 +40,7 @@ type CreateMilestoneOption struct { // swagger:strfmt date-time // Deadline is the due date for the milestone Deadline *time.Time `json:"due_on"` - // enum: open,closed + // enum: ["open","closed"] // State indicates the initial state of the milestone State string `json:"state"` } @@ -52,6 +52,7 @@ type EditMilestoneOption struct { // Description provides updated details about the milestone Description *string `json:"description"` // State indicates the updated state of the milestone + // enum: ["open","closed"] State *string `json:"state"` // Deadline is the updated due date for the milestone Deadline *time.Time `json:"due_on"` diff --git a/modules/structs/notifications.go b/modules/structs/notifications.go index cee5da6624d88..d7aa0783dc26b 100644 --- a/modules/structs/notifications.go +++ b/modules/structs/notifications.go @@ -40,7 +40,7 @@ type NotificationSubject struct { // Type indicates the type of the notification subject Type NotifySubjectType `json:"type" binding:"In(Issue,Pull,Commit,Repository)"` // State indicates the current state of the notification subject - State StateType `json:"state"` + State NotifySubjectStateType `json:"state"` } // NotificationCount number of unread notifications @@ -49,7 +49,22 @@ type NotificationCount struct { New int64 `json:"new"` } +// NotifySubjectStateType represents the state of a notification subject +// swagger:enum NotifySubjectStateType +type NotifySubjectStateType string + +const ( + // NotifySubjectStateOpen is an open subject + NotifySubjectStateOpen NotifySubjectStateType = "open" + // NotifySubjectStateClosed is a closed subject + NotifySubjectStateClosed NotifySubjectStateType = "closed" + // NotifySubjectStateMerged is a merged pull request + NotifySubjectStateMerged NotifySubjectStateType = "merged" +) + // NotifySubjectType represent type of notification subject +// +// swagger:enum NotifySubjectType type NotifySubjectType string const ( diff --git a/modules/structs/org.go b/modules/structs/org.go index d79b1d1d1c0b7..723689cb53a1d 100644 --- a/modules/structs/org.go +++ b/modules/structs/org.go @@ -60,7 +60,7 @@ type CreateOrgOption struct { // The location of the organization Location string `json:"location" binding:"MaxSize(50)"` // possible values are `public` (default), `limited` or `private` - // enum: public,limited,private + // enum: ["public","limited","private"] Visibility string `json:"visibility" binding:"In(,public,limited,private)"` // Whether repository administrators can change team access RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"` @@ -79,7 +79,7 @@ type EditOrgOption struct { // The location of the organization Location *string `json:"location" binding:"MaxSize(50)"` // possible values are `public`, `limited` or `private` - // enum: public,limited,private + // enum: ["public","limited","private"] Visibility *string `json:"visibility" binding:"In(,public,limited,private)"` // Whether repository administrators can change team access RepoAdminChangeTeamAccess *bool `json:"repo_admin_change_team_access"` diff --git a/modules/structs/org_team.go b/modules/structs/org_team.go index d34de5b6d2e0b..f730a5681c870 100644 --- a/modules/structs/org_team.go +++ b/modules/structs/org_team.go @@ -16,7 +16,7 @@ type Team struct { Organization *Organization `json:"organization"` // Whether the team has access to all repositories in the organization IncludesAllRepositories bool `json:"includes_all_repositories"` - // enum: none,read,write,admin,owner + // enum: ["none","read","write","admin","owner"] Permission string `json:"permission"` // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. @@ -35,7 +35,7 @@ type CreateTeamOption struct { Description string `json:"description" binding:"MaxSize(255)"` // Whether the team has access to all repositories in the organization IncludesAllRepositories bool `json:"includes_all_repositories"` - // enum: read,write,admin + // enum: ["read","write","admin"] Permission string `json:"permission"` // example: ["repo.actions","repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.ext_wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. @@ -54,7 +54,7 @@ type EditTeamOption struct { Description *string `json:"description" binding:"MaxSize(255)"` // Whether the team has access to all repositories in the organization IncludesAllRepositories *bool `json:"includes_all_repositories"` - // enum: read,write,admin + // enum: ["read","write","admin"] Permission string `json:"permission"` // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. diff --git a/modules/structs/pull_review.go b/modules/structs/pull_review.go index f44d2f84f5af3..de0677efabd37 100644 --- a/modules/structs/pull_review.go +++ b/modules/structs/pull_review.go @@ -8,6 +8,8 @@ import ( ) // ReviewStateType review state type +// +// swagger:enum ReviewStateType type ReviewStateType string const ( @@ -21,10 +23,11 @@ const ( ReviewStateRequestChanges ReviewStateType = "REQUEST_CHANGES" // ReviewStateRequestReview review is requested from user ReviewStateRequestReview ReviewStateType = "REQUEST_REVIEW" - // ReviewStateUnknown state of pr is unknown - ReviewStateUnknown ReviewStateType = "" ) +// ReviewStateUnknown is an internal sentinel for unknown review state, not a valid API value. +const ReviewStateUnknown = "" + // PullReview represents a pull request review type PullReview struct { ID int64 `json:"id"` diff --git a/modules/structs/repo.go b/modules/structs/repo.go index 3507cc410a113..7cd64fd7a4d7c 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -114,7 +114,7 @@ type Repository struct { Internal bool `json:"internal"` MirrorInterval string `json:"mirror_interval"` // ObjectFormatName of the underlying git repository - // enum: sha1,sha256 + // enum: ["sha1","sha256"] ObjectFormatName string `json:"object_format_name"` // swagger:strfmt date-time MirrorUpdated time.Time `json:"mirror_updated"` @@ -150,10 +150,10 @@ type CreateRepoOption struct { // DefaultBranch of the repository (used when initializes and in template) DefaultBranch string `json:"default_branch" binding:"GitRefName;MaxSize(100)"` // TrustModel of the repository - // enum: default,collaborator,committer,collaboratorcommitter + // enum: ["default","collaborator","committer","collaboratorcommitter"] TrustModel string `json:"trust_model"` // ObjectFormatName of the underlying git repository, empty string for default (sha1) - // enum: sha1,sha256 + // enum: ["sha1","sha256"] ObjectFormatName string `json:"object_format_name" binding:"MaxSize(6)"` } @@ -378,7 +378,7 @@ type MigrateRepoOptions struct { // required: true RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"` - // enum: git,github,gitea,gitlab,gogs,onedev,gitbucket,codebase,codecommit + // enum: ["git","github","gitea","gitlab","gogs","onedev","gitbucket","codebase","codecommit"] Service string `json:"service"` AuthUsername string `json:"auth_username"` AuthPassword string `json:"auth_password"` diff --git a/modules/structs/repo_collaborator.go b/modules/structs/repo_collaborator.go index 9ede7f075a66f..6b315df403a46 100644 --- a/modules/structs/repo_collaborator.go +++ b/modules/structs/repo_collaborator.go @@ -5,7 +5,7 @@ package structs // AddCollaboratorOption options when adding a user as a collaborator of a repository type AddCollaboratorOption struct { - // enum: read,write,admin + // enum: ["read","write","admin"] // Permission level to grant the collaborator Permission *string `json:"permission"` } diff --git a/modules/structs/repo_file.go b/modules/structs/repo_file.go index 59665062b771b..53ce5aeae285c 100644 --- a/modules/structs/repo_file.go +++ b/modules/structs/repo_file.go @@ -72,7 +72,7 @@ type ChangeFileOperation struct { // indicates what to do with the file: "create" for creating a new file, "update" for updating an existing file, // "upload" for creating or updating a file, "rename" for renaming a file, and "delete" for deleting an existing file. // required: true - // enum: create,update,upload,rename,delete + // enum: ["create","update","upload","rename","delete"] Operation string `json:"operation" binding:"Required"` // path to the existing or new file // required: true diff --git a/routers/api/v1/admin/runners.go b/routers/api/v1/admin/runners.go index 93983f6c7e2f0..3d27c87935af6 100644 --- a/routers/api/v1/admin/runners.go +++ b/routers/api/v1/admin/runners.go @@ -40,7 +40,7 @@ func ListRunners(ctx *context.APIContext) { // required: false // responses: // "200": - // "$ref": "#/definitions/ActionRunnersResponse" + // "$ref": "#/responses/RunnerList" // "400": // "$ref": "#/responses/error" // "404": @@ -63,7 +63,7 @@ func GetRunner(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": @@ -115,7 +115,7 @@ func UpdateRunner(ctx *context.APIContext) { // "$ref": "#/definitions/EditActionRunnerOption" // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index ea595407d11aa..e1d836b5c859a 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -11,11 +11,9 @@ // // Consumes: // - application/json -// - text/plain // // Produces: // - application/json -// - text/html // // Security: // - BasicAuth : diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index 18ed602ddbbe5..01b57b3fac964 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -492,7 +492,7 @@ func (Action) ListRunners(ctx *context.APIContext) { // required: false // responses: // "200": - // "$ref": "#/definitions/ActionRunnersResponse" + // "$ref": "#/responses/RunnerList" // "400": // "$ref": "#/responses/error" // "404": @@ -520,7 +520,7 @@ func (Action) GetRunner(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": @@ -582,7 +582,7 @@ func (Action) UpdateRunner(ctx *context.APIContext) { // "$ref": "#/definitions/EditActionRunnerOption" // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 0c48f732abfb4..7ac8a10575cfb 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -561,7 +561,7 @@ func (Action) ListRunners(ctx *context.APIContext) { // required: false // responses: // "200": - // "$ref": "#/definitions/ActionRunnersResponse" + // "$ref": "#/responses/RunnerList" // "400": // "$ref": "#/responses/error" // "404": @@ -594,7 +594,7 @@ func (Action) GetRunner(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": @@ -666,7 +666,7 @@ func (Action) UpdateRunner(ctx *context.APIContext) { // "$ref": "#/definitions/EditActionRunnerOption" // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": @@ -1192,7 +1192,7 @@ func GetWorkflowRun(ctx *context.APIContext) { // - name: run // in: path // description: id of the run - // type: string + // type: integer // required: true // responses: // "200": diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index e535b5e0091dd..1f313acde8c35 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -175,7 +175,7 @@ func DeleteIssueCommentReaction(ctx *context.APIContext) { // schema: // "$ref": "#/definitions/EditReactionOption" // responses: - // "200": + // "204": // "$ref": "#/responses/empty" // "403": // "$ref": "#/responses/forbidden" @@ -248,8 +248,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp ctx.APIErrorInternal(err) return } - // ToDo respond 204 - ctx.Status(http.StatusOK) + ctx.Status(http.StatusNoContent) } } @@ -408,7 +407,7 @@ func DeleteIssueReaction(ctx *context.APIContext) { // schema: // "$ref": "#/definitions/EditReactionOption" // responses: - // "200": + // "204": // "$ref": "#/responses/empty" // "403": // "$ref": "#/responses/forbidden" @@ -464,7 +463,6 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i ctx.APIErrorInternal(err) return } - // ToDo respond 204 - ctx.Status(http.StatusOK) + ctx.Status(http.StatusNoContent) } } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index f405a3152f738..a045bba49ccf1 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -898,6 +898,8 @@ func MergePullRequest(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" // "404": // "$ref": "#/responses/notFound" // "405": diff --git a/routers/api/v1/user/runners.go b/routers/api/v1/user/runners.go index 667bdb36fee03..e06b022f35640 100644 --- a/routers/api/v1/user/runners.go +++ b/routers/api/v1/user/runners.go @@ -40,7 +40,7 @@ func ListRunners(ctx *context.APIContext) { // required: false // responses: // "200": - // "$ref": "#/definitions/ActionRunnersResponse" + // "$ref": "#/responses/RunnerList" // "400": // "$ref": "#/responses/error" // "404": @@ -63,7 +63,7 @@ func GetRunner(ctx *context.APIContext) { // required: true // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": @@ -115,7 +115,7 @@ func UpdateRunner(ctx *context.APIContext) { // "$ref": "#/definitions/EditActionRunnerOption" // responses: // "200": - // "$ref": "#/definitions/ActionRunner" + // "$ref": "#/responses/Runner" // "400": // "$ref": "#/responses/error" // "404": diff --git a/services/convert/notification.go b/services/convert/notification.go index e91bc7dcde453..3a1ae09dc5bb2 100644 --- a/services/convert/notification.go +++ b/services/convert/notification.go @@ -47,7 +47,7 @@ func ToNotificationThread(ctx context.Context, n *activities_model.Notification) result.Subject.Title = n.Issue.Title result.Subject.URL = n.Issue.APIURL(ctx) result.Subject.HTMLURL = n.Issue.HTMLURL(ctx) - result.Subject.State = n.Issue.State() + result.Subject.State = api.NotifySubjectStateType(n.Issue.State()) comment, err := n.Issue.GetLastComment(ctx) if err == nil && comment != nil { result.Subject.LatestCommentURL = comment.APIURL(ctx) @@ -60,7 +60,7 @@ func ToNotificationThread(ctx context.Context, n *activities_model.Notification) result.Subject.Title = n.Issue.Title result.Subject.URL = n.Issue.APIURL(ctx) result.Subject.HTMLURL = n.Issue.HTMLURL(ctx) - result.Subject.State = n.Issue.State() + result.Subject.State = api.NotifySubjectStateType(n.Issue.State()) comment, err := n.Issue.GetLastComment(ctx) if err == nil && comment != nil { result.Subject.LatestCommentURL = comment.APIURL(ctx) @@ -70,7 +70,7 @@ func ToNotificationThread(ctx context.Context, n *activities_model.Notification) if err := n.Issue.LoadPullRequest(ctx); err == nil && n.Issue.PullRequest != nil && n.Issue.PullRequest.HasMerged { - result.Subject.State = "merged" + result.Subject.State = api.NotifySubjectStateMerged } } case activities_model.NotificationSourceCommit: diff --git a/services/convert/notification_test.go b/services/convert/notification_test.go index 718a07081987d..0a4f9d6c0a0ca 100644 --- a/services/convert/notification_test.go +++ b/services/convert/notification_test.go @@ -7,12 +7,15 @@ import ( "testing" activities_model "code.gitea.io/gitea/models/activities" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestToNotificationThreadIncludesRepoForAccessibleUser(t *testing.T) { @@ -36,6 +39,78 @@ func TestToNotificationThreadOmitsRepoWhenAccessRevoked(t *testing.T) { assert.Nil(t, thread.Repository) } +func TestToNotificationThread(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + + t.Run("issue notification", func(t *testing.T) { + // Notification 1: source=issue, issue_id=1, status=unread + n := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 1}) + require.NoError(t, n.LoadAttributes(t.Context())) + + thread := ToNotificationThread(t.Context(), n) + assert.Equal(t, int64(1), thread.ID) + assert.True(t, thread.Unread) + assert.False(t, thread.Pinned) + require.NotNil(t, thread.Subject) + assert.Equal(t, api.NotifySubjectIssue, thread.Subject.Type) + assert.Equal(t, api.NotifySubjectStateOpen, thread.Subject.State) + }) + + t.Run("pinned notification", func(t *testing.T) { + // Notification 3: status=pinned + n := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 3}) + require.NoError(t, n.LoadAttributes(t.Context())) + + thread := ToNotificationThread(t.Context(), n) + assert.False(t, thread.Unread) + assert.True(t, thread.Pinned) + }) + + t.Run("merged pull request returns merged state", func(t *testing.T) { + // Issue 2 is a pull request; pull_request 1 has has_merged=true. + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + + n := &activities_model.Notification{ + ID: 999, + UserID: 2, + RepoID: repo.ID, + Status: activities_model.NotificationStatusUnread, + Source: activities_model.NotificationSourcePullRequest, + IssueID: issue.ID, + Issue: issue, + Repository: repo, + } + + thread := ToNotificationThread(t.Context(), n) + require.NotNil(t, thread.Subject) + assert.Equal(t, api.NotifySubjectPull, thread.Subject.Type) + assert.Equal(t, api.NotifySubjectStateMerged, thread.Subject.State) + }) + + t.Run("open pull request returns open state", func(t *testing.T) { + // Issue 3 is a pull request; pull_request 2 has has_merged=false. + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + + n := &activities_model.Notification{ + ID: 998, + UserID: 2, + RepoID: repo.ID, + Status: activities_model.NotificationStatusUnread, + Source: activities_model.NotificationSourcePullRequest, + IssueID: issue.ID, + Issue: issue, + Repository: repo, + } + + thread := ToNotificationThread(t.Context(), n) + require.NotNil(t, thread.Subject) + assert.Equal(t, api.NotifySubjectPull, thread.Subject.Type) + assert.Equal(t, api.NotifySubjectStateOpen, thread.Subject.State) + }) +} + func newRepoNotification(t *testing.T, repoID, userID int64) *activities_model.Notification { t.Helper() diff --git a/services/convert/status.go b/services/convert/status.go index fe8240a8f7212..a8ef94d107de7 100644 --- a/services/convert/status.go +++ b/services/convert/status.go @@ -9,6 +9,7 @@ import ( git_model "code.gitea.io/gitea/models/git" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/commitstatus" api "code.gitea.io/gitea/modules/structs" ) @@ -55,6 +56,8 @@ func ToCombinedStatus(ctx context.Context, commitID string, statuses []*git_mode if combinedStatus != nil { status.Statuses = ToCommitStatuses(ctx, statuses) status.State = combinedStatus.State + } else { + status.State = commitstatus.CommitStatusPending } return &status } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 8b69c6bcc6f9e..7ccf0aa6228b2 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -521,7 +521,7 @@ func (f *InitializeLabelsForm) Validate(req *http.Request, errs binding.Errors) // swagger:model MergePullRequestOption type MergePullRequestForm struct { // required: true - // enum: merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged + // enum: ["merge","rebase","rebase-merge","squash","fast-forward-only","manually-merged"] Do string `binding:"Required;In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged)"` MergeTitleField string MergeMessageField string diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index adc6c18175512..e01ff1112bfb3 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1,11 +1,9 @@ { "consumes": [ - "application/json", - "text/plain" + "application/json" ], "produces": [ - "application/json", - "text/html" + "application/json" ], "schemes": [ "https", @@ -86,7 +84,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunnersResponse" + "$ref": "#/responses/RunnerList" }, "400": { "$ref": "#/responses/error" @@ -135,7 +133,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -205,7 +203,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -2008,7 +2006,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunnersResponse" + "$ref": "#/responses/RunnerList" }, "400": { "$ref": "#/responses/error" @@ -2073,7 +2071,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -2157,7 +2155,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -4989,7 +4987,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunnersResponse" + "$ref": "#/responses/RunnerList" }, "400": { "$ref": "#/responses/error" @@ -5068,7 +5066,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -5166,7 +5164,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -5287,7 +5285,7 @@ "required": true }, { - "type": "string", + "type": "integer", "description": "id of the run", "name": "run", "in": "path", @@ -10230,7 +10228,7 @@ } ], "responses": { - "200": { + "204": { "$ref": "#/responses/empty" }, "403": { @@ -11969,7 +11967,7 @@ } ], "responses": { - "200": { + "204": { "$ref": "#/responses/empty" }, "403": { @@ -14495,6 +14493,9 @@ "200": { "$ref": "#/responses/empty" }, + "403": { + "$ref": "#/responses/forbidden" + }, "404": { "$ref": "#/responses/notFound" }, @@ -18670,7 +18671,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunnersResponse" + "$ref": "#/responses/RunnerList" }, "400": { "$ref": "#/responses/error" @@ -18719,7 +18720,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -18789,7 +18790,7 @@ ], "responses": { "200": { - "$ref": "#/definitions/ActionRunner" + "$ref": "#/responses/Runner" }, "400": { "$ref": "#/responses/error" @@ -23887,7 +23888,16 @@ "x-go-name": "CommitID" }, "event": { - "$ref": "#/definitions/ReviewStateType" + "type": "string", + "enum": [ + "APPROVED", + "PENDING", + "COMMENT", + "REQUEST_CHANGES", + "REQUEST_REVIEW" + ], + "x-go-enum-desc": "APPROVED ReviewStateApproved ReviewStateApproved pr is approved\nPENDING ReviewStatePending ReviewStatePending pr state is pending\nCOMMENT ReviewStateComment ReviewStateComment is a comment review\nREQUEST_CHANGES ReviewStateRequestChanges ReviewStateRequestChanges changes for pr are requested\nREQUEST_REVIEW ReviewStateRequestReview ReviewStateRequestReview review is requested from user", + "x-go-name": "Event" } }, "x-go-package": "code.gitea.io/gitea/modules/structs" @@ -24835,6 +24845,10 @@ "state": { "description": "State indicates the updated state of the milestone", "type": "string", + "enum": [ + "open", + "closed" + ], "x-go-name": "State" }, "title": { @@ -26272,7 +26286,13 @@ "$ref": "#/definitions/RepositoryMeta" }, "state": { - "$ref": "#/definitions/StateType" + "type": "string", + "enum": [ + "open", + "closed" + ], + "x-go-enum-desc": "open StateOpen StateOpen pr is opened\nclosed StateClosed StateClosed pr is closed", + "x-go-name": "State" }, "time_estimate": { "type": "integer", @@ -26373,7 +26393,16 @@ "x-go-name": "ID" }, "type": { - "$ref": "#/definitions/IssueFormFieldType" + "type": "string", + "enum": [ + "markdown", + "textarea", + "input", + "dropdown", + "checkboxes" + ], + "x-go-enum-desc": "markdown IssueFormFieldTypeMarkdown\ntextarea IssueFormFieldTypeTextarea\ninput IssueFormFieldTypeInput\ndropdown IssueFormFieldTypeDropdown\ncheckboxes IssueFormFieldTypeCheckboxes", + "x-go-name": "Type" }, "validations": { "type": "object", @@ -26383,23 +26412,18 @@ "visible": { "type": "array", "items": { - "$ref": "#/definitions/IssueFormFieldVisible" + "type": "string", + "enum": [ + "form", + "content" + ], + "x-go-enum-desc": "form IssueFormFieldVisibleForm\ncontent IssueFormFieldVisibleContent" }, "x-go-name": "Visible" } }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, - "IssueFormFieldType": { - "type": "string", - "title": "IssueFormFieldType defines issue form field type, can be \"markdown\", \"textarea\", \"input\", \"dropdown\" or \"checkboxes\"", - "x-go-package": "code.gitea.io/gitea/modules/structs" - }, - "IssueFormFieldVisible": { - "description": "IssueFormFieldVisible defines issue form field visible", - "type": "string", - "x-go-package": "code.gitea.io/gitea/modules/structs" - }, "IssueLabelsOption": { "description": "IssueLabelsOption a collection of labels", "type": "object", @@ -26897,7 +26921,14 @@ "x-go-name": "OpenIssues" }, "state": { - "$ref": "#/definitions/StateType" + "description": "State indicates if the milestone is open or closed\nopen StateOpen StateOpen pr is opened\nclosed StateClosed StateClosed pr is closed", + "type": "string", + "enum": [ + "open", + "closed" + ], + "x-go-enum-desc": "open StateOpen StateOpen pr is opened\nclosed StateClosed StateClosed pr is closed", + "x-go-name": "State" }, "title": { "description": "Title is the title of the milestone", @@ -27111,7 +27142,15 @@ "x-go-name": "LatestCommentURL" }, "state": { - "$ref": "#/definitions/StateType" + "description": "State indicates the current state of the notification subject\nopen NotifySubjectStateOpen NotifySubjectStateOpen is an open subject\nclosed NotifySubjectStateClosed NotifySubjectStateClosed is a closed subject\nmerged NotifySubjectStateMerged NotifySubjectStateMerged is a merged pull request", + "type": "string", + "enum": [ + "open", + "closed", + "merged" + ], + "x-go-enum-desc": "open NotifySubjectStateOpen NotifySubjectStateOpen is an open subject\nclosed NotifySubjectStateClosed NotifySubjectStateClosed is a closed subject\nmerged NotifySubjectStateMerged NotifySubjectStateMerged is a merged pull request", + "x-go-name": "State" }, "title": { "description": "Title is the title of the notification subject", @@ -27119,7 +27158,16 @@ "x-go-name": "Title" }, "type": { - "$ref": "#/definitions/NotifySubjectType" + "description": "Type indicates the type of the notification subject\nIssue NotifySubjectIssue NotifySubjectIssue an issue is subject of an notification\nPull NotifySubjectPull NotifySubjectPull an pull is subject of an notification\nCommit NotifySubjectCommit NotifySubjectCommit an commit is subject of an notification\nRepository NotifySubjectRepository NotifySubjectRepository an repository is subject of an notification", + "type": "string", + "enum": [ + "Issue", + "Pull", + "Commit", + "Repository" + ], + "x-go-enum-desc": "Issue NotifySubjectIssue NotifySubjectIssue an issue is subject of an notification\nPull NotifySubjectPull NotifySubjectPull an pull is subject of an notification\nCommit NotifySubjectCommit NotifySubjectCommit an commit is subject of an notification\nRepository NotifySubjectRepository NotifySubjectRepository an repository is subject of an notification", + "x-go-name": "Type" }, "url": { "description": "URL is the API URL for the notification subject", @@ -27169,11 +27217,6 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, - "NotifySubjectType": { - "description": "NotifySubjectType represent type of notification subject", - "type": "string", - "x-go-package": "code.gitea.io/gitea/modules/structs" - }, "OAuth2Application": { "type": "object", "title": "OAuth2Application represents an OAuth2 application.", @@ -27806,7 +27849,14 @@ "x-go-name": "ReviewComments" }, "state": { - "$ref": "#/definitions/StateType" + "description": "The current state of the pull request\nopen StateOpen StateOpen pr is opened\nclosed StateClosed StateClosed pr is closed", + "type": "string", + "enum": [ + "open", + "closed" + ], + "x-go-enum-desc": "open StateOpen StateOpen pr is opened\nclosed StateClosed StateClosed pr is closed", + "x-go-name": "State" }, "title": { "description": "The title of the pull request", @@ -27898,7 +27948,16 @@ "x-go-name": "Stale" }, "state": { - "$ref": "#/definitions/ReviewStateType" + "type": "string", + "enum": [ + "APPROVED", + "PENDING", + "COMMENT", + "REQUEST_CHANGES", + "REQUEST_REVIEW" + ], + "x-go-enum-desc": "APPROVED ReviewStateApproved ReviewStateApproved pr is approved\nPENDING ReviewStatePending ReviewStatePending pr state is pending\nCOMMENT ReviewStateComment ReviewStateComment is a comment review\nREQUEST_CHANGES ReviewStateRequestChanges ReviewStateRequestChanges changes for pr are requested\nREQUEST_REVIEW ReviewStateRequestReview ReviewStateRequestReview review is requested from user", + "x-go-name": "State" }, "submitted_at": { "type": "string", @@ -28635,11 +28694,6 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, - "ReviewStateType": { - "description": "ReviewStateType review state type", - "type": "string", - "x-go-package": "code.gitea.io/gitea/modules/structs" - }, "RunDetails": { "description": "RunDetails returns workflow_dispatch runid and url", "type": "object", @@ -28714,11 +28768,6 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, - "StateType": { - "description": "StateType issue state type", - "type": "string", - "x-go-package": "code.gitea.io/gitea/modules/structs" - }, "StopWatch": { "description": "StopWatch represent a running stopwatch", "type": "object", @@ -28772,7 +28821,16 @@ "x-go-name": "Body" }, "event": { - "$ref": "#/definitions/ReviewStateType" + "type": "string", + "enum": [ + "APPROVED", + "PENDING", + "COMMENT", + "REQUEST_CHANGES", + "REQUEST_REVIEW" + ], + "x-go-enum-desc": "APPROVED ReviewStateApproved ReviewStateApproved pr is approved\nPENDING ReviewStatePending ReviewStatePending pr state is pending\nCOMMENT ReviewStateComment ReviewStateComment is a comment review\nREQUEST_CHANGES ReviewStateRequestChanges ReviewStateRequestChanges changes for pr are requested\nREQUEST_REVIEW ReviewStateRequestReview ReviewStateRequestReview review is requested from user", + "x-go-name": "Event" } }, "x-go-package": "code.gitea.io/gitea/modules/structs" diff --git a/tests/integration/api_issue_reaction_test.go b/tests/integration/api_issue_reaction_test.go index 01588f9900d10..d099e72edbd8f 100644 --- a/tests/integration/api_issue_reaction_test.go +++ b/tests/integration/api_issue_reaction_test.go @@ -44,7 +44,7 @@ func TestAPIIssuesReactions(t *testing.T) { req = NewRequestWithJSON(t, "DELETE", urlStr, &api.EditReactionOption{ Reaction: "zzz", }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusOK) + MakeRequest(t, req, http.StatusNoContent) // Add allowed reaction req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{ @@ -111,7 +111,7 @@ func TestAPICommentReactions(t *testing.T) { req = NewRequestWithJSON(t, "DELETE", urlStr, &api.EditReactionOption{ Reaction: "eyes", }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusOK) + MakeRequest(t, req, http.StatusNoContent) t.Run("UnrelatedCommentID", func(t *testing.T) { // Using the ID of a comment that does not belong to the repository must fail