github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/bulk/gorm-bulk/bulk_insert_test.go (about)

     1  package gormbulk
     2  
     3  import (
     4  	"database/sql"
     5  	"sort"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/DATA-DOG/go-sqlmock"
    10  	"github.com/jinzhu/gorm"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  type fakeRelationTable struct{}
    16  
    17  type fakeTable struct {
    18  	ID        int `gorm:"primary_key;auto_increment"`
    19  	Name      string
    20  	Email     string              `gorm:"default:default@mail.com"`
    21  	Relation  *fakeRelationTable  `gorm:"foreignkey:RelationID"`
    22  	Relations []fakeRelationTable `gorm:"foreignkey:UserRefer"`
    23  	Message   sql.NullString
    24  	Publish   bool
    25  	CreatedAt time.Time
    26  	UpdatedAt time.Time
    27  }
    28  
    29  func Test_extractMapValue(t *testing.T) {
    30  	collectKeys := func(val map[string]interface{}) []string {
    31  		keys := make([]string, 0, len(val))
    32  		for key := range val {
    33  			keys = append(keys, key)
    34  		}
    35  		sort.Strings(keys)
    36  		return keys
    37  	}
    38  
    39  	notNow := time.Now().Add(-3600 * time.Second)
    40  
    41  	value := fakeTable{
    42  		Name:      "name1",
    43  		Email:     "test1@test.com",
    44  		Relation:  &fakeRelationTable{},
    45  		Message:   sql.NullString{String: "message1", Valid: true},
    46  		CreatedAt: notNow,
    47  		Publish:   false,
    48  	}
    49  
    50  	// test without excluding columns
    51  	fullKeys := []string{"name", "email", "message", "publish", "created_at", "updated_at"}
    52  	sort.Strings(fullKeys)
    53  
    54  	mapVal, err := extractMapValue(value, []string{})
    55  	assert.NoError(t, err)
    56  
    57  	// Ensure we kept the CreatedAt time
    58  	createdAt, ok := mapVal["created_at"].(time.Time)
    59  	require.True(t, ok)
    60  	assert.True(t, createdAt.Before(time.Now().Add(-100*time.Second)))
    61  
    62  	// Ensure we set default UpdatedAt time
    63  	updatedAt, ok := mapVal["updated_at"].(time.Time)
    64  	require.True(t, ok)
    65  	assert.True(t, updatedAt.After(time.Now().Add(-1*time.Second)))
    66  
    67  	mapKeys := collectKeys(mapVal)
    68  	assert.Equal(t, fullKeys, mapKeys)
    69  
    70  	// test with excluding columns
    71  	excludedVal, err := extractMapValue(value, []string{"Email", "CreatedAt"})
    72  	assert.NoError(t, err)
    73  
    74  	excludedKeys := collectKeys(excludedVal)
    75  	assert.NotContains(t, excludedKeys, "email")
    76  	assert.NotContains(t, excludedKeys, "created_at")
    77  }
    78  
    79  func Test_insertObject(t *testing.T) {
    80  	type Table struct {
    81  		RegularColumn string
    82  		Custom        string `gorm:"column:ThisIsCamelCase"`
    83  	}
    84  
    85  	db, mock, err := sqlmock.New()
    86  	require.NoError(t, err)
    87  
    88  	defer db.Close()
    89  
    90  	gdb, err := gorm.Open("mysql", db)
    91  	require.NoError(t, err)
    92  
    93  	mock.ExpectExec(
    94  		"INSERT INTO `tables` \\(`ThisIsCamelCase`, `regular_column`\\)",
    95  	).WithArgs(
    96  		"first custom", "first regular",
    97  		"second custom", "second regular",
    98  	).WillReturnResult(
    99  		sqlmock.NewResult(1, 1),
   100  	)
   101  
   102  	err = insertObjSet(gdb, []interface{}{
   103  		Table{
   104  			RegularColumn: "first regular",
   105  			Custom:        "first custom",
   106  		},
   107  		Table{
   108  			RegularColumn: "second regular",
   109  			Custom:        "second custom",
   110  		},
   111  	})
   112  
   113  	require.NoError(t, err)
   114  }
   115  
   116  func Test_fieldIsAutoIncrement(t *testing.T) {
   117  	type explicitSetTable struct {
   118  		ID int `gorm:"column:id;auto_increment"`
   119  	}
   120  	type notSpecifiedTable struct {
   121  		ID int `gorm:"column:id"`
   122  	}
   123  	type primaryKeyTable struct {
   124  		ID int `gorm:"column:id;primary_key"`
   125  	}
   126  	type autoIncrementTable struct {
   127  		ID int `gorm:"column:id;primary_key;auto_increment:false"`
   128  	}
   129  
   130  	cases := []struct {
   131  		Value    interface{}
   132  		Expected bool
   133  	}{
   134  		{explicitSetTable{}, true},
   135  		{notSpecifiedTable{}, false},
   136  		{primaryKeyTable{}, false},
   137  		{autoIncrementTable{}, false},
   138  	}
   139  	for _, c := range cases {
   140  		for _, field := range (&gorm.Scope{Value: c.Value}).Fields() {
   141  			assert.Equal(t, fieldIsAutoIncrement(field), c.Expected)
   142  		}
   143  	}
   144  }
   145  
   146  func Test_fieldIsPrimaryAndBlank(t *testing.T) {
   147  	type notPrimaryTable struct {
   148  		Dummy int
   149  	}
   150  	type primaryKeyTable struct {
   151  		ID int `gorm:"column:id;primary_key"`
   152  	}
   153  
   154  	cases := []struct {
   155  		Value    interface{}
   156  		Expected bool
   157  	}{
   158  		{notPrimaryTable{Dummy: 0}, false},
   159  		{notPrimaryTable{Dummy: 1}, false},
   160  		{primaryKeyTable{ID: 0}, true},
   161  		{primaryKeyTable{ID: 1}, false},
   162  	}
   163  	for _, c := range cases {
   164  		for _, field := range (&gorm.Scope{Value: c.Value}).Fields() {
   165  			assert.Equal(t, fieldIsPrimaryAndBlank(field), c.Expected)
   166  		}
   167  	}
   168  }