gitlab.com/ignitionrobotics/web/ign-go@v1.0.0-rc4/repository/sql_repository_test.go (about)

     1  package repository
     2  
     3  import (
     4  	"github.com/jinzhu/gorm"
     5  	"github.com/stretchr/testify/suite"
     6  	utilsgorm "gitlab.com/ignitionrobotics/web/ign-go/database/gorm"
     7  	"testing"
     8  )
     9  
    10  func TestRepository(t *testing.T) {
    11  	suite.Run(t, new(RepositoryTestSuite))
    12  }
    13  
    14  type RepositoryTestSuite struct {
    15  	suite.Suite
    16  	db         *gorm.DB
    17  	Repository Repository
    18  }
    19  
    20  type Test struct {
    21  	ModelSQL
    22  	Name  string `json:"name"`
    23  	Value int    `json:"value"`
    24  }
    25  
    26  func (t Test) GetID() uint {
    27  	return t.ID
    28  }
    29  
    30  func (t Test) TableName() string {
    31  	return "test"
    32  }
    33  
    34  func (suite *RepositoryTestSuite) SetupSuite() {
    35  	db, err := utilsgorm.GetTestDBFromEnvVars()
    36  	suite.Require().NoError(err)
    37  	suite.db = db
    38  
    39  	suite.Repository = NewRepositorySQL(suite.db, &Test{})
    40  }
    41  
    42  func (suite *RepositoryTestSuite) SetupTest() {
    43  	suite.Require().NoError(suite.db.DropTableIfExists(&Test{}).Error)
    44  	suite.Require().NoError(suite.db.AutoMigrate(&Test{}).Error)
    45  
    46  	test1 := &Test{
    47  		Name:  "Test1",
    48  		Value: 1,
    49  	}
    50  	test2 := &Test{
    51  		Name:  "Test2",
    52  		Value: 2,
    53  	}
    54  
    55  	test3 := &Test{
    56  		Name:  "Test3",
    57  		Value: 3,
    58  	}
    59  
    60  	res, err := suite.Repository.CreateBulk([]Model{test1, test2, test3})
    61  	suite.Require().NoError(err)
    62  	suite.Require().Len(res, 3)
    63  }
    64  
    65  func (suite *RepositoryTestSuite) TearDownSuite() {
    66  	suite.Require().NoError(suite.db.DropTableIfExists(&Test{}).Error)
    67  	suite.Require().NoError(suite.db.Close())
    68  }
    69  
    70  func (suite *RepositoryTestSuite) TestImplementsInterface() {
    71  	var expected *Repository
    72  	suite.Assert().Implements(expected, new(repositorySQL))
    73  }
    74  
    75  func (suite *RepositoryTestSuite) TestCreateOne() {
    76  	// Creating one record should not fail.
    77  	res, err := suite.Repository.CreateBulk([]Model{&Test{
    78  		Name:  "test",
    79  		Value: 999,
    80  	}})
    81  	suite.Assert().NoError(err)
    82  	suite.Assert().Len(res, 1)
    83  
    84  	var count int64
    85  	err = suite.db.Model(&Test{}).Count(&count).Error
    86  	suite.Require().NoError(err)
    87  	suite.Assert().Equal(int64(4), count)
    88  }
    89  
    90  func (suite *RepositoryTestSuite) TestCreateMultiple() {
    91  	// Creating multiple records should not fail
    92  	res, err := suite.Repository.CreateBulk([]Model{
    93  		&Test{
    94  			Name:  "test",
    95  			Value: 999,
    96  		},
    97  		&Test{
    98  			Name:  "test",
    99  			Value: 999,
   100  		},
   101  		&Test{
   102  			Name:  "test",
   103  			Value: 999,
   104  		},
   105  	})
   106  	suite.Assert().NoError(err)
   107  	suite.Assert().Len(res, 3)
   108  
   109  	// And those records should be in the database.
   110  	var count int64
   111  	err = suite.db.Model(&Test{}).Count(&count).Error
   112  	suite.Require().NoError(err)
   113  	suite.Assert().Equal(int64(6), count)
   114  }
   115  
   116  func (suite *RepositoryTestSuite) TestFind() {
   117  	var t []Test
   118  
   119  	// Finding multiple records should not fail.
   120  	err := suite.Repository.Find(&t, nil, nil, Filter{
   121  		Template: "name IN (?)",
   122  		Values:   []interface{}{[]string{"Test1", "Test2"}},
   123  	})
   124  	suite.Assert().NoError(err)
   125  
   126  	suite.Assert().Len(t, 2)
   127  }
   128  
   129  func (suite *RepositoryTestSuite) TestFindOne() {
   130  	var t Test
   131  
   132  	// Finding one should not fail.
   133  	suite.Assert().NoError(suite.Repository.FindOne(&t, Filter{
   134  		Template: "name = ?",
   135  		Values:   []interface{}{"Test1"},
   136  	}, Filter{
   137  		Template: "value = ?",
   138  		Values:   []interface{}{1},
   139  	}))
   140  
   141  	suite.Assert().Equal("Test1", t.Name)
   142  	suite.Assert().Equal(1, t.Value)
   143  }
   144  
   145  func (suite *RepositoryTestSuite) TestUpdate() {
   146  	filter := Filter{
   147  		Template: "name = ?",
   148  		Values:   []interface{}{"Test1"},
   149  	}
   150  
   151  	// Update record using filters should not fail.
   152  	suite.Assert().NoError(suite.Repository.Update(map[string]interface{}{"name": "Test111", "value": 12345}, filter))
   153  
   154  	var t Test
   155  
   156  	// Finding the old record should fail.
   157  	suite.Assert().Error(suite.Repository.FindOne(&t, filter))
   158  
   159  	// Finding the correct record should not fail.
   160  	suite.Assert().NoError(suite.Repository.FindOne(&t, Filter{
   161  		Template: "name = ?",
   162  		Values:   []interface{}{"Test111"},
   163  	}))
   164  
   165  	// The updated values should be in the record
   166  	suite.Assert().Equal("Test111", t.Name)
   167  	suite.Assert().Equal(12345, t.Value)
   168  }
   169  
   170  func (suite *RepositoryTestSuite) TestDelete() {
   171  	filter := Filter{
   172  		Template: "name = ?",
   173  		Values:   []interface{}{"Test1"},
   174  	}
   175  
   176  	// Deleting should not fail.
   177  	suite.Assert().NoError(suite.Repository.Delete(filter))
   178  
   179  	// Finding one should fail, the record no longer exists.
   180  	var t Test
   181  	suite.Assert().Error(suite.Repository.FindOne(&t, filter))
   182  
   183  	// Deleting is idempotent, deleting twice should not return an error.
   184  	suite.Assert().NoError(suite.Repository.Delete(filter))
   185  }
   186  
   187  func (suite *RepositoryTestSuite) TestFirstOrCreate() {
   188  	var test Test
   189  	suite.Require().NoError(suite.Repository.FirstOrCreate(&test, Filter{
   190  		Template: "value = ?",
   191  		Values:   []interface{}{1},
   192  	}))
   193  
   194  	suite.Assert().Equal(uint(1), test.ID)
   195  	suite.Assert().Equal("Test1", test.Name)
   196  
   197  	test = Test{
   198  		Name:  "Test4",
   199  		Value: 4,
   200  	}
   201  
   202  	suite.Require().NoError(suite.Repository.FirstOrCreate(&test, Filter{
   203  		Template: "value = ?",
   204  		Values:   []interface{}{4},
   205  	}))
   206  
   207  	suite.Assert().Equal(uint(4), test.ID)
   208  	suite.Assert().Equal("Test4", test.Name)
   209  }