Skip to content

Commit 72bd8c8

Browse files
Add default message priority for applications
Co-authored-by: Jannis Mattheis <contact@jmattheis.de>
1 parent aedc3e2 commit 72bd8c8

18 files changed

Lines changed: 210 additions & 35 deletions

api/application.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ type ApplicationParams struct {
4444
//
4545
// example: Backup server for the interwebs
4646
Description string `form:"description" query:"description" json:"description"`
47+
// The default priority of messages sent by this application. Defaults to 0.
48+
//
49+
// example: 5
50+
DefaultPriority int `form:"defaultPriority" query:"defaultPriority" json:"defaultPriority"`
4751
}
4852

4953
// CreateApplication creates an application and returns the access token.
@@ -83,11 +87,12 @@ func (a *ApplicationAPI) CreateApplication(ctx *gin.Context) {
8387
applicationParams := ApplicationParams{}
8488
if err := ctx.Bind(&applicationParams); err == nil {
8589
app := model.Application{
86-
Name: applicationParams.Name,
87-
Description: applicationParams.Description,
88-
Token: auth.GenerateNotExistingToken(generateApplicationToken, a.applicationExists),
89-
UserID: auth.GetUserID(ctx),
90-
Internal: false,
90+
Name: applicationParams.Name,
91+
Description: applicationParams.Description,
92+
DefaultPriority: applicationParams.DefaultPriority,
93+
Token: auth.GenerateNotExistingToken(generateApplicationToken, a.applicationExists),
94+
UserID: auth.GetUserID(ctx),
95+
Internal: false,
9196
}
9297

9398
if success := successOrAbort(ctx, 500, a.DB.CreateApplication(&app)); !success {
@@ -245,6 +250,7 @@ func (a *ApplicationAPI) UpdateApplication(ctx *gin.Context) {
245250
if err := ctx.Bind(&applicationParams); err == nil {
246251
app.Description = applicationParams.Description
247252
app.Name = applicationParams.Name
253+
app.DefaultPriority = applicationParams.DefaultPriority
248254

249255
if success := successOrAbort(ctx, 500, a.DB.UpdateApplication(app)); !success {
250256
return

api/application_test.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (s *ApplicationSuite) Test_ensureApplicationHasCorrectJsonRepresentation()
9292
Image: "asd",
9393
Internal: true,
9494
}
95-
test.JSONEquals(s.T(), actual, `{"id":1,"token":"Aasdasfgeeg","name":"myapp","description":"mydesc", "image": "asd", "internal":true}`)
95+
test.JSONEquals(s.T(), actual, `{"id":1,"token":"Aasdasfgeeg","name":"myapp","description":"mydesc", "image": "asd", "internal":true, "defaultPriority":0}`)
9696
}
9797

9898
func (s *ApplicationSuite) Test_CreateApplication_expectBadRequestOnEmptyName() {
@@ -527,6 +527,29 @@ func (s *ApplicationSuite) Test_UpdateApplicationName_expectSuccess() {
527527
}
528528
}
529529

530+
func (s *ApplicationSuite) Test_UpdateApplicationDefaultPriority_expectSuccess() {
531+
s.db.User(5).NewAppWithToken(2, "app-2")
532+
533+
test.WithUser(s.ctx, 5)
534+
s.withFormData("name=name&description=&defaultPriority=4")
535+
s.ctx.Params = gin.Params{{Key: "id", Value: "2"}}
536+
s.a.UpdateApplication(s.ctx)
537+
538+
expected := &model.Application{
539+
ID: 2,
540+
Token: "app-2",
541+
UserID: 5,
542+
Name: "name",
543+
Description: "",
544+
DefaultPriority: 4,
545+
}
546+
547+
assert.Equal(s.T(), 200, s.recorder.Code)
548+
if app, err := s.db.GetApplicationByID(2); assert.NoError(s.T(), err) {
549+
assert.Equal(s.T(), expected, app)
550+
}
551+
}
552+
530553
func (s *ApplicationSuite) Test_UpdateApplication_preservesImage() {
531554
app := s.db.User(5).NewAppWithToken(2, "app-2")
532555
app.Image = "existing.png"

api/message.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,11 @@ func (a *MessageAPI) CreateMessage(ctx *gin.Context) {
371371
if strings.TrimSpace(message.Title) == "" {
372372
message.Title = application.Name
373373
}
374+
375+
if message.Priority == nil {
376+
message.Priority = &application.DefaultPriority
377+
}
378+
374379
message.Date = timeNow()
375380
message.ID = 0
376381
msgInternal := toInternalMessage(&message)
@@ -388,9 +393,12 @@ func toInternalMessage(msg *model.MessageExternal) *model.Message {
388393
ApplicationID: msg.ApplicationID,
389394
Message: msg.Message,
390395
Title: msg.Title,
391-
Priority: msg.Priority,
392396
Date: msg.Date,
393397
}
398+
if msg.Priority != nil {
399+
res.Priority = *msg.Priority
400+
}
401+
394402
if msg.Extras != nil {
395403
res.Extras, _ = json.Marshal(msg.Extras)
396404
}
@@ -403,7 +411,7 @@ func toExternalMessage(msg *model.Message) *model.MessageExternal {
403411
ApplicationID: msg.ApplicationID,
404412
Message: msg.Message,
405413
Title: msg.Title,
406-
Priority: msg.Priority,
414+
Priority: &msg.Priority,
407415
Date: msg.Date,
408416
}
409417
if len(msg.Extras) != 0 {

api/message_test.go

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (s *MessageSuite) Test_ensureCorrectJsonRepresentation() {
5353

5454
actual := &model.PagedMessages{
5555
Paging: model.Paging{Limit: 5, Since: 122, Size: 5, Next: "http://example.com/message?limit=5&since=122"},
56-
Messages: []*model.MessageExternal{{ID: 55, ApplicationID: 2, Message: "hi", Title: "hi", Date: t, Priority: 4, Extras: map[string]interface{}{
56+
Messages: []*model.MessageExternal{{ID: 55, ApplicationID: 2, Message: "hi", Title: "hi", Date: t, Priority: intPtr(4), Extras: map[string]interface{}{
5757
"test::string": "string",
5858
"test::array": []interface{}{1, 2, 3},
5959
"test::int": 1,
@@ -331,7 +331,29 @@ func (s *MessageSuite) Test_CreateMessage_onJson_allParams() {
331331

332332
msgs, err := s.db.GetMessagesByApplication(7)
333333
assert.NoError(s.T(), err)
334-
expected := &model.MessageExternal{ID: 1, ApplicationID: 7, Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
334+
expected := &model.MessageExternal{ID: 1, ApplicationID: 7, Title: "mytitle", Message: "mymessage", Priority: intPtr(1), Date: t}
335+
assert.Len(s.T(), msgs, 1)
336+
assert.Equal(s.T(), expected, toExternalMessage(msgs[0]))
337+
assert.Equal(s.T(), 200, s.recorder.Code)
338+
assert.Equal(s.T(), expected, s.notifiedMessage)
339+
}
340+
341+
func (s *MessageSuite) Test_CreateMessage_WithDefaultPriority() {
342+
t, _ := time.Parse("2006/01/02", "2017/01/02")
343+
344+
timeNow = func() time.Time { return t }
345+
defer func() { timeNow = time.Now }()
346+
347+
auth.RegisterAuthentication(s.ctx, nil, 4, "app-token")
348+
s.db.User(4).AppWithTokenAndDefaultPriority(8, "app-token", 5)
349+
s.ctx.Request = httptest.NewRequest("POST", "/message", strings.NewReader(`{"title": "mytitle", "message": "mymessage"}`))
350+
s.ctx.Request.Header.Set("Content-Type", "application/json")
351+
352+
s.a.CreateMessage(s.ctx)
353+
354+
msgs, err := s.db.GetMessagesByApplication(8)
355+
assert.NoError(s.T(), err)
356+
expected := &model.MessageExternal{ID: 1, ApplicationID: 8, Title: "mytitle", Message: "mymessage", Priority: intPtr(5), Date: t}
335357
assert.Len(s.T(), msgs, 1)
336358
assert.Equal(s.T(), expected, toExternalMessage(msgs[0]))
337359
assert.Equal(s.T(), 200, s.recorder.Code)
@@ -352,7 +374,7 @@ func (s *MessageSuite) Test_CreateMessage_WithTitle() {
352374

353375
msgs, err := s.db.GetMessagesByApplication(5)
354376
assert.NoError(s.T(), err)
355-
expected := &model.MessageExternal{ID: 1, ApplicationID: 5, Title: "mytitle", Message: "mymessage", Date: t}
377+
expected := &model.MessageExternal{ID: 1, ApplicationID: 5, Title: "mytitle", Message: "mymessage", Date: t, Priority: intPtr(0)}
356378
assert.Len(s.T(), msgs, 1)
357379
assert.Equal(s.T(), expected, toExternalMessage(msgs[0]))
358380
assert.Equal(s.T(), 200, s.recorder.Code)
@@ -446,6 +468,7 @@ func (s *MessageSuite) Test_CreateMessage_WithExtras() {
446468
Message: "mymessage",
447469
Title: "msg with extras",
448470
Date: t,
471+
Priority: intPtr(0),
449472
Extras: map[string]interface{}{
450473
"gotify::test": map[string]interface{}{
451474
"string": "test",
@@ -492,7 +515,7 @@ func (s *MessageSuite) Test_CreateMessage_onQueryData() {
492515

493516
s.a.CreateMessage(s.ctx)
494517

495-
expected := &model.MessageExternal{ID: 1, ApplicationID: 2, Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
518+
expected := &model.MessageExternal{ID: 1, ApplicationID: 2, Title: "mytitle", Message: "mymessage", Priority: intPtr(1), Date: t}
496519

497520
msgs, err := s.db.GetMessagesByApplication(2)
498521
assert.NoError(s.T(), err)
@@ -515,7 +538,7 @@ func (s *MessageSuite) Test_CreateMessage_onFormData() {
515538

516539
s.a.CreateMessage(s.ctx)
517540

518-
expected := &model.MessageExternal{ID: 1, ApplicationID: 99, Title: "mytitle", Message: "mymessage", Priority: 1, Date: t}
541+
expected := &model.MessageExternal{ID: 1, ApplicationID: 99, Title: "mytitle", Message: "mymessage", Priority: intPtr(1), Date: t}
519542
msgs, err := s.db.GetMessagesByApplication(99)
520543
assert.NoError(s.T(), err)
521544
assert.Len(s.T(), msgs, 1)
@@ -528,3 +551,7 @@ func (s *MessageSuite) withURL(scheme, host, path, query string) {
528551
s.ctx.Request.URL = &url.URL{Path: path, RawQuery: query}
529552
s.ctx.Set("location", &url.URL{Scheme: scheme, Host: host})
530553
}
554+
555+
func intPtr(x int) *int {
556+
return &x
557+
}

docs/spec.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2063,6 +2063,13 @@
20632063
"image"
20642064
],
20652065
"properties": {
2066+
"defaultPriority": {
2067+
"description": "The default priority of messages sent by this application. Defaults to 0.",
2068+
"type": "integer",
2069+
"format": "int64",
2070+
"x-go-name": "DefaultPriority",
2071+
"example": 4
2072+
},
20662073
"description": {
20672074
"description": "The description of the application.",
20682075
"type": "string",
@@ -2115,6 +2122,13 @@
21152122
"name"
21162123
],
21172124
"properties": {
2125+
"defaultPriority": {
2126+
"description": "The default priority of messages sent by this application. Defaults to 0.",
2127+
"type": "integer",
2128+
"format": "int64",
2129+
"x-go-name": "DefaultPriority",
2130+
"example": 5
2131+
},
21182132
"description": {
21192133
"description": "The description of the application.",
21202134
"type": "string",
@@ -2326,7 +2340,7 @@
23262340
"example": "**Backup** was successfully finished."
23272341
},
23282342
"priority": {
2329-
"description": "The priority of the message.",
2343+
"description": "The priority of the message. If unset, then the default priority of the\napplication will be used.",
23302344
"type": "integer",
23312345
"format": "int64",
23322346
"x-go-name": "Priority",

model/application.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,9 @@ type Application struct {
4242
// example: image/image.jpeg
4343
Image string `gorm:"type:text" json:"image"`
4444
Messages []MessageExternal `json:"-"`
45+
// The default priority of messages sent by this application. Defaults to 0.
46+
//
47+
// required: false
48+
// example: 4
49+
DefaultPriority int `form:"defaultPriority" query:"defaultPriority" json:"defaultPriority"`
4550
}

model/message.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ type MessageExternal struct {
4242
//
4343
// example: Backup
4444
Title string `form:"title" query:"title" json:"title"`
45-
// The priority of the message.
45+
// The priority of the message. If unset, then the default priority of the
46+
// application will be used.
4647
//
4748
// example: 2
48-
Priority int `form:"priority" query:"priority" json:"priority"`
49+
Priority *int `form:"priority" query:"priority" json:"priority"`
4950
// The extra data sent along the message.
5051
//
5152
// The extra fields are stored in a key-value scheme. Only accepted in CreateMessage requests with application/json content-type.

plugin/manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func NewManager(db Database, directory string, mux *gin.RouterGroup, notifier No
7070
internalMsg := &model.Message{
7171
ApplicationID: message.Message.ApplicationID,
7272
Title: message.Message.Title,
73-
Priority: message.Message.Priority,
73+
Priority: *message.Message.Priority,
7474
Date: message.Message.Date,
7575
Message: message.Message.Message,
7676
}

plugin/messagehandler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func (c redirectToChannel) SendMessage(msg compat.Message) error {
2626
ApplicationID: c.ApplicationID,
2727
Message: msg.Message,
2828
Title: msg.Title,
29-
Priority: msg.Priority,
29+
Priority: &msg.Priority,
3030
Date: time.Now(),
3131
Extras: msg.Extras,
3232
},

test/testdb/database.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ func (ab *AppClientBuilder) newAppWithTokenAndName(id uint, token, name string,
138138
return application
139139
}
140140

141+
// AppWithTokenAndDefaultPriority creates an application with a token and defaultPriority and returns a message builder.
142+
func (ab *AppClientBuilder) AppWithTokenAndDefaultPriority(id uint, token string, defaultPriority int) *MessageBuilder {
143+
application := &model.Application{ID: id, UserID: ab.userID, Token: token, DefaultPriority: defaultPriority}
144+
ab.db.CreateApplication(application)
145+
return &MessageBuilder{db: ab.db, appID: id}
146+
}
147+
141148
// Client creates a client and returns itself.
142149
func (ab *AppClientBuilder) Client(id uint) *AppClientBuilder {
143150
return ab.ClientWithToken(id, "client"+fmt.Sprint(id))

0 commit comments

Comments
 (0)