package repository import ( "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/gochat/gochat/internal/model" ) func TestBaseRepository_Create(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) account := &model.Account{ Name: "TestOrg", Locale: "en", } err := repo.Create(context.Background(), account) assert.NoError(t, err) assert.NotZero(t, account.ID, "ID should be set after Create") } func TestBaseRepository_GetByID(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) account := &model.Account{Name: "GetTestOrg", Locale: "en"} err := repo.Create(context.Background(), account) assert.NoError(t, err) found, err := repo.GetByID(context.Background(), account.ID) assert.NoError(t, err) assert.Equal(t, account.Name, found.Name) assert.Equal(t, account.ID, found.ID) } func TestBaseRepository_GetByID_NotFound(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) found, err := repo.GetByID(context.Background(), 9999) assert.Error(t, err) assert.Nil(t, found) } func TestBaseRepository_Update(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) account := &model.Account{Name: "BeforeUpdate", Locale: "en"} err := repo.Create(context.Background(), account) assert.NoError(t, err) account.Name = "AfterUpdate" err = repo.Update(context.Background(), account) assert.NoError(t, err) found, err := repo.GetByID(context.Background(), account.ID) assert.NoError(t, err) assert.Equal(t, "AfterUpdate", found.Name) } func TestBaseRepository_Delete(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) account := &model.Account{Name: "DeleteTarget", Locale: "en"} err := repo.Create(context.Background(), account) assert.NoError(t, err) err = repo.Delete(context.Background(), account.ID) assert.NoError(t, err) // After soft-delete, normal GetByID should not find it found, err := repo.GetByID(context.Background(), account.ID) assert.Error(t, err) assert.Nil(t, found) } func TestBaseRepository_List(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) // Create 3 accounts for i := 0; i < 3; i++ { acc := &model.Account{Name: "ListOrg" + string(rune('A'+i)), Locale: "en"} err := repo.Create(context.Background(), acc) assert.NoError(t, err) } // List with pagination entities, err := repo.List(context.Background(), 0, 10) assert.NoError(t, err) assert.Len(t, entities, 3) } func TestBaseRepository_List_Pagination(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) for i := 0; i < 5; i++ { acc := &model.Account{Name: "PageOrg" + string(rune('A'+i)), Locale: "en"} err := repo.Create(context.Background(), acc) assert.NoError(t, err) } // First page page1, err := repo.List(context.Background(), 0, 2) assert.NoError(t, err) assert.Len(t, page1, 2) // Second page page2, err := repo.List(context.Background(), 2, 2) assert.NoError(t, err) assert.Len(t, page2, 2) } func TestBaseRepository_Count(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) for i := 0; i < 4; i++ { acc := &model.Account{Name: "CountOrg" + string(rune('A'+i)), Locale: "en"} err := repo.Create(context.Background(), acc) assert.NoError(t, err) } count, err := repo.Count(context.Background()) assert.NoError(t, err) assert.Equal(t, int64(4), count) } func TestBaseRepository_DB_ReturnsUnderlyingDB(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) retrievedDB := repo.DB() assert.NotNil(t, retrievedDB) } // --- Mock-based tests for BaseRepository error paths --- // These use testify/mock to verify that BaseRepository properly propagates GORM errors. type MockGormDB struct { mock.Mock } // We don't need to mock the full gorm.DB interface for compilation; // the real-DB tests above cover the actual CRUD flows. // This test verifies that the constructor returns a non-nil repository. func TestNewBaseRepository_ReturnsNonNil(t *testing.T) { db := setupTestDB(t) repo := NewBaseRepository[model.Account](db) assert.NotNil(t, repo) } func TestNewBaseRepository_WithUserModel(t *testing.T) { db := setupTestDB(t) if err := db.AutoMigrate(&model.User{}); err != nil { t.Fatalf("failed to migrate User: %v", err) } repo := NewBaseRepository[model.User](db) assert.NotNil(t, repo) user := &model.User{ AccountID: 1, Name: "TestUser", Email: "test@example.com", Password: "hashed", Provider: "email", Role: "agent", } err := repo.Create(context.Background(), user) assert.NoError(t, err) assert.NotZero(t, user.ID) }