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