fasten-onprem/backend/pkg/database/sqlite_repository_test.go

264 lines
9.0 KiB
Go

package database
import (
"fmt"
sourceModels "github.com/fastenhealth/fasten-sources/clients/models"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg"
mock_config "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config/mock"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models"
"github.com/gin-gonic/gin"
"github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"golang.org/x/net/context"
"io/ioutil"
"log"
"os"
"testing"
)
func TestSourceCredentialInterface(t *testing.T) {
t.Parallel()
repo := new(SqliteRepository)
//assert
require.Implements(t, (*sourceModels.DatabaseRepository)(nil), repo, "should implement the DatabaseRepository interface from fasten-sources")
require.Implements(t, (*DatabaseRepository)(nil), repo, "should implement the DatabaseRepository interface")
}
// Define the suite, and absorb the built-in basic suite
// functionality from testify - including a T() method which
// returns the current testing context
type RepositoryTestSuite struct {
suite.Suite
MockCtrl *gomock.Controller
TestDatabase *os.File
}
// BeforeTest has a function to be executed right before the test starts and receives the suite and test names as input
func (suite *RepositoryTestSuite) BeforeTest(suiteName, testName string) {
suite.MockCtrl = gomock.NewController(suite.T())
dbFile, err := ioutil.TempFile("", fmt.Sprintf("%s.*.db", testName))
if err != nil {
log.Fatal(err)
}
suite.TestDatabase = dbFile
}
// AfterTest has a function to be executed right after the test finishes and receives the suite and test names as input
func (suite *RepositoryTestSuite) AfterTest(suiteName, testName string) {
suite.MockCtrl.Finish()
os.Remove(suite.TestDatabase.Name())
}
// In order for 'go test' to run this suite, we need to create
// a normal test function and pass our suite to suite.Run
func TestRepositoryTestSuite(t *testing.T) {
suite.Run(t, new(RepositoryTestSuite))
}
func (suite *RepositoryTestSuite) TestNewRepository() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
//test
_, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
//assert
require.NoError(suite.T(), err)
}
func (suite *RepositoryTestSuite) TestCreateUser() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
//test
userModel := &models.User{
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
dbRepo.CreateUser(context.Background(), userModel)
//assert
require.NotEmpty(suite.T(), userModel.ID)
}
func (suite *RepositoryTestSuite) TestCreateUser_WithExitingUser_ShouldFail() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
//test
userModel := &models.User{
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
err = dbRepo.CreateUser(context.Background(), userModel)
require.NoError(suite.T(), err)
userModel2 := &models.User{
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
err = dbRepo.CreateUser(context.Background(), userModel2)
//assert
require.Error(suite.T(), err)
}
//TODO: ensure user's cannot specify the ID when creating a user.
func (suite *RepositoryTestSuite) TestCreateUser_WithUserProvidedId_ShouldBeReplaced() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
//test
userProvidedId := uuid.New()
userModel := &models.User{
ModelBase: models.ModelBase{
ID: userProvidedId,
},
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
dbRepo.CreateUser(context.Background(), userModel)
//assert
require.NotEmpty(suite.T(), userModel.ID)
require.NotEqual(suite.T(), userProvidedId.String(), userModel.ID.String())
}
func (suite *RepositoryTestSuite) TestGetUserByUsername() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
userModel := &models.User{
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
err = dbRepo.CreateUser(context.Background(), userModel)
require.NoError(suite.T(), err)
//test
userModelResult, err := dbRepo.GetUserByUsername(context.Background(), "test_username")
//assert
require.NoError(suite.T(), err)
require.Equal(suite.T(), userModel.ID, userModelResult.ID)
}
func (suite *RepositoryTestSuite) TestGetUserByUsername_WithInvalidUsername() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
userModel := &models.User{
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
err = dbRepo.CreateUser(context.Background(), userModel)
require.NoError(suite.T(), err)
//test
_, err = dbRepo.GetUserByUsername(context.Background(), "userdoesntexist")
//assert
require.Error(suite.T(), err)
}
func (suite *RepositoryTestSuite) TestGetCurrentUser_WithContextBackgroundAuthUser() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
userModel := &models.User{
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
err = dbRepo.CreateUser(context.Background(), userModel)
require.NoError(suite.T(), err)
//test
userModelResult, err := dbRepo.GetCurrentUser(context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username"))
//assert
require.NoError(suite.T(), err)
require.NotNil(suite.T(), userModelResult)
require.Equal(suite.T(), userModelResult.Username, "test_username")
}
func (suite *RepositoryTestSuite) TestGetCurrentUser_WithGinContextBackgroundAuthUser() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
userModel := &models.User{
Username: "test_username",
Password: "testpassword",
Email: "test@test.com",
}
err = dbRepo.CreateUser(context.Background(), userModel)
require.NoError(suite.T(), err)
//test
ginContext := gin.Context{}
ginContext.Set(pkg.ContextKeyTypeAuthUsername, "test_username")
userModelResult, err := dbRepo.GetCurrentUser(&ginContext)
//assert
require.NoError(suite.T(), err)
require.NotNil(suite.T(), userModelResult)
require.Equal(suite.T(), userModelResult.Username, "test_username")
}
func (suite *RepositoryTestSuite) TestGetCurrentUser_WithContextBackgroundAuthUserAndNoUserExists_ShouldThrowError() {
//setup
fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()))
require.NoError(suite.T(), err)
//test
userModelResult, err := dbRepo.GetCurrentUser(context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username"))
//assert
require.Error(suite.T(), err)
require.Nil(suite.T(), userModelResult)
}
//TODO - merging multiple Compositions is broken