package sql_test import ( "context" "database/sql" "regexp" "testing" repo "tercul/internal/data/sql" "tercul/internal/domain" "tercul/internal/platform/config" "time" "github.com/DATA-DOG/go-sqlmock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestNewBookmarkRepository(t *testing.T) { db, _, err := newMockDb() require.NoError(t, err) cfg, err := config.LoadConfig() require.NoError(t, err) repo := repo.NewBookmarkRepository(db, cfg) assert.NotNil(t, repo) } func TestBookmarkRepository_ListByUserID(t *testing.T) { t.Run("should return bookmarks 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.NewBookmarkRepository(db, cfg) userID := uint(1) expectedBookmarks := []domain.Bookmark{ {BaseModel: domain.BaseModel{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, UserID: userID, WorkID: 1}, {BaseModel: domain.BaseModel{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, UserID: userID, WorkID: 2}, } rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at", "user_id", "work_id"}). AddRow(expectedBookmarks[0].ID, expectedBookmarks[0].CreatedAt, expectedBookmarks[0].UpdatedAt, expectedBookmarks[0].UserID, expectedBookmarks[0].WorkID). AddRow(expectedBookmarks[1].ID, expectedBookmarks[1].CreatedAt, expectedBookmarks[1].UpdatedAt, expectedBookmarks[1].UserID, expectedBookmarks[1].WorkID) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "bookmarks" WHERE user_id = $1`)). WithArgs(userID). WillReturnRows(rows) bookmarks, err := repo.ListByUserID(context.Background(), userID) require.NoError(t, err) assert.Equal(t, expectedBookmarks, bookmarks) 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.NewBookmarkRepository(db, cfg) userID := uint(1) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "bookmarks" WHERE user_id = $1`)). WithArgs(userID). WillReturnError(sql.ErrNoRows) bookmarks, err := repo.ListByUserID(context.Background(), userID) require.Error(t, err) assert.Nil(t, bookmarks) assert.NoError(t, mock.ExpectationsWereMet()) }) } func TestBookmarkRepository_ListByWorkID(t *testing.T) { t.Run("should return bookmarks 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.NewBookmarkRepository(db, cfg) workID := uint(1) expectedBookmarks := []domain.Bookmark{ {BaseModel: domain.BaseModel{ID: 1, CreatedAt: time.Now(), UpdatedAt: time.Now()}, UserID: 1, WorkID: workID}, {BaseModel: domain.BaseModel{ID: 2, CreatedAt: time.Now(), UpdatedAt: time.Now()}, UserID: 2, WorkID: workID}, } rows := sqlmock.NewRows([]string{"id", "created_at", "updated_at", "user_id", "work_id"}). AddRow(expectedBookmarks[0].ID, expectedBookmarks[0].CreatedAt, expectedBookmarks[0].UpdatedAt, expectedBookmarks[0].UserID, expectedBookmarks[0].WorkID). AddRow(expectedBookmarks[1].ID, expectedBookmarks[1].CreatedAt, expectedBookmarks[1].UpdatedAt, expectedBookmarks[1].UserID, expectedBookmarks[1].WorkID) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "bookmarks" WHERE work_id = $1`)). WithArgs(workID). WillReturnRows(rows) bookmarks, err := repo.ListByWorkID(context.Background(), workID) require.NoError(t, err) assert.Equal(t, expectedBookmarks, bookmarks) 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.NewBookmarkRepository(db, cfg) workID := uint(1) mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "bookmarks" WHERE work_id = $1`)). WithArgs(workID). WillReturnError(sql.ErrNoRows) bookmarks, err := repo.ListByWorkID(context.Background(), workID) require.Error(t, err) assert.Nil(t, bookmarks) assert.NoError(t, mock.ExpectationsWereMet()) }) }