* introduce GET /notifications/new * add TEST * use Sprintf instead of path.Join * Error more verbose * return number of notifications if unreaded exist * 200 http status for available notifications
This commit is contained in:
parent
ce274d652f
commit
44de66bf50
9 changed files with 107 additions and 5 deletions
|
@ -81,6 +81,10 @@ func TestAPINotification(t *testing.T) {
|
|||
assert.EqualValues(t, thread5.Issue.APIURL(), apiN.Subject.URL)
|
||||
assert.EqualValues(t, thread5.Repository.HTMLURL(), apiN.Repository.HTMLURL)
|
||||
|
||||
// -- check notifications --
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/new?token=%s", token))
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
// -- mark notifications as read --
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token))
|
||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||
|
@ -103,4 +107,8 @@ func TestAPINotification(t *testing.T) {
|
|||
assert.Equal(t, models.NotificationStatusUnread, thread5.Status)
|
||||
thread5 = models.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification)
|
||||
assert.Equal(t, models.NotificationStatusRead, thread5.Status)
|
||||
|
||||
// -- check notifications --
|
||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/new?token=%s", token))
|
||||
resp = session.MakeRequest(t, req, http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ package models
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -324,7 +323,7 @@ func (issue *Issue) GetIsRead(userID int64) error {
|
|||
|
||||
// APIURL returns the absolute APIURL to this issue.
|
||||
func (issue *Issue) APIURL() string {
|
||||
return issue.Repo.APIURL() + "/" + path.Join("issues", fmt.Sprint(issue.Index))
|
||||
return fmt.Sprintf("%s/issues/%d", issue.Repo.APIURL(), issue.Index)
|
||||
}
|
||||
|
||||
// HTMLURL returns the absolute URL to this issue.
|
||||
|
|
|
@ -8,7 +8,6 @@ package models
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
|
@ -249,7 +248,7 @@ func (c *Comment) APIURL() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
return c.Issue.Repo.APIURL() + "/" + path.Join("issues/comments", fmt.Sprint(c.ID))
|
||||
return fmt.Sprintf("%s/issues/comments/%d", c.Issue.Repo.APIURL(), c.ID)
|
||||
}
|
||||
|
||||
// IssueURL formats a URL-string to the issue
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"path"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
|
@ -294,6 +295,20 @@ func notificationsForUser(e Engine, user *User, statuses []NotificationStatus, p
|
|||
return
|
||||
}
|
||||
|
||||
// CountUnread count unread notifications for a user
|
||||
func CountUnread(user *User) int64 {
|
||||
return countUnread(x, user.ID)
|
||||
}
|
||||
|
||||
func countUnread(e Engine, userID int64) int64 {
|
||||
exist, err := e.Where("user_id = ?", userID).And("status = ?", NotificationStatusUnread).Count(new(Notification))
|
||||
if err != nil {
|
||||
log.Error("countUnread", err)
|
||||
return 0
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// APIFormat converts a Notification to api.NotificationThread
|
||||
func (n *Notification) APIFormat() *api.NotificationThread {
|
||||
result := &api.NotificationThread{
|
||||
|
@ -388,7 +403,7 @@ func (n *Notification) loadComment(e Engine) (err error) {
|
|||
if n.Comment == nil && n.CommentID > 0 {
|
||||
n.Comment, err = GetCommentByID(n.CommentID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("GetCommentByID [%d]: %v", n.CommentID, err)
|
||||
return fmt.Errorf("GetCommentByID [%d] for issue ID [%d]: %v", n.CommentID, n.IssueID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -26,3 +26,8 @@ type NotificationSubject struct {
|
|||
LatestCommentURL string `json:"latest_comment_url"`
|
||||
Type string `json:"type" binding:"In(Issue,Pull,Commit)"`
|
||||
}
|
||||
|
||||
// NotificationCount number of unread notifications
|
||||
type NotificationCount struct {
|
||||
New int64 `json:"new"`
|
||||
}
|
||||
|
|
|
@ -518,6 +518,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||
m.Combo("").
|
||||
Get(notify.ListNotifications).
|
||||
Put(notify.ReadNotifications)
|
||||
m.Get("/new", notify.NewAvailable)
|
||||
m.Combo("/threads/:id").
|
||||
Get(notify.GetThread).
|
||||
Patch(notify.ReadThread)
|
||||
|
|
33
routers/api/v1/notify/notifications.go
Normal file
33
routers/api/v1/notify/notifications.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
// 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 notify
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
// NewAvailable check if unread notifications exist
|
||||
func NewAvailable(ctx *context.APIContext) {
|
||||
// swagger:operation GET /notifications/new notification notifyNewAvailable
|
||||
// ---
|
||||
// summary: Check if unread notifications exist
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/NotificationCount"
|
||||
// "204":
|
||||
// description: No unread notification
|
||||
|
||||
count := models.CountUnread(ctx.User)
|
||||
|
||||
if count > 0 {
|
||||
ctx.JSON(http.StatusOK, api.NotificationCount{New: count})
|
||||
} else {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
|
@ -21,3 +21,10 @@ type swaggerNotificationThreadList struct {
|
|||
// in:body
|
||||
Body []api.NotificationThread `json:"body"`
|
||||
}
|
||||
|
||||
// Number of unread notifications
|
||||
// swagger:response NotificationCount
|
||||
type swaggerNotificationCount struct {
|
||||
// in:body
|
||||
Body api.NotificationCount `json:"body"`
|
||||
}
|
||||
|
|
|
@ -494,6 +494,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/notifications/new": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"notification"
|
||||
],
|
||||
"summary": "Check if unread notifications exist",
|
||||
"operationId": "notifyNewAvailable",
|
||||
"responses": {
|
||||
"200": {
|
||||
"$ref": "#/responses/NotificationCount"
|
||||
},
|
||||
"204": {
|
||||
"description": "No unread notification"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/notifications/threads/{id}": {
|
||||
"get": {
|
||||
"consumes": [
|
||||
|
@ -10911,6 +10928,18 @@
|
|||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"NotificationCount": {
|
||||
"description": "NotificationCount number of unread notifications",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"new": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "New"
|
||||
}
|
||||
},
|
||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||
},
|
||||
"NotificationSubject": {
|
||||
"description": "NotificationSubject contains the notification subject (Issue/Pull/Commit)",
|
||||
"type": "object",
|
||||
|
@ -12397,6 +12426,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"NotificationCount": {
|
||||
"description": "Number of unread notifications",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/NotificationCount"
|
||||
}
|
||||
},
|
||||
"NotificationThread": {
|
||||
"description": "NotificationThread",
|
||||
"schema": {
|
||||
|
|
Reference in a new issue