package sql_test import ( "context" "database/sql" "regexp" repo "tercul/internal/data/sql" "tercul/internal/domain" "tercul/internal/platform/config" "testing" "time" "github.com/DATA-DOG/go-sqlmock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewContributionRepository(t *testing.T) { db, _, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) assert.NotNil(t, repo) } func TestContributionRepository_ListByUserID(t *testing.T) { t.Run("should return contributions for a given user id", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) userID := uint(1) expectedContributions := []domain.Contribution{ {BaseModel: domain.BaseModel{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, {BaseModel: domain.BaseModel{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, } rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}). AddRow(expectedContributions[0].ID, expectedContributions[0].CreatedAt, expectedContributions[0].UpdatedAt). AddRow(expectedContributions[1].ID, expectedContributions[1].CreatedAt, expectedContributions[1].UpdatedAt) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE user_id = $1`)). WithArgs(userID). WillReturnRows(rows) contributions, err := repo.ListByUserID(context.Background(), userID) require.NoError(t, err) assert.Equal(t, expectedContributions, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) t.Run("should return error if query fails", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) userID := uint(1) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE user_id = $1`)). WithArgs(userID). WillReturnError(sql.ErrNoRows) contributions, err := repo.ListByUserID(context.Background(), userID) require.Error(t, err) assert.Nil(t, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) } func TestContributionRepository_ListByReviewerID(t *testing.T) { t.Run("should return contributions for a given reviewer id", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) reviewerID := uint(1) expectedContributions := []domain.Contribution{ {BaseModel: domain.BaseModel{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, {BaseModel: domain.BaseModel{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, } rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}). AddRow(expectedContributions[0].ID, expectedContributions[0].CreatedAt, expectedContributions[0].UpdatedAt). AddRow(expectedContributions[1].ID, expectedContributions[1].CreatedAt, expectedContributions[1].UpdatedAt) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE reviewer_id = $1`)). WithArgs(reviewerID). WillReturnRows(rows) contributions, err := repo.ListByReviewerID(context.Background(), reviewerID) require.NoError(t, err) assert.Equal(t, expectedContributions, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) t.Run("should return error if query fails", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) reviewerID := uint(1) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE reviewer_id = $1`)). WithArgs(reviewerID). WillReturnError(sql.ErrNoRows) contributions, err := repo.ListByReviewerID(context.Background(), reviewerID) require.Error(t, err) assert.Nil(t, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) } func TestContributionRepository_ListByWorkID(t *testing.T) { t.Run("should return contributions for a given work id", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) workID := uint(1) expectedContributions := []domain.Contribution{ {BaseModel: domain.BaseModel{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, {BaseModel: domain.BaseModel{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, } rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}). AddRow(expectedContributions[0].ID, expectedContributions[0].CreatedAt, expectedContributions[0].UpdatedAt). AddRow(expectedContributions[1].ID, expectedContributions[1].CreatedAt, expectedContributions[1].UpdatedAt) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE work_id = $1`)). WithArgs(workID). WillReturnRows(rows) contributions, err := repo.ListByWorkID(context.Background(), workID) require.NoError(t, err) assert.Equal(t, expectedContributions, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) t.Run("should return error if query fails", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) workID := uint(1) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE work_id = $1`)). WithArgs(workID). WillReturnError(sql.ErrNoRows) contributions, err := repo.ListByWorkID(context.Background(), workID) require.Error(t, err) assert.Nil(t, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) } func TestContributionRepository_ListByTranslationID(t *testing.T) { t.Run("should return contributions for a given translation id", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) translationID := uint(1) expectedContributions := []domain.Contribution{ {BaseModel: domain.BaseModel{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, {BaseModel: domain.BaseModel{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, } rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}). AddRow(expectedContributions[0].ID, expectedContributions[0].CreatedAt, expectedContributions[0].UpdatedAt). AddRow(expectedContributions[1].ID, expectedContributions[1].CreatedAt, expectedContributions[1].UpdatedAt) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE translation_id = $1`)). WithArgs(translationID). WillReturnRows(rows) contributions, err := repo.ListByTranslationID(context.Background(), translationID) require.NoError(t, err) assert.Equal(t, expectedContributions, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) t.Run("should return error if query fails", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) translationID := uint(1) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE translation_id = $1`)). WithArgs(translationID). WillReturnError(sql.ErrNoRows) contributions, err := repo.ListByTranslationID(context.Background(), translationID) require.Error(t, err) assert.Nil(t, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) } func TestContributionRepository_ListByStatus(t *testing.T) { t.Run("should return contributions for a given status", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) status := "draft" expectedContributions := []domain.Contribution{ {BaseModel: domain.BaseModel{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, {BaseModel: domain.BaseModel{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}}, } rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at"}). AddRow(expectedContributions[0].ID, expectedContributions[0].CreatedAt, expectedContributions[0].UpdatedAt). AddRow(expectedContributions[1].ID, expectedContributions[1].CreatedAt, expectedContributions[1].UpdatedAt) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE status = $1`)). WithArgs(status). WillReturnRows(rows) contributions, err := repo.ListByStatus(context.Background(), status) require.NoError(t, err) assert.Equal(t, expectedContributions, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) t.Run("should return error if query fails", func(t *testing.T) { db, mock, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewContributionRepository(db, cfg) status := "draft" mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "contributions" WHERE status = $1`)). WithArgs(status). WillReturnError(sql.ErrNoRows) contributions, err := repo.ListByStatus(context.Background(), status) require.Error(t, err) assert.Nil(t, contributions) assert.NoError(t, mock.ExpectationsWereMet()) }) }