package main import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/ydn/yourdreamnamehere/internal/api" "github.com/ydn/yourdreamnamehere/internal/config" "github.com/ydn/yourdreamnamehere/internal/models" "github.com/ydn/yourdreamnamehere/internal/services" "gorm.io/driver/sqlite" "gorm.io/gorm" ) // Test API endpoints func TestHealthEndpoint(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() handler := &api.Handler{} handler.RegisterRoutes(router) req, _ := http.NewRequest("GET", "/health", nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) var response map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) assert.Equal(t, "healthy", response["status"]) } func TestUserRegistration(t *testing.T) { // Setup test database db := setupTestDB(t) defer cleanupTestDB(db) // Create test services cfg := &config.Config{ JWT: config.JWTConfig{ Secret: "test-secret", Expiry: 24 * time.Hour, }, } userService := services.NewUserService(db, cfg) handler := api.NewHandler(userService, nil, nil, nil, nil, nil, nil) gin.SetMode(gin.TestMode) router := gin.New() router.Use(func(c *gin.Context) { c.Set("config", cfg) c.Next() }) handler.RegisterRoutes(router) // Test user registration userData := map[string]string{ "email": "test@example.com", "first_name": "Test", "last_name": "User", "password": "password123", } jsonData, _ := json.Marshal(userData) req, _ := http.NewRequest("POST", "/api/v1/register", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusCreated, w.Code) } func TestDomainValidation(t *testing.T) { // Test valid domains validDomains := []string{ "example.com", "test-domain.org", "sub.domain.co.uk", } for _, domain := range validDomains { assert.True(t, isValidDomain(domain), "Domain %s should be valid", domain) } // Test invalid domains invalidDomains := []string{ ".com", "example..com", "-example.com", "example-.com", "example", "toolongdomainnamethatexceedsthemaximumallowedlengthforadomainnamewhichisthirtytwocharacterslong.com", } for _, domain := range invalidDomains { assert.False(t, isValidDomain(domain), "Domain %s should be invalid", domain) } } func TestPricingEndpoint(t *testing.T) { gin.SetMode(gin.TestMode) router := gin.New() handler := &api.Handler{} handler.RegisterRoutes(router) req, _ := http.NewRequest("GET", "/api/v1/pricing", nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) var response map[string]interface{} err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) assert.Contains(t, response, "plans") } // Helper function to setup test database func setupTestDB(t *testing.T) *gorm.DB { db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) assert.NoError(t, err) // Migrate tables err = db.AutoMigrate( &models.User{}, &models.Customer{}, &models.Subscription{}, &models.Domain{}, &models.VPS{}, &models.DeploymentLog{}, &models.Invitation{}, ) assert.NoError(t, err) return db } func cleanupTestDB(db *gorm.DB) { sqlDB, _ := db.DB() sqlDB.Close() } // Mock domain validation function (copied from handler) func isValidDomain(domain string) bool { if len(domain) < 3 || len(domain) > 63 { return false } // Basic validation - should contain at least one dot if !strings.Contains(domain, ".") { return false } // Should not start or end with hyphen if strings.HasPrefix(domain, "-") || strings.HasSuffix(domain, "-") { return false } // Should not start or end with dot if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") { return false } return true }