package testing import ( "bytes" "encoding/json" "fotbal-club/internal/models" "net/http" "net/http/httptest" "strconv" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "gorm.io/driver/sqlite" "gorm.io/gorm" ) // SetupTestDB creates an in-memory SQLite database for testing func SetupTestDB(t *testing.T) *gorm.DB { db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) if err != nil { t.Fatalf("Failed to create test database: %v", err) } // Auto-migrate all models err = db.AutoMigrate( &models.User{}, &models.Article{}, &models.Category{}, &models.Player{}, &models.Settings{}, &models.ContactMessage{}, &models.NewsletterSubscription{}, &models.Clothing{}, &models.Poll{}, &models.PollOption{}, &models.PollVote{}, ) if err != nil { t.Fatalf("Failed to migrate test database: %v", err) } return db } // CreateTestUser creates a test user func CreateTestUser(db *gorm.DB, role string) *models.User { user := &models.User{ Email: "test@example.com", Password: "$2a$10$test_hashed_password", FirstName: "Test", LastName: "User", Role: role, } db.Create(user) return user } // CreateTestArticle creates a test article func CreateTestArticle(db *gorm.DB, authorID uint) *models.Article { article := &models.Article{ Title: "Test Article", Content: "

Test content

", Slug: "test-article", Published: true, AuthorID: &authorID, } db.Create(article) return article } // MakeTestRequest creates a test HTTP request func MakeTestRequest(method, path string, body interface{}) (*http.Request, error) { var reqBody *bytes.Buffer if body != nil { jsonData, err := json.Marshal(body) if err != nil { return nil, err } reqBody = bytes.NewBuffer(jsonData) } else { reqBody = &bytes.Buffer{} } req, err := http.NewRequest(method, path, reqBody) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/json") return req, nil } // ExecuteRequest executes a test request and returns response func ExecuteRequest(router *gin.Engine, req *http.Request) *httptest.ResponseRecorder { w := httptest.NewRecorder() router.ServeHTTP(w, req) return w } // AssertJSONResponse checks JSON response func AssertJSONResponse(t *testing.T, w *httptest.ResponseRecorder, expectedStatus int, expectedBody map[string]interface{}) { assert.Equal(t, expectedStatus, w.Code) var response map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) for key, expectedValue := range expectedBody { assert.Equal(t, expectedValue, response[key], "Mismatch for key: %s", key) } } // MockGinContext creates a mock Gin context for testing func MockGinContext() (*gin.Context, *httptest.ResponseRecorder) { gin.SetMode(gin.TestMode) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) return c, w } // CleanupTestDB closes and cleans up test database func CleanupTestDB(db *gorm.DB) { sqlDB, _ := db.DB() if sqlDB != nil { sqlDB.Close() } } // SeedTestData populates test database with sample data func SeedTestData(db *gorm.DB) { // Create admin user admin := CreateTestUser(db, "admin") // Create categories categories := []models.Category{ {Name: "Aktuality", Description: "Club news"}, {Name: "Zápasy", Description: "Match reports"}, {Name: "Tréninky", Description: "Training updates"}, } for _, cat := range categories { db.Create(&cat) } // Create articles for i := 1; i <= 10; i++ { article := &models.Article{ Title: "Test Article " + strconv.Itoa(i), Content: "

Test content

", Slug: "test-article-" + strconv.Itoa(i), Published: true, AuthorID: &admin.ID, CategoryID: &[]uint{1}[0], } db.Create(article) } } // AssertDatabaseState checks database state func AssertDatabaseState(t *testing.T, db *gorm.DB, model interface{}, count int64) { var actualCount int64 db.Model(model).Count(&actualCount) assert.Equal(t, count, actualCount) }