From 1831b6078f799bc6d206402ece7af87b5f58d3a8 Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Sun, 8 Apr 2018 14:33:23 +0200 Subject: [PATCH] [#34] Add db calls for paged message api --- database/message.go | 29 ++++++++++++++-- database/message_test.go | 75 ++++++++++++++++++++++++++++++++++++++++ router/router_test.go | 6 ++-- test/database_test.go | 4 +-- 4 files changed, 107 insertions(+), 7 deletions(-) diff --git a/database/message.go b/database/message.go index a7bbc3f..99f1906 100644 --- a/database/message.go +++ b/database/message.go @@ -23,14 +23,39 @@ func (d *GormDatabase) CreateMessage(message *model.Message) error { func (d *GormDatabase) GetMessagesByUser(userID uint) []*model.Message { var messages []*model.Message d.DB.Joins("JOIN applications ON applications.user_id = ?", userID). - Where("messages.application_id = applications.id").Order("date desc").Find(&messages) + Where("messages.application_id = applications.id").Order("id desc").Find(&messages) + return messages +} + +// GetMessagesByUserSince returns limited messages from a user. +// If since is 0 it will be ignored. +func (d *GormDatabase) GetMessagesByUserSince(userID uint, limit int, since uint) []*model.Message { + var messages []*model.Message + db := d.DB.Joins("JOIN applications ON applications.user_id = ?", userID). + Where("messages.application_id = applications.id").Order("id desc").Limit(limit) + if since != 0 { + db = db.Where("messages.id < ?", since) + } + db.Find(&messages) return messages } // GetMessagesByApplication returns all messages from an application. func (d *GormDatabase) GetMessagesByApplication(tokenID uint) []*model.Message { var messages []*model.Message - d.DB.Where("application_id = ?", tokenID).Order("date desc").Find(&messages) + d.DB.Where("application_id = ?", tokenID).Order("id desc").Find(&messages) + return messages +} + +// GetMessagesByApplicationSince returns limited messages from an application. +// If since is 0 it will be ignored. +func (d *GormDatabase) GetMessagesByApplicationSince(appID uint, limit int, since uint) []*model.Message { + var messages []*model.Message + db := d.DB.Where("application_id = ?", appID).Order("id desc").Limit(limit) + if since != 0 { + db = db.Where("messages.id < ?", since) + } + db.Find(&messages) return messages } diff --git a/database/message_test.go b/database/message_test.go index 15c72e5..8f83bdc 100644 --- a/database/message_test.go +++ b/database/message_test.go @@ -121,6 +121,81 @@ func (s *DatabaseSuite) TestMessage() { assert.Empty(s.T(), s.db.GetMessagesByUser(user.ID)) } +func (s *DatabaseSuite) TestGetMessagesSince() { + user := &model.User{Name: "test", Pass: []byte{1}} + s.db.CreateUser(user) + + app := &model.Application{UserID: user.ID, Token: "A0000000000"} + app2 := &model.Application{UserID: user.ID, Token: "A0000000001"} + s.db.CreateApplication(app) + s.db.CreateApplication(app2) + + curDate := time.Now() + for i := 1; i <= 500; i++ { + s.db.CreateMessage(&model.Message{ApplicationID: app.ID, Message: "abc", Date: curDate.Add(time.Duration(i) * time.Second)}) + s.db.CreateMessage(&model.Message{ApplicationID: app2.ID, Message: "abc", Date: curDate.Add(time.Duration(i) * time.Second)}) + } + + actual := s.db.GetMessagesByUserSince(user.ID, 50, 0) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 1000, 951, 1) + + actual = s.db.GetMessagesByUserSince(user.ID, 50, 951) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 950, 901, 1) + + actual = s.db.GetMessagesByUserSince(user.ID, 100, 951) + assert.Len(s.T(), actual, 100) + hasIDInclusiveBetween(s.T(), actual, 950, 851, 1) + + actual = s.db.GetMessagesByUserSince(user.ID, 100, 51) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 50, 1, 1) + + actual = s.db.GetMessagesByApplicationSince(app.ID, 50, 0) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 999, 901, 2) + + actual = s.db.GetMessagesByApplicationSince(app.ID, 50, 901) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 899, 801, 2) + + actual = s.db.GetMessagesByApplicationSince(app.ID, 100, 666) + assert.Len(s.T(), actual, 100) + hasIDInclusiveBetween(s.T(), actual, 665, 467, 2) + + actual = s.db.GetMessagesByApplicationSince(app.ID, 100, 101) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 99, 1, 2) + + actual = s.db.GetMessagesByApplicationSince(app2.ID, 50, 0) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 1000, 902, 2) + + actual = s.db.GetMessagesByApplicationSince(app2.ID, 50, 902) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 900, 802, 2) + + actual = s.db.GetMessagesByApplicationSince(app2.ID, 100, 667) + assert.Len(s.T(), actual, 100) + hasIDInclusiveBetween(s.T(), actual, 666, 468, 2) + + actual = s.db.GetMessagesByApplicationSince(app2.ID, 100, 102) + assert.Len(s.T(), actual, 50) + hasIDInclusiveBetween(s.T(), actual, 100, 2, 2) +} + +func hasIDInclusiveBetween(t *testing.T, msgs []*model.Message, from, to, decrement int) { + index := 0 + for expectedID := from; expectedID >= to; expectedID -= decrement { + if !assert.Equal(t, uint(expectedID), msgs[index].ID) { + break + } + index++ + } + assert.Equal(t, index, len(msgs), "not all entries inside msgs were checked") +} + // assertEquals compares messages and correctly check dates func assertEquals(t *testing.T, left *model.Message, right *model.Message) { assert.Equal(t, left.Date.Unix(), right.Date.Unix()) diff --git a/router/router_test.go b/router/router_test.go index f59bd18..c23badc 100644 --- a/router/router_test.go +++ b/router/router_test.go @@ -102,11 +102,11 @@ func (s *IntegrationSuite) TestSendMessage() { res, err = client.Do(req) assert.Nil(s.T(), err) assert.Equal(s.T(), 200, res.StatusCode) - var msgs []model.Message + msgs := &model.PagedMessages{} json.NewDecoder(res.Body).Decode(&msgs) - assert.Len(s.T(), msgs, 1) + assert.Len(s.T(), msgs.Messages, 1) - msg := msgs[0] + msg := msgs.Messages[0] assert.Equal(s.T(), "backup done", msg.Message) assert.Equal(s.T(), "backup done", msg.Title) assert.Equal(s.T(), uint(1), msg.ID) diff --git a/test/database_test.go b/test/database_test.go index daa6760..7ff22b4 100644 --- a/test/database_test.go +++ b/test/database_test.go @@ -116,9 +116,9 @@ func (s *DatabaseSuite) Test_Messages() { s.db.User(1).App(1).Message(1).Message(2) s.db.User(2).App(2).Message(4).Message(5) - userOneExpected := []*model.Message{{ID: 1, ApplicationID: 1}, {ID: 2, ApplicationID: 1}} + userOneExpected := []*model.Message{{ID: 2, ApplicationID: 1}, {ID: 1, ApplicationID: 1}} assert.Equal(s.T(), userOneExpected, s.db.GetMessagesByUser(1)) - userTwoExpected := []*model.Message{{ID: 4, ApplicationID: 2}, {ID: 5, ApplicationID: 2}} + userTwoExpected := []*model.Message{{ID: 5, ApplicationID: 2}, {ID: 4, ApplicationID: 2}} assert.Equal(s.T(), userTwoExpected, s.db.GetMessagesByUser(2)) s.db.AssertMessageExist(1)