You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
boundary/internal/oplog/writer_test.go

325 lines
8.4 KiB

package oplog
import (
"testing"
dbassert "github.com/hashicorp/dbassert/gorm"
"github.com/hashicorp/watchtower/internal/oplog/oplog_test"
"github.com/jinzhu/gorm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// Test_GormWriterCreate provides unit tests for GormWriter Create
func Test_GormWriterCreate(t *testing.T) {
cleanup, db := setup(t)
defer testCleanup(t, cleanup, db)
t.Run("valid", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
tx := db.Begin()
defer tx.Rollback()
w := GormWriter{tx}
user := oplog_test.TestUser{
Name: "foo-" + testId(t),
}
require.NoError(w.Create(&user))
foundUser := testFindUser(t, tx, user.Id)
assert.Equal(user.Name, foundUser.Name)
})
t.Run("nil tx", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := GormWriter{nil}
err := w.Create(&oplog_test.TestUser{})
require.Error(err)
assert.Equal(err.Error(), "create Tx is nil")
})
t.Run("nil model", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
tx := db.Begin()
defer tx.Rollback()
w := GormWriter{tx}
err := w.Create(nil)
require.Error(err)
assert.Equal(err.Error(), "create interface is nil")
})
}
// Test_GormWriterDelete provides unit tests for GormWriter Delete
func Test_GormWriterDelete(t *testing.T) {
cleanup, db := setup(t)
defer testCleanup(t, cleanup, db)
t.Run("valid", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
tx := db.Begin()
defer tx.Rollback()
w := GormWriter{tx}
id := testId(t)
user := testUser(t, db, "foo-"+id, "", "")
foundUser := testFindUser(t, db, user.Id)
require.NoError(w.Delete(&user))
err := tx.Where("id = ?", user.Id).First(&foundUser).Error
require.Error(err)
assert.Equal(err, gorm.ErrRecordNotFound)
})
t.Run("nil tx", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := GormWriter{nil}
err := w.Delete(&oplog_test.TestUser{})
require.Error(err)
assert.Equal(err.Error(), "delete Tx is nil")
})
t.Run("nil model", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
tx := db.Begin()
defer tx.Rollback()
w := GormWriter{tx}
err := w.Delete(nil)
require.Error(err)
assert.Equal(err.Error(), "delete interface is nil")
})
}
// Test_GormWriterHasTable provides unit tests for GormWriter HasTable
func Test_GormWriterHasTable(t *testing.T) {
cleanup, db := setup(t)
defer testCleanup(t, cleanup, db)
w := GormWriter{Tx: db}
t.Run("success", func(t *testing.T) {
assert := require.New(t)
ok := w.hasTable("oplog_test_user")
assert.Equal(ok, true)
})
t.Run("no table", func(t *testing.T) {
assert := assert.New(t)
badTableName := testId(t)
ok := w.hasTable(badTableName)
assert.Equal(ok, false)
})
t.Run("blank table name", func(t *testing.T) {
assert := assert.New(t)
ok := w.hasTable("")
assert.Equal(ok, false)
})
}
// Test_GormWriterCreateTable provides unit tests for GormWriter CreateTable
func Test_GormWriterCreateTable(t *testing.T) {
cleanup, db := setup(t)
defer testCleanup(t, cleanup, db)
t.Run("success", func(t *testing.T) {
assert := assert.New(t)
w := GormWriter{Tx: db}
suffix := testId(t)
u := &oplog_test.TestUser{}
newTableName := u.TableName() + "_" + suffix
defer func() { assert.NoError(w.dropTableIfExists(newTableName)) }()
err := w.createTableLike(u.TableName(), newTableName)
assert.NoError(err)
})
t.Run("call twice", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := GormWriter{Tx: db}
suffix := testId(t)
u := &oplog_test.TestUser{}
newTableName := u.TableName() + "_" + suffix
defer func() { assert.NoError(w.dropTableIfExists(newTableName)) }()
err := w.createTableLike(u.TableName(), newTableName)
require.NoError(err)
// should be an error to create the same table twice
err = w.createTableLike(u.TableName(), newTableName)
require.Error(err)
assert.Error(err, err.Error(), nil)
})
t.Run("empty existing", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := GormWriter{Tx: db}
suffix := testId(t)
u := &oplog_test.TestUser{}
newTableName := u.TableName() + "_" + suffix
defer func() { assert.NoError(w.dropTableIfExists(newTableName)) }()
err := w.createTableLike("", newTableName)
require.Error(err)
assert.Error(err, err.Error(), nil)
assert.Equal(err.Error(), "error existingTableName is empty string")
})
t.Run("blank name", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := GormWriter{Tx: db}
u := &oplog_test.TestUser{}
err := w.createTableLike(u.TableName(), "")
require.Error(err)
assert.Error(err, err.Error(), nil)
assert.Equal(err.Error(), "error newTableName is empty string")
})
}
// Test_GormWriterDropTableIfExists provides unit tests for GormWriter DropTableIfExists
func Test_GormWriterDropTableIfExists(t *testing.T) {
cleanup, db := setup(t)
defer testCleanup(t, cleanup, db)
t.Run("success", func(t *testing.T) {
assert := assert.New(t)
w := GormWriter{Tx: db}
suffix := testId(t)
u := &oplog_test.TestUser{}
newTableName := u.TableName() + "_" + suffix
assert.NoError(w.createTableLike(u.TableName(), newTableName))
defer func() { assert.NoError(w.dropTableIfExists(newTableName)) }()
})
t.Run("success with blank", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
w := GormWriter{Tx: db}
err := w.dropTableIfExists("")
require.Error(err)
assert.Equal(err.Error(), "cannot drop table whose name is an empty string")
})
}
func TestGormWriter_Update(t *testing.T) {
cleanup, db := setup(t)
defer testCleanup(t, cleanup, db)
id := testId(t)
type fields struct {
Tx *gorm.DB
}
type args struct {
user *oplog_test.TestUser
fieldMaskPaths []string
setToNullPaths []string
}
tests := []struct {
name string
Tx *gorm.DB
args args
wantUser *oplog_test.TestUser
wantErr bool
}{
{
name: "valid-fieldmask",
Tx: db,
args: args{
user: &oplog_test.TestUser{
Name: "valid-fieldmask",
},
fieldMaskPaths: []string{"name"},
},
wantUser: &oplog_test.TestUser{
Name: "valid-fieldmask",
Email: id,
PhoneNumber: id,
},
wantErr: false,
},
{
name: "valid-setToNull",
Tx: db,
args: args{
user: &oplog_test.TestUser{
Name: "valid-setToNull",
},
fieldMaskPaths: nil,
setToNullPaths: []string{"name"},
},
wantUser: &oplog_test.TestUser{
Name: "",
Email: id,
PhoneNumber: id,
},
wantErr: false,
},
{
name: "valid-setToNull-and-fieldMask",
Tx: db,
args: args{
user: &oplog_test.TestUser{
Email: "valid-setToNull-and-fieldMask",
},
fieldMaskPaths: []string{"email"},
setToNullPaths: []string{"name"},
},
wantUser: &oplog_test.TestUser{
Name: "",
Email: "valid-setToNull-and-fieldMask",
PhoneNumber: id,
},
wantErr: false,
},
{
name: "no-field-mask",
Tx: db,
args: args{
user: &oplog_test.TestUser{
Name: "no-field-mask",
},
fieldMaskPaths: []string{""},
},
wantErr: true,
},
{
name: "nil-field-mask",
Tx: db,
args: args{
user: &oplog_test.TestUser{
Name: "nil-field-mask",
},
fieldMaskPaths: nil,
},
wantErr: true,
},
{
name: "nil-tx",
Tx: nil,
args: args{
user: &oplog_test.TestUser{
Name: "nil-txt",
},
fieldMaskPaths: []string{"name"},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require, dbassert := assert.New(t), require.New(t), dbassert.New(t, db.DB(), "postgres")
w := &GormWriter{
Tx: tt.Tx,
}
u := testUser(t, db, id, id, id) // intentionally, not relying on tt.Tx
u.Name = tt.args.user.Name
u.Email = tt.args.user.Email
u.PhoneNumber = tt.args.user.PhoneNumber
err := w.Update(tt.args.user, tt.args.fieldMaskPaths, tt.args.setToNullPaths)
if tt.wantErr {
require.Error(err)
return
}
require.NoError(err)
var foundUser oplog_test.TestUser
err = db.Where("id = ?", u.Id).First(&foundUser).Error
require.NoError(err)
tt.wantUser.Id = u.Id
assert.Equal(tt.wantUser, &foundUser)
for _, f := range tt.args.setToNullPaths {
dbassert.IsNull(u, f)
}
})
}
t.Run("nil model", func(t *testing.T) {
assert := assert.New(t)
w := GormWriter{db}
err := w.Create(nil)
assert.Error(err)
})
}