From 496a0ba7dc161099213f47ead73a75705fe56a71 Mon Sep 17 00:00:00 2001 From: Jannis Mattheis Date: Sat, 24 Mar 2018 16:41:06 +0100 Subject: [PATCH] Add in memory test database util --- test/database.go | 154 ++++++++++++++++++++++++++++++++++++++++++ test/database_test.go | 134 ++++++++++++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 test/database.go create mode 100644 test/database_test.go diff --git a/test/database.go b/test/database.go new file mode 100644 index 0000000..9d75d92 --- /dev/null +++ b/test/database.go @@ -0,0 +1,154 @@ +package test + +import ( + "fmt" + "testing" + "time" + + "github.com/gotify/server/database" + "github.com/gotify/server/model" + "github.com/stretchr/testify/assert" +) + +// Database is the wrapper for the gorm database with sleek helper methods. +type Database struct { + *database.GormDatabase + t *testing.T +} + +// AppClientBuilder has helper methods to create applications and clients. +type AppClientBuilder struct { + userID uint + db *Database +} + +// MessageBuilder has helper methods to create messages. +type MessageBuilder struct { + appID uint + db *Database +} + +// NewDBWithDefaultUser creates a new test db instance with the default user. +func NewDBWithDefaultUser(t *testing.T) *Database { + db, err := database.New("sqlite3", fmt.Sprintf("file:%s?mode=memory&cache=shared", fmt.Sprint(time.Now().Unix())), "admin", "pw", 5, true) + assert.Nil(t, err) + assert.NotNil(t, db) + return &Database{GormDatabase: db, t: t} +} + +// NewDB creates a new test db instance. +func NewDB(t *testing.T) *Database { + db, err := database.New("sqlite3", fmt.Sprintf("file:%s?mode=memory&cache=shared", fmt.Sprint(time.Now().Unix())), "admin", "pw", 5, false) + assert.Nil(t, err) + assert.NotNil(t, db) + return &Database{GormDatabase: db, t: t} +} + +// User creates a user and returns a builder for applications and clients. +func (d *Database) User(id uint) *AppClientBuilder { + d.NewUser(id) + return &AppClientBuilder{db: d, userID: id} +} + +// NewUser creates a user and returns the user. +func (d *Database) NewUser(id uint) *model.User { + return d.NewUserWithName(id, "user"+fmt.Sprint(id)) +} + +// NewUserWithName creates a user with a name and returns the user. +func (d *Database) NewUserWithName(id uint, name string) *model.User { + user := &model.User{ID: id, Name: name} + d.CreateUser(user) + return user +} + +// App creates an application and returns a message builder. +func (ab *AppClientBuilder) App(id uint) *MessageBuilder { + return ab.AppWithToken(id, "app"+fmt.Sprint(id)) +} + +// AppWithToken creates an application with a token and returns a message builder. +func (ab *AppClientBuilder) AppWithToken(id uint, token string) *MessageBuilder { + ab.NewAppWithToken(id, token) + return &MessageBuilder{db: ab.db, appID: id} +} + +// NewAppWithToken creates an application with a token and returns the app. +func (ab *AppClientBuilder) NewAppWithToken(id uint, token string) *model.Application { + application := &model.Application{ID: id, UserID: ab.userID, Token: token} + ab.db.CreateApplication(application) + return application +} + +// Client creates a client and returns itself. +func (ab *AppClientBuilder) Client(id uint) *AppClientBuilder { + return ab.ClientWithToken(id, "client"+fmt.Sprint(id)) +} + +// ClientWithToken creates a client with a token and returns itself. +func (ab *AppClientBuilder) ClientWithToken(id uint, token string) *AppClientBuilder { + ab.NewClientWithToken(id, token) + return ab +} + +// NewClientWithToken creates a client with a token and returns the client. +func (ab *AppClientBuilder) NewClientWithToken(id uint, token string) *model.Client { + client := &model.Client{ID: id, Token: token, UserID: ab.userID} + ab.db.CreateClient(client) + return client +} + +// Message creates a message and returns itself +func (mb *MessageBuilder) Message(id uint) *MessageBuilder { + mb.NewMessage(id) + return mb +} + +// NewMessage creates a message and returns the message. +func (mb *MessageBuilder) NewMessage(id uint) model.Message { + message := model.Message{ID: id, ApplicationID: mb.appID} + mb.db.CreateMessage(&message) + return message +} + +// AssertAppNotExist asserts that the app does not exist. +func (d *Database) AssertAppNotExist(id uint) { + assert.True(d.t, d.GetApplicationByID(id) == nil, "app %d must not exist", id) +} + +// AssertUserNotExist asserts that the user does not exist. +func (d *Database) AssertUserNotExist(id uint) { + assert.True(d.t, d.GetUserByID(id) == nil, "user %d must not exist", id) +} + +// AssertClientNotExist asserts that the client does not exist. +func (d *Database) AssertClientNotExist(id uint) { + assert.True(d.t, d.GetClientByID(id) == nil, "client %d must not exist", id) +} + +// AssertMessageNotExist asserts that the messages does not exist. +func (d *Database) AssertMessageNotExist(ids ...uint) { + for _, id := range ids { + assert.True(d.t, d.GetMessageByID(id) == nil, "message %d must not exist", id) + } +} + +// AssertAppExist asserts that the app does exist. +func (d *Database) AssertAppExist(id uint) { + assert.False(d.t, d.GetApplicationByID(id) == nil, "app %d must exist", id) +} + +// AssertUserExist asserts that the user does exist. +func (d *Database) AssertUserExist(id uint) { + assert.False(d.t, d.GetUserByID(id) == nil, "user %d must exist", id) +} + +// AssertClientExist asserts that the client does exist. +func (d *Database) AssertClientExist(id uint) { + assert.False(d.t, d.GetClientByID(id) == nil, "client %d must exist", id) +} + +// AssertMessageExist asserts that the message does exist. +func (d *Database) AssertMessageExist(id uint) { + assert.False(d.t, d.GetMessageByID(id) == nil, "message %d must exist", id) +} diff --git a/test/database_test.go b/test/database_test.go new file mode 100644 index 0000000..daa6760 --- /dev/null +++ b/test/database_test.go @@ -0,0 +1,134 @@ +package test_test + +import ( + "testing" + + "github.com/gotify/server/mode" + "github.com/gotify/server/model" + "github.com/gotify/server/test" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +func Test_WithDefault(t *testing.T) { + db := test.NewDBWithDefaultUser(t) + assert.NotNil(t, db.GetUserByName("admin")) + db.Close() +} + +func TestDatabaseSuite(t *testing.T) { + suite.Run(t, new(DatabaseSuite)) +} + +type DatabaseSuite struct { + suite.Suite + db *test.Database +} + +func (s *DatabaseSuite) BeforeTest(suiteName, testName string) { + mode.Set(mode.TestDev) + s.db = test.NewDB(s.T()) +} + +func (s *DatabaseSuite) AfterTest(suiteName, testName string) { + s.db.Close() +} + +func (s *DatabaseSuite) Test_Users() { + s.db.User(1) + newUserActual := s.db.NewUser(2) + s.db.NewUserWithName(3, "tom") + + newUserExpected := &model.User{ID: 2, Name: "user2"} + + assert.Equal(s.T(), newUserExpected, newUserActual) + + users := []*model.User{{ID: 1, Name: "user1"}, {ID: 2, Name: "user2"}, {ID: 3, Name: "tom"}} + + assert.Equal(s.T(), users, s.db.GetUsers()) + s.db.AssertUserExist(1) + s.db.AssertUserExist(2) + s.db.AssertUserExist(3) + s.db.AssertUserNotExist(4) + + s.db.DeleteUserByID(2) + + s.db.AssertUserNotExist(2) +} + +func (s *DatabaseSuite) Test_Clients() { + userBuilder := s.db.User(1) + userBuilder.Client(1) + newClientActual := userBuilder.NewClientWithToken(2, "asdf") + + s.db.User(2).Client(5) + + newClientExpected := &model.Client{ID: 2, Token: "asdf", UserID: 1} + + assert.Equal(s.T(), newClientExpected, newClientActual) + + userOneExpected := []*model.Client{{ID: 1, Token: "client1", UserID: 1}, {ID: 2, Token: "asdf", UserID: 1}} + assert.Equal(s.T(), userOneExpected, s.db.GetClientsByUser(1)) + userTwoExpected := []*model.Client{{ID: 5, Token: "client5", UserID: 2}} + assert.Equal(s.T(), userTwoExpected, s.db.GetClientsByUser(2)) + + s.db.AssertClientExist(1) + s.db.AssertClientExist(2) + s.db.AssertClientNotExist(3) + s.db.AssertClientNotExist(4) + s.db.AssertClientExist(5) + s.db.AssertClientNotExist(6) + + s.db.DeleteClientByID(2) + + s.db.AssertClientNotExist(2) +} + +func (s *DatabaseSuite) Test_Apps() { + userBuilder := s.db.User(1) + userBuilder.App(1) + newAppActual := userBuilder.NewAppWithToken(2, "asdf") + + s.db.User(2).App(5) + + newAppExpected := &model.Application{ID: 2, Token: "asdf", UserID: 1} + + assert.Equal(s.T(), newAppExpected, newAppActual) + + userOneExpected := []*model.Application{{ID: 1, Token: "app1", UserID: 1}, {ID: 2, Token: "asdf", UserID: 1}} + assert.Equal(s.T(), userOneExpected, s.db.GetApplicationsByUser(1)) + userTwoExpected := []*model.Application{{ID: 5, Token: "app5", UserID: 2}} + assert.Equal(s.T(), userTwoExpected, s.db.GetApplicationsByUser(2)) + + s.db.AssertAppExist(1) + s.db.AssertAppExist(2) + s.db.AssertAppNotExist(3) + s.db.AssertAppNotExist(4) + s.db.AssertAppExist(5) + s.db.AssertAppNotExist(6) + + s.db.DeleteApplicationByID(2) + + s.db.AssertAppNotExist(2) +} + +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}} + assert.Equal(s.T(), userOneExpected, s.db.GetMessagesByUser(1)) + userTwoExpected := []*model.Message{{ID: 4, ApplicationID: 2}, {ID: 5, ApplicationID: 2}} + assert.Equal(s.T(), userTwoExpected, s.db.GetMessagesByUser(2)) + + s.db.AssertMessageExist(1) + s.db.AssertMessageExist(2) + s.db.AssertMessageExist(4) + s.db.AssertMessageExist(5) + + s.db.AssertMessageNotExist(3, 6, 7, 8) + + s.db.DeleteMessageByID(2) + + s.db.AssertMessageNotExist(2) +}