package store_test import ( "fmt" "gitea.deepak.science/deepak/gogmagog/models" "gitea.deepak.science/deepak/gogmagog/store" "github.com/DATA-DOG/go-sqlmock" "github.com/jmoiron/sqlx" "github.com/stretchr/testify/assert" "testing" "time" ) func getDbMock(t *testing.T) (models.Store, sqlmock.Sqlmock) { db, mock, err := sqlmock.New(sqlmock.MonitorPingsOption(true)) if err != nil { t.Fatalf("got an error creating a stub db. How?: %s", err) } str, err := store.GetPostgresStore(sqlx.NewDb(db, "pgx")) if err != nil { t.Errorf("Error creating postgres store: %s", err) } return str, mock } func TestSelectActions(t *testing.T) { // set up test assert := assert.New(t) createTime, _ := time.Parse("2006-01-02", "2020-12-31") updateTime, _ := time.Parse("2006-01-02", "2021-01-01") completeTime, _ := time.Parse("2006-01-02", "2021-01-05") idToUse := 1 estChunks := 5 compChunks := 7 desc := "Howdy, partner." str, mock := getDbMock(t) rows := sqlmock.NewRows([]string{ "action_id", "action_description", "estimated_chunks", "completed_chunks", "completed_on", "created_at", "updated_at", "plan_id"}). AddRow(idToUse, desc, estChunks, compChunks, completeTime, createTime, updateTime, idToUse). AddRow(idToUse+1, desc, estChunks, compChunks, completeTime, createTime, updateTime, idToUse) mock.ExpectQuery("^SELECT action_id, action_description, estimated_chunks, completed_chunks, completed_on, created_at, updated_at, plan_id FROM actions$").WillReturnRows(rows) // function under test actions, err := str.SelectActions() // test results assert.Nil(err) assert.Equal(2, len(actions)) action := actions[0] assert.EqualValues(idToUse, action.ActionID) assert.Equal(desc, action.ActionDescription) assert.Equal(estChunks, action.EstimatedChunks) assert.Equal(compChunks, action.CompletedChunks) assert.Equal(completeTime, *action.CompletedOn) assert.Equal(createTime, *action.CreatedAt) assert.Equal(updateTime, *action.UpdatedAt) assert.Equal(idToUse, action.PlanID) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestSelectActionsByPlanID(t *testing.T) { // set up test assert := assert.New(t) createTime, _ := time.Parse("2006-01-02", "2020-12-31") updateTime, _ := time.Parse("2006-01-02", "2021-01-01") completeTime, _ := time.Parse("2006-01-02", "2021-01-05") idToUse := 1 estChunks := 5 compChunks := 7 desc := "Howdy, partner." str, mock := getDbMock(t) rows := sqlmock.NewRows([]string{ "action_id", "action_description", "estimated_chunks", "completed_chunks", "completed_on", "created_at", "updated_at", "plan_id"}). AddRow(idToUse, desc, estChunks, compChunks, completeTime, createTime, updateTime, idToUse). AddRow(idToUse+1, desc, estChunks, compChunks, completeTime, createTime, updateTime, idToUse) mock.ExpectQuery("^SELECT action_id, action_description, estimated_chunks, completed_chunks, completed_on, created_at, updated_at, plan_id FROM actions WHERE plan_id = \\$1$"). WithArgs(idToUse). WillReturnRows(rows) // function under test actions, err := str.SelectActionsByPlanID(&models.Plan{PlanID: int64(idToUse)}) // test results assert.Nil(err) assert.Equal(2, len(actions)) action := actions[0] assert.EqualValues(idToUse, action.ActionID) assert.Equal(desc, action.ActionDescription) assert.Equal(estChunks, action.EstimatedChunks) assert.Equal(compChunks, action.CompletedChunks) assert.Equal(completeTime, *action.CompletedOn) assert.Equal(createTime, *action.CreatedAt) assert.Equal(updateTime, *action.UpdatedAt) assert.Equal(idToUse, action.PlanID) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestSelectActionsByPlanIDErr(t *testing.T) { // set up test assert := assert.New(t) idToUse := 1 str, mock := getDbMock(t) mock.ExpectQuery("^SELECT action_id, action_description, estimated_chunks, completed_chunks, completed_on, created_at, updated_at, plan_id FROM actions WHERE plan_id = \\$1$"). WithArgs(idToUse). WillReturnError(fmt.Errorf("example error")) // function under test actions, err := str.SelectActionsByPlanID(&models.Plan{PlanID: int64(idToUse)}) // test results assert.NotNil(err) assert.Nil(actions) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestSelectActionById(t *testing.T) { // set up test assert := assert.New(t) createTime, _ := time.Parse("2006-01-02", "2020-12-31") updateTime, _ := time.Parse("2006-01-02", "2021-01-01") completeTime, _ := time.Parse("2006-01-02", "2021-01-05") idToUse := 1 estChunks := 5 compChunks := 7 desc := "Howdy, partner." str, mock := getDbMock(t) rows := sqlmock.NewRows([]string{ "action_id", "action_description", "estimated_chunks", "completed_chunks", "completed_on", "created_at", "updated_at", "plan_id"}). AddRow(idToUse, desc, estChunks, compChunks, completeTime, createTime, updateTime, idToUse) mock.ExpectQuery("^SELECT action_id, action_description, estimated_chunks, completed_chunks, completed_on, created_at, updated_at, plan_id FROM actions WHERE action_id = \\$1"). WithArgs(1). WillReturnRows(rows) // function under test action, err := str.SelectActionByID(1) // test results assert.Nil(err) assert.EqualValues(idToUse, action.ActionID) assert.Equal(desc, action.ActionDescription) assert.Equal(estChunks, action.EstimatedChunks) assert.Equal(compChunks, action.CompletedChunks) assert.Equal(completeTime, *action.CompletedOn) assert.Equal(createTime, *action.CreatedAt) assert.Equal(updateTime, *action.UpdatedAt) assert.Equal(idToUse, action.PlanID) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestErrActions(t *testing.T) { // set up tests assert := assert.New(t) str, mock := getDbMock(t) mock.ExpectQuery("^SELECT action_id, action_description, estimated_chunks, completed_chunks, completed_on, created_at, updated_at, plan_id FROM actions$").WillReturnError(fmt.Errorf("example error")) // function under test actions, err := str.SelectActions() // test results assert.Nil(actions) assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestErrActionByID(t *testing.T) { // set up tests assert := assert.New(t) str, mock := getDbMock(t) mock.ExpectQuery("^SELECT action_id, action_description, estimated_chunks, completed_chunks, completed_on, created_at, updated_at, plan_id FROM actions WHERE action_id = \\$1").WillReturnError(fmt.Errorf("example error")) // function under test action, err := str.SelectActionByID(1) // test results assert.Nil(action) assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestConnectionLive(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) mock.ExpectPing() // perform func under tests err := str.ConnectionLive() // results assert.Nil(err) } func TestInsertAction(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) completedOn, _ := time.Parse("2006-01-02", "2021-01-01") action := &models.Action{ CompletedOn: &completedOn, EstimatedChunks: 3, CompletedChunks: 6, PlanID: 5, ActionDescription: "testing", } idToUse := 8 rows := sqlmock.NewRows([]string{"action_id"}).AddRow(8) mock.ExpectBegin() mock.ExpectQuery("^INSERT INTO actions \\(action_description, estimated_chunks, completed_chunks, completed_on, plan_id\\) VALUES \\(\\$1, \\$2, \\$3, \\$4, \\$5\\) RETURNING action_id$"). WithArgs("testing", 3, 6, completedOn, 5). WillReturnRows(rows) mock.ExpectCommit() // function under test insertedId, err := str.InsertAction(action) // check results assert.Nil(err) assert.EqualValues(idToUse, insertedId) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestInsertActionErr(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) completedOn, _ := time.Parse("2006-01-02", "2021-01-01") action := &models.Action{ CompletedOn: &completedOn, EstimatedChunks: 3, CompletedChunks: 6, PlanID: 5, ActionDescription: "testing", } mock.ExpectBegin() mock.ExpectQuery("^INSERT INTO actions \\(action_description, estimated_chunks, completed_chunks, completed_on, plan_id\\) VALUES \\(\\$1, \\$2, \\$3, \\$4, \\$5\\) RETURNING action_id$"). WithArgs("testing", 3, 6, completedOn, 5). WillReturnError(fmt.Errorf("example error")) mock.ExpectRollback() // function under test _, err := str.InsertAction(action) // check results assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestInsertActionCommitErr(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) completedOn, _ := time.Parse("2006-01-02", "2021-01-01") action := &models.Action{ CompletedOn: &completedOn, EstimatedChunks: 3, CompletedChunks: 6, PlanID: 5, ActionDescription: "testing", } idToUse := 8 rows := sqlmock.NewRows([]string{"plan_id"}).AddRow(idToUse) mock.ExpectBegin() mock.ExpectQuery("^INSERT INTO actions \\(action_description, estimated_chunks, completed_chunks, completed_on, plan_id\\) VALUES \\(\\$1, \\$2, \\$3, \\$4, \\$5\\) RETURNING action_id$"). WithArgs("testing", 3, 6, completedOn, 5). WillReturnRows(rows) mock.ExpectCommit().WillReturnError(fmt.Errorf("another error example")) // function under test _, err := str.InsertAction(action) // check results assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestUpdateAction(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) completedOn, _ := time.Parse("2006-01-02", "2021-01-01") action := &models.Action{ CompletedOn: &completedOn, EstimatedChunks: 3, CompletedChunks: 6, PlanID: 5, ActionDescription: "testing", ActionID: 2, } mock.ExpectBegin() mock.ExpectExec(` UPDATE actions SET action_description = \$1, estimated_chunks = \$2, completed_chunks = \$3, completed_on = \$4, plan_id = \$5 WHERE action_id = \$6`). WithArgs("testing", 3, 6, completedOn, 5, 2). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() // function under test err := str.UpdateAction(action) // check results assert.Nil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestUpdateActionErr(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) completedOn, _ := time.Parse("2006-01-02", "2021-01-01") action := &models.Action{ CompletedOn: &completedOn, EstimatedChunks: 3, CompletedChunks: 6, PlanID: 5, ActionDescription: "testing", ActionID: 2, } mock.ExpectBegin() mock.ExpectExec("UPDATE actions"). WithArgs("testing", 3, 6, completedOn, 5, 2). WillReturnError(fmt.Errorf("example error")) mock.ExpectRollback() // function under test err := str.UpdateAction(action) // check results assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestUpdateActionCommitErr(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) completedOn, _ := time.Parse("2006-01-02", "2021-01-01") action := &models.Action{ CompletedOn: &completedOn, EstimatedChunks: 3, CompletedChunks: 6, PlanID: 5, ActionDescription: "testing", ActionID: 2, } mock.ExpectBegin() mock.ExpectExec("UPDATE actions"). WithArgs("testing", 3, 6, completedOn, 5, 2). WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit().WillReturnError(fmt.Errorf("another error example")) // function under test err := str.UpdateAction(action) // check results assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } }