package service import ( "context" "fmt" "testing" "github.com/gochat/gochat/internal/model" "github.com/gochat/gochat/internal/repository" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/driver/sqlite" "gorm.io/gorm" ) func setupPreferenceServiceTestDB(t *testing.T) *gorm.DB { t.Helper() // Use unique DB per test to avoid cross-test data leakage dbName := fmt.Sprintf("file:%s?mode=memory&cache=private", t.Name()) db, err := gorm.Open(sqlite.Open(dbName), &gorm.Config{}) require.NoError(t, err) require.NoError(t, db.AutoMigrate(&model.CaptainPreference{})) return db } func newTestPreferenceService(t *testing.T) (*CaptainPreferenceService, *repository.CaptainPreferenceRepo) { t.Helper() db := setupPreferenceServiceTestDB(t) repo := repository.NewCaptainPreferenceRepo(db) svc := NewCaptainPreferenceService(repo) return svc, repo } func intPtr(v int) *int { return &v } func TestCaptainPreferenceService_Create(t *testing.T) { svc, _ := newTestPreferenceService(t) ctx := context.Background() req := &CreatePreferenceRequest{ Tone: "professional", Language: "en", AutoLabelEnabled: true, MaxResponseLength: 500, } pref, err := svc.Create(ctx, 1, req) require.NoError(t, err) assert.NotZero(t, pref.ID) assert.Equal(t, uint(1), pref.AccountID) assert.Equal(t, "professional", pref.Tone) assert.Equal(t, "en", pref.Language) assert.True(t, pref.AutoLabelEnabled) } func TestCaptainPreferenceService_Create_DuplicateAccount(t *testing.T) { svc, _ := newTestPreferenceService(t) ctx := context.Background() req := &CreatePreferenceRequest{Tone: "professional"} _, err := svc.Create(ctx, 1, req) require.NoError(t, err) req2 := &CreatePreferenceRequest{Tone: "casual"} _, err = svc.Create(ctx, 1, req2) assert.Error(t, err) // duplicate account_id should fail } func TestCaptainPreferenceService_Get(t *testing.T) { svc, _ := newTestPreferenceService(t) ctx := context.Background() req := &CreatePreferenceRequest{Tone: "friendly", Language: "es"} pref, err := svc.Create(ctx, 42, req) require.NoError(t, err) found, err := svc.Get(ctx, 42) require.NoError(t, err) assert.Equal(t, pref.ID, found.ID) assert.Equal(t, "friendly", found.Tone) } func TestCaptainPreferenceService_Get_NotFound(t *testing.T) { svc, _ := newTestPreferenceService(t) ctx := context.Background() _, err := svc.Get(ctx, 999) assert.Error(t, err) } func TestCaptainPreferenceService_Update(t *testing.T) { svc, _ := newTestPreferenceService(t) ctx := context.Background() req := &CreatePreferenceRequest{Tone: "professional", MaxResponseLength: 500} _, err := svc.Create(ctx, 1, req) require.NoError(t, err) updateReq := &UpdatePreferenceRequest{ Tone: "casual", MaxResponseLength: intPtr(200), } updated, err := svc.Update(ctx, 1, updateReq) require.NoError(t, err) assert.Equal(t, "casual", updated.Tone) assert.Equal(t, 200, updated.MaxResponseLength) } func TestCaptainPreferenceService_Delete(t *testing.T) { svc, _ := newTestPreferenceService(t) ctx := context.Background() req := &CreatePreferenceRequest{Tone: "formal"} _, err := svc.Create(ctx, 1, req) require.NoError(t, err) // Delete and verify soft delete err = svc.Delete(ctx, 1) require.NoError(t, err) _, err = svc.Get(ctx, 1) assert.Error(t, err) // soft deleted, should not be found }