From 8f1a70ee7f8148d50700ff5b0a46bc5f7beaa15b Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Mon, 6 Jul 2020 11:42:21 +0100 Subject: [PATCH 1/8] Extend notifications API and return pinned notifications in notifications list Signed-off-by: Andrew Thornton --- integrations/eventsource_test.go | 4 +- models/notification.go | 12 +++-- routers/api/v1/notify/repo.go | 83 +++++++++++++++++++++++++++++--- routers/api/v1/notify/threads.go | 12 ++++- routers/api/v1/notify/user.go | 50 ++++++++++++++++--- 5 files changed, 142 insertions(+), 19 deletions(-) diff --git a/integrations/eventsource_test.go b/integrations/eventsource_test.go index bc154531476a5..caaf8c2cefff8 100644 --- a/integrations/eventsource_test.go +++ b/integrations/eventsource_test.go @@ -59,7 +59,7 @@ func TestEventSourceManagerRun(t *testing.T) { var apiNL []api.NotificationThread // -- mark notifications as read -- - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token)) resp := session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) @@ -69,7 +69,7 @@ func TestEventSourceManagerRun(t *testing.T) { req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token)) resp = session.MakeRequest(t, req, http.StatusResetContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s&status-types=unread", token)) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 1) diff --git a/models/notification.go b/models/notification.go index 1c378a1350da0..c691b5dc06886 100644 --- a/models/notification.go +++ b/models/notification.go @@ -72,7 +72,7 @@ type FindNotificationOptions struct { UserID int64 RepoID int64 IssueID int64 - Status NotificationStatus + Status []NotificationStatus UpdatedAfterUnix int64 UpdatedBeforeUnix int64 } @@ -89,8 +89,14 @@ func (opts *FindNotificationOptions) ToCond() builder.Cond { if opts.IssueID != 0 { cond = cond.And(builder.Eq{"notification.issue_id": opts.IssueID}) } - if opts.Status != 0 { - cond = cond.And(builder.Eq{"notification.status": opts.Status}) + if len(opts.Status) == 1 { + cond = cond.And(builder.Eq{"notification.status": opts.Status[0]}) + } else if len(opts.Status) > 1 { + eqConds := make([]builder.Cond, 0, len(opts.Status)) + for _, status := range opts.Status { + eqConds = append(eqConds, builder.Eq{"notification.status": status}) + } + cond = cond.And(cond.Or(eqConds...)) } if opts.UpdatedAfterUnix != 0 { cond = cond.And(builder.Gte{"notification.updated_unix": opts.UpdatedAfterUnix}) diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 3050cca1e5b88..715409aa50d81 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -11,9 +11,37 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/routers/api/v1/utils" ) +func statusStringToNotificationStatus(status string) models.NotificationStatus { + switch strings.ToLower(strings.TrimSpace(status)) { + case "unread": + return models.NotificationStatusUnread + case "read": + return models.NotificationStatusRead + case "pinned": + return models.NotificationStatusPinned + default: + return 0 + } +} + +func statusStringsToNotificationStatuses(statuses []string, defaultStatuses []string) []models.NotificationStatus { + if len(statuses) == 0 { + statuses = defaultStatuses + } + results := make([]models.NotificationStatus, 0, len(statuses)) + for _, status := range statuses { + notificationStatus := statusStringToNotificationStatus(status) + if notificationStatus > 0 { + results = append(results, notificationStatus) + } + } + return results +} + // ListRepoNotifications list users's notification threads on a specific repo func ListRepoNotifications(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/notifications notification notifyGetRepoList @@ -39,6 +67,15 @@ func ListRepoNotifications(ctx *context.APIContext) { // description: If true, show notifications marked as read. Default value is false // type: string // required: false + // - name: status-types + // in: query + // description: Show notifications with the provided status types. Options are: unread, read and/or pinned + // type: array + // collectionFormat: multi + // items: + // type: string + // default: unread, pinned + // required: false // - name: since // in: query // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format @@ -75,9 +112,10 @@ func ListRepoNotifications(ctx *context.APIContext) { UpdatedBeforeUnix: before, UpdatedAfterUnix: since, } - qAll := strings.Trim(ctx.Query("all"), " ") - if qAll != "true" { - opts.Status = models.NotificationStatusUnread + + if !ctx.QueryBool("all") { + statuses := ctx.QueryStrings("status-types") + opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread", "pinned"}) } nl, err := models.GetNotifications(opts) if err != nil { @@ -97,7 +135,7 @@ func ListRepoNotifications(ctx *context.APIContext) { func ReadRepoNotifications(ctx *context.APIContext) { // swagger:operation PUT /repos/{owner}/{repo}/notifications notification notifyReadRepoList // --- - // summary: Mark notification threads as read on a specific repo + // summary: Mark notification threads as read, pinned or unread on a specific repo // consumes: // - application/json // produces: @@ -113,6 +151,25 @@ func ReadRepoNotifications(ctx *context.APIContext) { // description: name of the repo // type: string // required: true + // - name: all + // in: query + // description: If true, mark all notifications on this repo. Default value is false + // type: string + // required: false + // - name: status-types + // in: query + // description: Mark notifications with the provided status types. Options are: unread, read and/or pinned + // type: array + // collectionFormat: multi + // items: + // type: string + // default: unread + // required: false + // - name: to-status + // in: query + // description: Status to mark notifications as + // default: read + // required: false // - name: last_read_at // in: query // description: Describes the last point that notifications were checked. Anything updated since this time will not be updated. @@ -135,20 +192,34 @@ func ReadRepoNotifications(ctx *context.APIContext) { lastRead = tmpLastRead.Unix() } } + opts := models.FindNotificationOptions{ UserID: ctx.User.ID, RepoID: ctx.Repo.Repository.ID, UpdatedBeforeUnix: lastRead, - Status: models.NotificationStatusUnread, + } + + if !ctx.QueryBool("all") { + statuses := ctx.QueryStrings("status-types") + opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) + log.Error("%v", opts.Status) } nl, err := models.GetNotifications(opts) if err != nil { ctx.InternalServerError(err) return } + for _, t := range nl { + log.Error("found thread: %d %d", t.ID, t.Status) + } + + targetStatus := statusStringToNotificationStatus(ctx.Query("to-status")) + if targetStatus == 0 { + targetStatus = models.NotificationStatusRead + } for _, n := range nl { - err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead) + err := models.SetNotificationStatus(n.ID, ctx.User, targetStatus) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index d0119e9938eec..f877ae0262334 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -62,6 +62,11 @@ func ReadThread(ctx *context.APIContext) { // description: id of notification thread // type: string // required: true + // - name: to-status + // in: query + // description: Status to mark notifications as + // default: read + // required: false // responses: // "205": // "$ref": "#/responses/empty" @@ -75,7 +80,12 @@ func ReadThread(ctx *context.APIContext) { return } - err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead) + targetStatus := statusStringToNotificationStatus(ctx.Query("to-status")) + if targetStatus == 0 { + targetStatus = models.NotificationStatusRead + } + + err := models.SetNotificationStatus(n.ID, ctx.User, targetStatus) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index 649eaa8a37c1b..2c7a0aaecfc92 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -29,6 +29,15 @@ func ListNotifications(ctx *context.APIContext) { // description: If true, show notifications marked as read. Default value is false // type: string // required: false + // - name: status-types + // in: query + // description: Show notifications with the provided status types. Options are: unread, read and/or pinned + // type: array + // collectionFormat: multi + // items: + // type: string + // default: unread, pinned + // required: false // - name: since // in: query // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format @@ -64,9 +73,9 @@ func ListNotifications(ctx *context.APIContext) { UpdatedBeforeUnix: before, UpdatedAfterUnix: since, } - qAll := strings.Trim(ctx.Query("all"), " ") - if qAll != "true" { - opts.Status = models.NotificationStatusUnread + if !ctx.QueryBool("all") { + statuses := ctx.QueryStrings("status-types") + opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread", "pinned"}) } nl, err := models.GetNotifications(opts) if err != nil { @@ -82,11 +91,11 @@ func ListNotifications(ctx *context.APIContext) { ctx.JSON(http.StatusOK, nl.APIFormat()) } -// ReadNotifications mark notification threads as read +// ReadNotifications mark notification threads as read, unread, or pinned func ReadNotifications(ctx *context.APIContext) { // swagger:operation PUT /notifications notification notifyReadList // --- - // summary: Mark notification threads as read + // summary: Mark notification threads as read, pinned or unread // consumes: // - application/json // produces: @@ -98,6 +107,25 @@ func ReadNotifications(ctx *context.APIContext) { // type: string // format: date-time // required: false + // - name: all + // in: query + // description: If true, mark all notifications on this repo. Default value is false + // type: string + // required: false + // - name: status-types + // in: query + // description: Mark notifications with the provided status types. Options are: unread, read and/or pinned + // type: array + // collectionFormat: multi + // items: + // type: string + // default: unread + // required: false + // - name: to-status + // in: query + // description: Status to mark notifications as + // default: read + // required: false // responses: // "205": // "$ref": "#/responses/empty" @@ -117,7 +145,10 @@ func ReadNotifications(ctx *context.APIContext) { opts := models.FindNotificationOptions{ UserID: ctx.User.ID, UpdatedBeforeUnix: lastRead, - Status: models.NotificationStatusUnread, + } + if !ctx.QueryBool("all") { + statuses := ctx.QueryStrings("status-types") + opts.Status = statusStringsToNotificationStatuses(statuses, []string{"unread"}) } nl, err := models.GetNotifications(opts) if err != nil { @@ -125,8 +156,13 @@ func ReadNotifications(ctx *context.APIContext) { return } + targetStatus := statusStringToNotificationStatus(ctx.Query("to-status")) + if targetStatus == 0 { + targetStatus = models.NotificationStatusRead + } + for _, n := range nl { - err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead) + err := models.SetNotificationStatus(n.ID, ctx.User, targetStatus) if err != nil { ctx.InternalServerError(err) return From 85c20fe10d284014751417add03d2c61de8c5767 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Mon, 6 Jul 2020 13:02:21 +0100 Subject: [PATCH 2/8] fix swagger Signed-off-by: Andrew Thornton --- routers/api/v1/notify/repo.go | 4 +- routers/api/v1/notify/user.go | 4 +- templates/swagger/v1_json.tmpl | 78 +++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 715409aa50d81..1446e1f38c4b7 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -69,7 +69,7 @@ func ListRepoNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: Show notifications with the provided status types. Options are: unread, read and/or pinned + // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned" // type: array // collectionFormat: multi // items: @@ -158,7 +158,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: Mark notifications with the provided status types. Options are: unread, read and/or pinned + // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned" // type: array // collectionFormat: multi // items: diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index 2c7a0aaecfc92..2a47ef66b24b6 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -31,7 +31,7 @@ func ListNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: Show notifications with the provided status types. Options are: unread, read and/or pinned + // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned" // type: array // collectionFormat: multi // items: @@ -114,7 +114,7 @@ func ReadNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: Mark notifications with the provided status types. Options are: unread, read and/or pinned + // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned" // type: array // collectionFormat: multi // items: diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 9290bfe0798f4..91efc3aac428c 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -459,6 +459,17 @@ "name": "all", "in": "query" }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "default": "unread, pinned", + "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned", + "name": "status-types", + "in": "query" + }, { "type": "string", "format": "date-time", @@ -502,7 +513,7 @@ "tags": [ "notification" ], - "summary": "Mark notification threads as read", + "summary": "Mark notification threads as read, pinned or unread", "operationId": "notifyReadList", "parameters": [ { @@ -511,6 +522,29 @@ "description": "Describes the last point that notifications were checked. Anything updated since this time will not be updated.", "name": "last_read_at", "in": "query" + }, + { + "type": "string", + "description": "If true, mark all notifications on this repo. Default value is false", + "name": "all", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "default": "unread", + "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned", + "name": "status-types", + "in": "query" + }, + { + "default": "read", + "description": "Status to mark notifications as", + "name": "to-status", + "in": "query" } ], "responses": { @@ -587,6 +621,12 @@ "name": "id", "in": "path", "required": true + }, + { + "default": "read", + "description": "Status to mark notifications as", + "name": "to-status", + "in": "query" } ], "responses": { @@ -6382,6 +6422,17 @@ "name": "all", "in": "query" }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "default": "unread, pinned", + "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned", + "name": "status-types", + "in": "query" + }, { "type": "string", "format": "date-time", @@ -6425,7 +6476,7 @@ "tags": [ "notification" ], - "summary": "Mark notification threads as read on a specific repo", + "summary": "Mark notification threads as read, pinned or unread on a specific repo", "operationId": "notifyReadRepoList", "parameters": [ { @@ -6442,6 +6493,29 @@ "in": "path", "required": true }, + { + "type": "string", + "description": "If true, mark all notifications on this repo. Default value is false", + "name": "all", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "default": "unread", + "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned", + "name": "status-types", + "in": "query" + }, + { + "default": "read", + "description": "Status to mark notifications as", + "name": "to-status", + "in": "query" + }, { "type": "string", "format": "date-time", From 99eef995c8839edd5f028441a4accaabbffe68cb Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Mon, 6 Jul 2020 22:56:47 +0100 Subject: [PATCH 3/8] Fix swagger again Signed-off-by: Andrew Thornton --- routers/api/v1/notify/repo.go | 10 ++++------ routers/api/v1/notify/threads.go | 1 + routers/api/v1/notify/user.go | 10 ++++------ templates/swagger/v1_json.tmpl | 21 +++++++++------------ 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 1446e1f38c4b7..728de438f98cd 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -69,12 +69,11 @@ func ListRepoNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned" + // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned" // type: array // collectionFormat: multi // items: // type: string - // default: unread, pinned // required: false // - name: since // in: query @@ -158,17 +157,16 @@ func ReadRepoNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned" + // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread." // type: array // collectionFormat: multi // items: // type: string - // default: unread // required: false // - name: to-status // in: query - // description: Status to mark notifications as - // default: read + // description: Status to mark notifications as. Defaults to read. + // type: string // required: false // - name: last_read_at // in: query diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index f877ae0262334..86ae2dca31821 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -65,6 +65,7 @@ func ReadThread(ctx *context.APIContext) { // - name: to-status // in: query // description: Status to mark notifications as + // type: string // default: read // required: false // responses: diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index 2a47ef66b24b6..9c3f9b1472b43 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -31,12 +31,11 @@ func ListNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned" + // description: "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned." // type: array // collectionFormat: multi // items: // type: string - // default: unread, pinned // required: false // - name: since // in: query @@ -114,17 +113,16 @@ func ReadNotifications(ctx *context.APIContext) { // required: false // - name: status-types // in: query - // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned" + // description: "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread." // type: array // collectionFormat: multi // items: // type: string - // default: unread // required: false // - name: to-status // in: query - // description: Status to mark notifications as - // default: read + // description: Status to mark notifications as, Defaults to read. + // type: string // required: false // responses: // "205": diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 91efc3aac428c..795e179cb9918 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -465,8 +465,7 @@ "type": "string" }, "collectionFormat": "multi", - "default": "unread, pinned", - "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned", + "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread \u0026 pinned.", "name": "status-types", "in": "query" }, @@ -535,14 +534,13 @@ "type": "string" }, "collectionFormat": "multi", - "default": "unread", - "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned", + "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread.", "name": "status-types", "in": "query" }, { - "default": "read", - "description": "Status to mark notifications as", + "type": "string", + "description": "Status to mark notifications as, Defaults to read.", "name": "to-status", "in": "query" } @@ -623,6 +621,7 @@ "required": true }, { + "type": "string", "default": "read", "description": "Status to mark notifications as", "name": "to-status", @@ -6428,8 +6427,7 @@ "type": "string" }, "collectionFormat": "multi", - "default": "unread, pinned", - "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned", + "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread \u0026 pinned", "name": "status-types", "in": "query" }, @@ -6505,14 +6503,13 @@ "type": "string" }, "collectionFormat": "multi", - "default": "unread", - "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned", + "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread.", "name": "status-types", "in": "query" }, { - "default": "read", - "description": "Status to mark notifications as", + "type": "string", + "description": "Status to mark notifications as. Defaults to read.", "name": "to-status", "in": "query" }, From 5309b8c4a692aeb3c2028f439357bd79591fb3c5 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 7 Jul 2020 19:57:24 +0100 Subject: [PATCH 4/8] fix test Signed-off-by: Andrew Thornton --- integrations/api_notification_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/api_notification_test.go b/integrations/api_notification_test.go index 3296604a081fc..42041734200b0 100644 --- a/integrations/api_notification_test.go +++ b/integrations/api_notification_test.go @@ -55,7 +55,7 @@ func TestAPINotification(t *testing.T) { assert.EqualValues(t, false, apiNL[2].Pinned) // -- GET /repos/{owner}/{repo}/notifications -- - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?token=%s", user2.Name, repo1.Name, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread&token=%s", user2.Name, repo1.Name, token)) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) @@ -92,7 +92,7 @@ func TestAPINotification(t *testing.T) { assert.True(t, new.New > 0) // -- mark notifications as read -- - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token)) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 2) @@ -101,7 +101,7 @@ func TestAPINotification(t *testing.T) { req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token)) resp = session.MakeRequest(t, req, http.StatusResetContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token)) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 1) From a7a718aad0092d1d62508db28425fcf6eae83717 Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 7 Jul 2020 20:12:22 +0100 Subject: [PATCH 5/8] remove spurious debugs --- routers/api/v1/notify/repo.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 728de438f98cd..49b493aa4fc59 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -207,9 +207,6 @@ func ReadRepoNotifications(ctx *context.APIContext) { ctx.InternalServerError(err) return } - for _, t := range nl { - log.Error("found thread: %d %d", t.ID, t.Status) - } targetStatus := statusStringToNotificationStatus(ctx.Query("to-status")) if targetStatus == 0 { From cddda260def5a5fce72f2417e4fed8ba9d426448 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Fri, 10 Jul 2020 21:49:17 +0100 Subject: [PATCH 6/8] as per @6543 Signed-off-by: Andrew Thornton --- models/notification.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/models/notification.go b/models/notification.go index c691b5dc06886..19e8f955a109e 100644 --- a/models/notification.go +++ b/models/notification.go @@ -92,11 +92,7 @@ func (opts *FindNotificationOptions) ToCond() builder.Cond { if len(opts.Status) == 1 { cond = cond.And(builder.Eq{"notification.status": opts.Status[0]}) } else if len(opts.Status) > 1 { - eqConds := make([]builder.Cond, 0, len(opts.Status)) - for _, status := range opts.Status { - eqConds = append(eqConds, builder.Eq{"notification.status": status}) - } - cond = cond.And(cond.Or(eqConds...)) + cond = cond.And(builder.In("notifiation.status", opts.Status)) } if opts.UpdatedAfterUnix != 0 { cond = cond.And(builder.Gte{"notification.updated_unix": opts.UpdatedAfterUnix}) From 8a248e48f138f09d949de2e606d701514c309445 Mon Sep 17 00:00:00 2001 From: zeripath Date: Fri, 10 Jul 2020 22:55:38 +0100 Subject: [PATCH 7/8] Update models/notification.go --- models/notification.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/notification.go b/models/notification.go index 19e8f955a109e..3dfd2faa698a5 100644 --- a/models/notification.go +++ b/models/notification.go @@ -92,7 +92,7 @@ func (opts *FindNotificationOptions) ToCond() builder.Cond { if len(opts.Status) == 1 { cond = cond.And(builder.Eq{"notification.status": opts.Status[0]}) } else if len(opts.Status) > 1 { - cond = cond.And(builder.In("notifiation.status", opts.Status)) + cond = cond.And(builder.In("notification.status", opts.Status)) } if opts.UpdatedAfterUnix != 0 { cond = cond.And(builder.Gte{"notification.updated_unix": opts.UpdatedAfterUnix}) From 29d8f57ae30dded564af4112623239d43cf49a19 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sat, 11 Jul 2020 17:24:46 +0100 Subject: [PATCH 8/8] as per @6543 Signed-off-by: Andrew Thornton --- models/notification.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/models/notification.go b/models/notification.go index 3dfd2faa698a5..9258b68f22b1a 100644 --- a/models/notification.go +++ b/models/notification.go @@ -89,9 +89,7 @@ func (opts *FindNotificationOptions) ToCond() builder.Cond { if opts.IssueID != 0 { cond = cond.And(builder.Eq{"notification.issue_id": opts.IssueID}) } - if len(opts.Status) == 1 { - cond = cond.And(builder.Eq{"notification.status": opts.Status[0]}) - } else if len(opts.Status) > 1 { + if len(opts.Status) > 0 { cond = cond.And(builder.In("notification.status", opts.Status)) } if opts.UpdatedAfterUnix != 0 {