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 TestSelectPlans(t *testing.T) { assert := assert.New(t) currentTime := time.Now() idToUse := 1 str, mock := getDbMock(t) rows := sqlmock.NewRows([]string{"plan_id", "plan_date"}).AddRow(idToUse, currentTime) mock.ExpectQuery("^SELECT plan_id, plan_date FROM plans$").WillReturnRows(rows) plans, err := str.SelectPlans() assert.Nil(err) assert.Equal(1, len(plans)) plan := plans[0] assert.EqualValues(idToUse, plan.PlanID) assert.Equal(currentTime, *plan.PlanDate) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestSelectPlanByID(t *testing.T) { assert := assert.New(t) currentTime := time.Now() idToUse := 1 str, mock := getDbMock(t) rows := sqlmock.NewRows([]string{"plan_id", "plan_date"}).AddRow(idToUse, currentTime) mock.ExpectQuery("^SELECT plan_id, plan_date FROM plans WHERE plan_id = \\$1$").WithArgs(idToUse).WillReturnRows(rows) plan, err := str.SelectPlanByID(idToUse) assert.Nil(err) assert.EqualValues(idToUse, plan.PlanID) assert.Equal(currentTime, *plan.PlanDate) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestInsertPlan(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) planDate, _ := time.Parse("2006-01-02", "2021-01-01") plan := &models.Plan{PlanDate: &planDate} idToUse := 8 rows := sqlmock.NewRows([]string{"plan_id"}).AddRow(8) mock.ExpectBegin() mock.ExpectQuery("^INSERT INTO plans \\(plan_date\\) VALUES \\(\\$1\\) RETURNING plan_id$"). WithArgs(planDate). WillReturnRows(rows) mock.ExpectCommit() // function under test insertedId, err := str.InsertPlan(plan) // check results assert.Nil(err) assert.EqualValues(idToUse, insertedId) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestInsertPlanErr(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) planDate, _ := time.Parse("2006-01-02", "2021-01-01") plan := &models.Plan{PlanDate: &planDate} mock.ExpectBegin() mock.ExpectQuery("^INSERT INTO plans \\(plan_date\\) VALUES \\(\\$1\\) RETURNING plan_id$"). WithArgs(planDate). WillReturnError(fmt.Errorf("example error")) mock.ExpectRollback() // function under test _, err := str.InsertPlan(plan) // check results assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestInsertPlanCommitErr(t *testing.T) { // setup assert := assert.New(t) str, mock := getDbMock(t) planDate, _ := time.Parse("2006-01-02", "2021-01-01") plan := &models.Plan{PlanDate: &planDate} idToUse := 8 rows := sqlmock.NewRows([]string{"plan_id"}).AddRow(idToUse) mock.ExpectBegin() mock.ExpectQuery("^INSERT INTO plans \\(plan_date\\) VALUES \\(\\$1\\) RETURNING plan_id$"). WithArgs(planDate). WillReturnRows(rows) mock.ExpectCommit().WillReturnError(fmt.Errorf("another error example")) // function under test _, err := str.InsertPlan(plan) // check results assert.NotNil(err) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } func TestErrPlanByID(t *testing.T) { assert := assert.New(t) idToUse := 1 str, mock := getDbMock(t) mock.ExpectQuery("^SELECT plan_id, plan_date FROM plans WHERE plan_id = \\$1$").WithArgs(idToUse).WillReturnError(fmt.Errorf("example error")) plan, err := str.SelectPlanByID(idToUse) assert.NotNil(err) assert.Nil(plan) if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("unfulfilled expectations: %s", err) } } 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 TestErrPlans(t *testing.T) { // set up tests assert := assert.New(t) str, mock := getDbMock(t) mock.ExpectQuery("^SELECT plan_id, plan_date FROM plans$").WillReturnError(fmt.Errorf("example error")) // function under test plans, err := str.SelectPlans() // test results assert.Nil(plans) assert.NotNil(err) 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) } }