github.com/Accefy/pop@v0.0.0-20230428174248-e9f677eab5b9/pop_test.go (about)

     1  package pop
     2  
     3  import (
     4  	stdlog "log"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/gobuffalo/nulls"
    10  	"github.com/gobuffalo/pop/v6/logging"
    11  	"github.com/gobuffalo/validate/v3"
    12  	"github.com/gobuffalo/validate/v3/validators"
    13  	"github.com/gofrs/uuid"
    14  	"github.com/stretchr/testify/suite"
    15  )
    16  
    17  var PDB *Connection
    18  
    19  type PostgreSQLSuite struct {
    20  	suite.Suite
    21  }
    22  
    23  type MySQLSuite struct {
    24  	suite.Suite
    25  }
    26  
    27  type SQLiteSuite struct {
    28  	suite.Suite
    29  }
    30  
    31  type CockroachSuite struct {
    32  	suite.Suite
    33  }
    34  
    35  func TestSpecificSuites(t *testing.T) {
    36  	switch os.Getenv("SODA_DIALECT") {
    37  	case "postgres":
    38  		suite.Run(t, &PostgreSQLSuite{})
    39  	case "mysql", "mysql_travis":
    40  		suite.Run(t, &MySQLSuite{})
    41  	case "sqlite":
    42  		suite.Run(t, &SQLiteSuite{})
    43  	case "cockroach":
    44  		suite.Run(t, &CockroachSuite{})
    45  	}
    46  }
    47  
    48  func init() {
    49  	Debug = false
    50  	AddLookupPaths("./")
    51  
    52  	dialect := os.Getenv("SODA_DIALECT")
    53  
    54  	if dialect == "" {
    55  		log(logging.Info, "Skipping integration tests because SODA_DIALECT is blank or unset")
    56  		return
    57  	}
    58  
    59  	if err := LoadConfigFile(); err != nil {
    60  		stdlog.Panic(err)
    61  	}
    62  
    63  	var err error
    64  	log(logging.Info, "Run test with dialect %v", dialect)
    65  	PDB, err = Connect(dialect)
    66  	if err != nil {
    67  		stdlog.Panic(err)
    68  	}
    69  }
    70  
    71  func transaction(fn func(tx *Connection)) {
    72  	err := PDB.Rollback(func(tx *Connection) {
    73  		fn(tx)
    74  	})
    75  	if err != nil {
    76  		stdlog.Fatal(err)
    77  	}
    78  }
    79  
    80  func ts(s string) string {
    81  	return PDB.Dialect.TranslateSQL(s)
    82  }
    83  
    84  type Client struct {
    85  	ClientID string `db:"id"`
    86  }
    87  
    88  func (c Client) TableName() string {
    89  	return "clients"
    90  }
    91  
    92  type User struct {
    93  	ID           int           `db:"id"`
    94  	UserName     string        `db:"user_name"`
    95  	Email        string        `db:"email"`
    96  	Name         nulls.String  `db:"name"`
    97  	Alive        nulls.Bool    `db:"alive"`
    98  	CreatedAt    time.Time     `db:"created_at"`
    99  	UpdatedAt    time.Time     `db:"updated_at"`
   100  	BirthDate    nulls.Time    `db:"birth_date"`
   101  	Bio          nulls.String  `db:"bio"`
   102  	Price        nulls.Float64 `db:"price"`
   103  	FullName     nulls.String  `db:"full_name" select:"name as full_name"`
   104  	Books        Books         `has_many:"books" order_by:"title asc"`
   105  	FavoriteSong Song          `has_one:"song" fk_id:"u_id"`
   106  	Houses       Addresses     `many_to_many:"users_addresses"`
   107  }
   108  
   109  type UserPointerAssocs struct {
   110  	ID           int           `db:"id"`
   111  	UserName     string        `db:"user_name"`
   112  	Email        string        `db:"email"`
   113  	Name         nulls.String  `db:"name"`
   114  	Alive        nulls.Bool    `db:"alive"`
   115  	CreatedAt    time.Time     `db:"created_at"`
   116  	UpdatedAt    time.Time     `db:"updated_at"`
   117  	BirthDate    nulls.Time    `db:"birth_date"`
   118  	Bio          nulls.String  `db:"bio"`
   119  	Price        nulls.Float64 `db:"price"`
   120  	FullName     nulls.String  `db:"full_name" select:"name as full_name"`
   121  	Books        Books         `has_many:"books" order_by:"title asc" fk_id:"user_id"`
   122  	FavoriteSong *Song         `has_one:"song" fk_id:"u_id"`
   123  	Houses       Addresses     `many_to_many:"users_addresses"`
   124  }
   125  
   126  func (UserPointerAssocs) TableName() string {
   127  	return "users"
   128  }
   129  
   130  // Validate gets run every time you call a "Validate*" (ValidateAndSave, ValidateAndCreate, ValidateAndUpdate) method.
   131  // This method is not required and may be deleted.
   132  func (u *User) Validate(tx *Connection) (*validate.Errors, error) {
   133  	return validate.Validate(
   134  		&validators.StringIsPresent{Field: u.Name.String, Name: "Name"},
   135  	), nil
   136  }
   137  
   138  type Users []User
   139  
   140  type UserAttribute struct {
   141  	ID       int    `db:"id"`
   142  	UserName string `db:"user_name"`
   143  	NickName string `db:"nick_name"`
   144  
   145  	User User `json:"user" belongs_to:"user" fk_id:"UserName" primary_id:"UserName"`
   146  }
   147  
   148  type Book struct {
   149  	ID          int       `db:"id"`
   150  	Title       string    `db:"title"`
   151  	Isbn        string    `db:"isbn"`
   152  	UserID      nulls.Int `db:"user_id"`
   153  	User        User      `belongs_to:"user"`
   154  	Description string    `db:"description"`
   155  	Writers     Writers   `has_many:"writers"`
   156  	TaxiID      nulls.Int `db:"taxi_id"`
   157  	Taxi        Taxi      `belongs_to:"taxi"`
   158  	CreatedAt   time.Time `db:"created_at"`
   159  	UpdatedAt   time.Time `db:"updated_at"`
   160  }
   161  
   162  type Taxi struct {
   163  	ID          int       `db:"id"`
   164  	Model       string    `db:"model"`
   165  	UserID      nulls.Int `db:"user_id"`
   166  	AddressID   nulls.Int `db:"address_id"`
   167  	Driver      *User     `belongs_to:"user" fk_id:"user_id"`
   168  	Address     Address   `belongs_to:"address"`
   169  	ToAddressID *int      `db:"to_address_id"`
   170  	ToAddress   *Address  `belongs_to:"address"`
   171  	CreatedAt   time.Time `db:"created_at"`
   172  	UpdatedAt   time.Time `db:"updated_at"`
   173  }
   174  
   175  type Taxis []Taxi
   176  
   177  // Validate gets run every time you call a "Validate*" (ValidateAndSave, ValidateAndCreate, ValidateAndUpdate) method.
   178  // This method is not required and may be deleted.
   179  func (b *Book) Validate(tx *Connection) (*validate.Errors, error) {
   180  	// Execute another query to test if Validate causes eager creation to fail
   181  	if err := tx.All(&Taxis{}); err != nil {
   182  		return nil, err
   183  	}
   184  	return validate.Validate(
   185  		&validators.StringIsPresent{Field: b.Description, Name: "Description"},
   186  	), nil
   187  }
   188  
   189  type Books []Book
   190  
   191  type Writer struct {
   192  	ID        int       `db:"id"`
   193  	Name      string    `db:"name"`
   194  	Addresses Addresses `has_many:"addresses"`
   195  	Friends   []Friend  `has_many:"friends"`
   196  	BookID    int       `db:"book_id"`
   197  	Book      Book      `belongs_to:"book"`
   198  	CreatedAt time.Time `db:"created_at"`
   199  	UpdatedAt time.Time `db:"updated_at"`
   200  }
   201  
   202  type Writers []Writer
   203  
   204  type Address struct {
   205  	ID          int       `db:"id"`
   206  	Street      string    `db:"street"`
   207  	WriterID    int       `db:"writer_id"`
   208  	HouseNumber int       `db:"house_number"`
   209  	CreatedAt   time.Time `db:"created_at"`
   210  	UpdatedAt   time.Time `db:"updated_at"`
   211  	TaxisToHere Taxis     `has_many:"taxis" fk_id:"to_address_id" order_by:"created_at asc"`
   212  }
   213  
   214  type Addresses []Address
   215  
   216  type UsersAddress struct {
   217  	ID        int       `db:"id"`
   218  	UserID    int       `db:"user_id"`
   219  	AddressID int       `db:"address_id"`
   220  	CreatedAt time.Time `db:"created_at"`
   221  	UpdatedAt time.Time `db:"updated_at"`
   222  }
   223  
   224  type UsersAddressQuery struct {
   225  	ID        int       `db:"id"`
   226  	UserID    int       `db:"user_id"`
   227  	AddressID int       `db:"address_id"`
   228  	CreatedAt time.Time `db:"created_at"`
   229  	UpdatedAt time.Time `db:"updated_at"`
   230  
   231  	UserName  *string `db:"name" json:"user_name"`
   232  	UserEmail *string `db:"email" json:"user_email"`
   233  }
   234  
   235  func (UsersAddressQuery) TableName() string {
   236  	return "users_addresses"
   237  }
   238  
   239  type Friend struct {
   240  	ID        int       `db:"id"`
   241  	FirstName string    `db:"first_name"`
   242  	WriterID  int       `db:"writer_id"`
   243  	LastName  string    `db:"last_name"`
   244  	CreatedAt time.Time `db:"created_at"`
   245  	UpdatedAt time.Time `db:"updated_at"`
   246  }
   247  
   248  func (Friend) TableName() string {
   249  	return "good_friends"
   250  }
   251  
   252  type Family struct {
   253  	ID        int       `db:"id"`
   254  	FirstName string    `db:"first_name"`
   255  	LastName  string    `db:"last_name"`
   256  	CreatedAt time.Time `db:"created_at"`
   257  	UpdatedAt time.Time `db:"updated_at"`
   258  }
   259  
   260  func (Family) TableName() string {
   261  	// schema.table_name
   262  	return "family.members"
   263  }
   264  
   265  type Enemy struct {
   266  	A string
   267  }
   268  
   269  type Song struct {
   270  	ID           uuid.UUID `db:"id"`
   271  	Title        string    `db:"title"`
   272  	UserID       int       `db:"u_id"`
   273  	CreatedAt    time.Time `json:"created_at" db:"created_at"`
   274  	UpdatedAt    time.Time `json:"updated_at" db:"updated_at"`
   275  	ComposedByID int       `json:"composed_by_id" db:"composed_by_id"`
   276  	ComposedBy   Composer  `belongs_to:"composer"`
   277  }
   278  
   279  type Composer struct {
   280  	ID        int       `db:"id"`
   281  	Name      string    `db:"name"`
   282  	CreatedAt time.Time `db:"created_at"`
   283  	UpdatedAt time.Time `db:"updated_at"`
   284  }
   285  
   286  type Course struct {
   287  	ID        uuid.UUID `json:"id" db:"id"`
   288  	CreatedAt time.Time `json:"created_at" db:"created_at"`
   289  	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
   290  }
   291  
   292  type CourseCode struct {
   293  	ID        uuid.UUID `json:"id" db:"id"`
   294  	CreatedAt time.Time `json:"created_at" db:"created_at"`
   295  	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
   296  	CourseID  uuid.UUID `json:"course_id" db:"course_id"`
   297  	Course    Course    `json:"-" belongs_to:"course"`
   298  	// Course Course `belongs_to:"course"`
   299  }
   300  
   301  type NetClient struct {
   302  	ID   uuid.UUID `json:"id" db:"id"`
   303  	Hops []Hop     `json:"hop_id" has_many:"hops"`
   304  }
   305  
   306  type Hop struct {
   307  	ID          uuid.UUID     `json:"id" db:"id"`
   308  	NetClient   *NetClient    `json:"net_client" belongs_to:"net_client" fk_id:"NetClientID"`
   309  	NetClientID uuid.UUID     `json:"net_client_id" db:"net_client_id"`
   310  	Server      *Server       `json:"course" belongs_to:"server" fk_id:"ServerID" oder_by:"id asc"`
   311  	ServerID    uuid.NullUUID `json:"server_id" db:"server_id"`
   312  }
   313  
   314  type Server struct {
   315  	ID uuid.UUID `json:"id" db:"id"`
   316  }
   317  
   318  type ValidatableCar struct {
   319  	ID        int64     `db:"id"`
   320  	Name      string    `db:"name"`
   321  	CreatedAt time.Time `json:"created_at" db:"created_at"`
   322  	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
   323  }
   324  
   325  var validationLogs []string
   326  
   327  func (v *ValidatableCar) Validate(tx *Connection) (*validate.Errors, error) {
   328  	validationLogs = append(validationLogs, "Validate")
   329  	verrs := validate.Validate(&validators.StringIsPresent{Field: v.Name, Name: "Name"})
   330  	return verrs, nil
   331  }
   332  
   333  func (v *ValidatableCar) ValidateSave(tx *Connection) (*validate.Errors, error) {
   334  	validationLogs = append(validationLogs, "ValidateSave")
   335  	return nil, nil
   336  }
   337  
   338  func (v *ValidatableCar) ValidateUpdate(tx *Connection) (*validate.Errors, error) {
   339  	validationLogs = append(validationLogs, "ValidateUpdate")
   340  	return nil, nil
   341  }
   342  
   343  func (v *ValidatableCar) ValidateCreate(tx *Connection) (*validate.Errors, error) {
   344  	validationLogs = append(validationLogs, "ValidateCreate")
   345  	return nil, nil
   346  }
   347  
   348  type NotValidatableCar struct {
   349  	ID        int       `db:"id"`
   350  	Name      string    `db:"name"`
   351  	CreatedAt time.Time `json:"created_at" db:"created_at"`
   352  	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
   353  }
   354  
   355  type CallbacksUser struct {
   356  	ID        int       `db:"id"`
   357  	BeforeS   string    `db:"before_s"`
   358  	BeforeC   string    `db:"before_c"`
   359  	BeforeU   string    `db:"before_u"`
   360  	BeforeD   string    `db:"before_d"`
   361  	BeforeV   string    `db:"before_v"`
   362  	AfterS    string    `db:"after_s"`
   363  	AfterC    string    `db:"after_c"`
   364  	AfterU    string    `db:"after_u"`
   365  	AfterD    string    `db:"after_d"`
   366  	AfterF    string    `db:"after_f"`
   367  	AfterEF   string    `db:"after_ef"`
   368  	CreatedAt time.Time `json:"created_at" db:"created_at"`
   369  	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
   370  }
   371  
   372  type CallbacksUsers []CallbacksUser
   373  
   374  func (u *CallbacksUser) BeforeSave(tx *Connection) error {
   375  	u.BeforeS = "BeforeSave"
   376  	return nil
   377  }
   378  
   379  func (u *CallbacksUser) BeforeUpdate(tx *Connection) error {
   380  	u.BeforeU = "BeforeUpdate"
   381  	return nil
   382  }
   383  
   384  func (u *CallbacksUser) BeforeCreate(tx *Connection) error {
   385  	u.BeforeC = "BeforeCreate"
   386  	return nil
   387  }
   388  
   389  func (u *CallbacksUser) BeforeDestroy(tx *Connection) error {
   390  	u.BeforeD = "BeforeDestroy"
   391  	return nil
   392  }
   393  
   394  func (u *CallbacksUser) BeforeValidate(tx *Connection) error {
   395  	u.BeforeV = "BeforeValidate"
   396  	return nil
   397  }
   398  
   399  func (u *CallbacksUser) AfterSave(tx *Connection) error {
   400  	u.AfterS = "AfterSave"
   401  	return nil
   402  }
   403  
   404  func (u *CallbacksUser) AfterUpdate(tx *Connection) error {
   405  	u.AfterU = "AfterUpdate"
   406  	return nil
   407  }
   408  
   409  func (u *CallbacksUser) AfterCreate(tx *Connection) error {
   410  	u.AfterC = "AfterCreate"
   411  	return nil
   412  }
   413  
   414  func (u *CallbacksUser) AfterDestroy(tx *Connection) error {
   415  	u.AfterD = "AfterDestroy"
   416  	return nil
   417  }
   418  
   419  func (u *CallbacksUser) AfterFind(tx *Connection) error {
   420  	u.AfterF = "AfterFind"
   421  	return nil
   422  }
   423  
   424  func (u *CallbacksUser) AfterEagerFind(tx *Connection) error {
   425  	u.AfterEF = "AfterEagerFind"
   426  	return nil
   427  }
   428  
   429  type Label struct {
   430  	ID string `db:"id"`
   431  }
   432  
   433  type SingleID struct {
   434  	ID int `db:"id"`
   435  }
   436  
   437  type Body struct {
   438  	ID   int   `json:"id" db:"id"`
   439  	Head *Head `json:"head" has_one:"head"`
   440  }
   441  
   442  type Head struct {
   443  	ID     int   `json:"id,omitempty" db:"id"`
   444  	BodyID int   `json:"-" db:"body_id"`
   445  	Body   *Body `json:"body,omitempty" belongs_to:"body"`
   446  }
   447  
   448  type HeadPtr struct {
   449  	ID     int   `json:"id,omitempty" db:"id"`
   450  	BodyID *int  `json:"-" db:"body_id"`
   451  	Body   *Body `json:"body,omitempty" belongs_to:"body"`
   452  }
   453  
   454  type Student struct {
   455  	ID        uuid.UUID `json:"id" db:"id"`
   456  	CreatedAt time.Time `json:"created_at" db:"created_at"`
   457  	UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
   458  }
   459  
   460  // https://github.com/gobuffalo/pop/issues/302
   461  type Parent struct {
   462  	ID        uuid.UUID  `json:"id" db:"id"`
   463  	CreatedAt time.Time  `json:"created_at" db:"created_at"`
   464  	UpdatedAt time.Time  `json:"updated_at" db:"updated_at"`
   465  	Students  []*Student `many_to_many:"parents_students"`
   466  }
   467  
   468  type CrookedColour struct {
   469  	ID        int       `db:"pk"`
   470  	Name      string    `db:"name"`
   471  	CreatedAt time.Time `db:"created_at"`
   472  	UpdatedAt time.Time `db:"updated_at"`
   473  }
   474  
   475  type CrookedSong struct {
   476  	ID        string    `db:"name"`
   477  	CreatedAt time.Time `db:"created_at"`
   478  	UpdatedAt time.Time `db:"updated_at"`
   479  }
   480  
   481  type NonStandardID struct {
   482  	ID          int    `db:"pk"`
   483  	OutfacingID string `db:"id"`
   484  }
   485  
   486  type InnerStruct struct {
   487  	ID        int       `db:"id"`
   488  	CreatedAt time.Time `db:"created_at"`
   489  	UpdatedAt time.Time `db:"updated_at"`
   490  }
   491  
   492  type EmbeddingStruct struct {
   493  	InnerStruct
   494  	AdditionalField string `db:"additional_field"`
   495  }