* 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": { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue