github.com/goravel/framework@v1.13.9/database/orm_test.go (about)

     1  package database
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"log"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/suite"
    11  
    12  	contractsorm "github.com/goravel/framework/contracts/database/orm"
    13  	"github.com/goravel/framework/database/gorm"
    14  	"github.com/goravel/framework/database/orm"
    15  	"github.com/goravel/framework/support/file"
    16  )
    17  
    18  var connections = []contractsorm.Driver{
    19  	contractsorm.DriverMysql,
    20  	contractsorm.DriverPostgresql,
    21  	contractsorm.DriverSqlite,
    22  	contractsorm.DriverSqlserver,
    23  }
    24  
    25  type contextKey int
    26  
    27  const testContextKey contextKey = 0
    28  
    29  type User struct {
    30  	orm.Model
    31  	orm.SoftDeletes
    32  	Name   string
    33  	Avatar string
    34  }
    35  
    36  type OrmSuite struct {
    37  	suite.Suite
    38  	orm *OrmImpl
    39  }
    40  
    41  var (
    42  	testMysqlQuery      contractsorm.Query
    43  	testPostgresqlQuery contractsorm.Query
    44  	testSqliteQuery     contractsorm.Query
    45  	testSqlserverDB     contractsorm.Query
    46  )
    47  
    48  func TestOrmSuite(t *testing.T) {
    49  	if testing.Short() {
    50  		t.Skip("Skipping tests of using docker")
    51  	}
    52  
    53  	mysqlDocker := gorm.NewMysqlDocker()
    54  	mysqlPool, mysqlResource, mysqlQuery, err := mysqlDocker.New()
    55  	if err != nil {
    56  		log.Fatalf("Get mysql error: %s", err)
    57  	}
    58  	testMysqlQuery = mysqlQuery
    59  
    60  	postgresqlDocker := gorm.NewPostgresqlDocker()
    61  	postgresqlPool, postgresqlResource, postgresqlQuery, err := postgresqlDocker.New()
    62  	if err != nil {
    63  		log.Fatalf("Get postgresql error: %s", err)
    64  	}
    65  	testPostgresqlQuery = postgresqlQuery
    66  
    67  	sqliteDocker := gorm.NewSqliteDocker("goravel")
    68  	_, _, sqliteQuery, err := sqliteDocker.New()
    69  	if err != nil {
    70  		log.Fatalf("Get sqlite error: %s", err)
    71  	}
    72  	testSqliteQuery = sqliteQuery
    73  
    74  	sqlserverDocker := gorm.NewSqlserverDocker()
    75  	sqlserverPool, sqlserverResource, sqlserverQuery, err := sqlserverDocker.New()
    76  	if err != nil {
    77  		log.Fatalf("Get sqlserver error: %s", err)
    78  	}
    79  	testSqlserverDB = sqlserverQuery
    80  
    81  	suite.Run(t, new(OrmSuite))
    82  
    83  	assert.Nil(t, file.Remove("goravel"))
    84  
    85  	if err := mysqlPool.Purge(mysqlResource); err != nil {
    86  		log.Fatalf("Could not purge resource: %s", err)
    87  	}
    88  	if err := postgresqlPool.Purge(postgresqlResource); err != nil {
    89  		log.Fatalf("Could not purge resource: %s", err)
    90  	}
    91  	if err := sqlserverPool.Purge(sqlserverResource); err != nil {
    92  		log.Fatalf("Could not purge resource: %s", err)
    93  	}
    94  
    95  }
    96  
    97  func (s *OrmSuite) SetupTest() {
    98  	s.orm = &OrmImpl{
    99  		connection: contractsorm.DriverMysql.String(),
   100  		ctx:        context.Background(),
   101  		query:      testMysqlQuery,
   102  		queries: map[string]contractsorm.Query{
   103  			contractsorm.DriverMysql.String():      testMysqlQuery,
   104  			contractsorm.DriverPostgresql.String(): testPostgresqlQuery,
   105  			contractsorm.DriverSqlite.String():     testSqliteQuery,
   106  			contractsorm.DriverSqlserver.String():  testSqlserverDB,
   107  		},
   108  	}
   109  }
   110  
   111  func (s *OrmSuite) TestConnection() {
   112  	for _, connection := range connections {
   113  		s.NotNil(s.orm.Connection(connection.String()))
   114  	}
   115  }
   116  
   117  func (s *OrmSuite) TestDB() {
   118  	db, err := s.orm.DB()
   119  	s.NotNil(db)
   120  	s.Nil(err)
   121  
   122  	for _, connection := range connections {
   123  		db, err := s.orm.Connection(connection.String()).DB()
   124  		s.NotNil(db)
   125  		s.Nil(err)
   126  	}
   127  }
   128  
   129  func (s *OrmSuite) TestQuery() {
   130  	s.NotNil(s.orm.Query())
   131  
   132  	s.NotPanics(func() {
   133  		for i := 0; i < 5; i++ {
   134  			go func() {
   135  				var user User
   136  				_ = s.orm.Query().Find(&user, 1)
   137  			}()
   138  		}
   139  	})
   140  
   141  	for _, connection := range connections {
   142  		s.NotNil(s.orm.Connection(connection.String()).Query())
   143  	}
   144  }
   145  
   146  func (s *OrmSuite) TestFactory() {
   147  	s.NotNil(s.orm.Factory())
   148  
   149  	for _, connection := range connections {
   150  		s.NotNil(s.orm.Connection(connection.String()).Factory())
   151  	}
   152  }
   153  
   154  func (s *OrmSuite) TestObserve() {
   155  	s.orm.Observe(User{}, &UserObserver{})
   156  
   157  	s.Equal([]orm.Observer{
   158  		{Model: User{}, Observer: &UserObserver{}},
   159  	}, orm.Observers)
   160  
   161  	for _, connection := range connections {
   162  		user := User{Name: "observer_name"}
   163  		s.EqualError(s.orm.Connection(connection.String()).Query().Create(&user), "error")
   164  	}
   165  }
   166  
   167  func (s *OrmSuite) TestTransactionSuccess() {
   168  	for _, connection := range connections {
   169  		user := User{Name: "transaction_success_user", Avatar: "transaction_success_avatar"}
   170  		user1 := User{Name: "transaction_success_user1", Avatar: "transaction_success_avatar1"}
   171  		s.Nil(s.orm.Connection(connection.String()).Transaction(func(tx contractsorm.Transaction) error {
   172  			s.Nil(tx.Create(&user))
   173  			s.Nil(tx.Create(&user1))
   174  
   175  			return nil
   176  		}))
   177  
   178  		var user2, user3 User
   179  		s.Nil(s.orm.Connection(connection.String()).Query().Find(&user2, user.ID))
   180  		s.Nil(s.orm.Connection(connection.String()).Query().Find(&user3, user1.ID))
   181  	}
   182  }
   183  
   184  func (s *OrmSuite) TestTransactionError() {
   185  	for _, connection := range connections {
   186  		s.NotNil(s.orm.Connection(connection.String()).Transaction(func(tx contractsorm.Transaction) error {
   187  			user := User{Name: "transaction_error_user", Avatar: "transaction_error_avatar"}
   188  			s.Nil(tx.Create(&user))
   189  
   190  			user1 := User{Name: "transaction_error_user1", Avatar: "transaction_error_avatar1"}
   191  			s.Nil(tx.Create(&user1))
   192  
   193  			return errors.New("error")
   194  		}))
   195  
   196  		var users []User
   197  		s.Nil(s.orm.Connection(connection.String()).Query().Find(&users))
   198  		s.Equal(0, len(users))
   199  	}
   200  }
   201  
   202  func (s *OrmSuite) TestWithContext() {
   203  	s.orm.Observe(User{}, &UserObserver{})
   204  	ctx := context.WithValue(context.Background(), testContextKey, "with_context_goravel")
   205  	user := User{Name: "with_context_name"}
   206  
   207  	// Call Query directly
   208  	err := s.orm.WithContext(ctx).Query().Create(&user)
   209  	s.Nil(err)
   210  	s.Equal("with_context_name", user.Name)
   211  	s.Equal("with_context_goravel", user.Avatar)
   212  
   213  	// Call Connection, then call WithContext
   214  	for _, connection := range connections {
   215  		user.ID = 0
   216  		user.Avatar = ""
   217  		err := s.orm.Connection(connection.String()).WithContext(ctx).Query().Create(&user)
   218  		s.Nil(err)
   219  		s.Equal("with_context_name", user.Name)
   220  		s.Equal("with_context_goravel", user.Avatar)
   221  	}
   222  
   223  	// Call WithContext, then call Connection
   224  	for _, connection := range connections {
   225  		user.ID = 0
   226  		user.Avatar = ""
   227  		err := s.orm.WithContext(ctx).Connection(connection.String()).Query().Create(&user)
   228  		s.Nil(err)
   229  		s.Equal("with_context_name", user.Name)
   230  		s.Equal("with_context_goravel", user.Avatar)
   231  	}
   232  }
   233  
   234  type UserObserver struct{}
   235  
   236  func (u *UserObserver) Retrieved(event contractsorm.Event) error {
   237  	return nil
   238  }
   239  
   240  func (u *UserObserver) Creating(event contractsorm.Event) error {
   241  	name := event.GetAttribute("name")
   242  	if name != nil {
   243  		if name.(string) == "observer_name" {
   244  			return errors.New("error")
   245  		}
   246  		if name.(string) == "with_context_name" {
   247  			if avatar := event.Context().Value(testContextKey); avatar != nil {
   248  				event.SetAttribute("avatar", avatar.(string))
   249  			}
   250  		}
   251  	}
   252  
   253  	return nil
   254  }
   255  
   256  func (u *UserObserver) Created(event contractsorm.Event) error {
   257  	return nil
   258  }
   259  
   260  func (u *UserObserver) Updating(event contractsorm.Event) error {
   261  	return nil
   262  }
   263  
   264  func (u *UserObserver) Updated(event contractsorm.Event) error {
   265  	return nil
   266  }
   267  
   268  func (u *UserObserver) Saving(event contractsorm.Event) error {
   269  	return nil
   270  }
   271  
   272  func (u *UserObserver) Saved(event contractsorm.Event) error {
   273  	return nil
   274  }
   275  
   276  func (u *UserObserver) Deleting(event contractsorm.Event) error {
   277  	return nil
   278  }
   279  
   280  func (u *UserObserver) Deleted(event contractsorm.Event) error {
   281  	return nil
   282  }
   283  
   284  func (u *UserObserver) ForceDeleting(event contractsorm.Event) error {
   285  	return nil
   286  }
   287  
   288  func (u *UserObserver) ForceDeleted(event contractsorm.Event) error {
   289  	return nil
   290  }