package tests import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" "mohportal/config" "mohportal/db" "mohportal/models" "mohportal/handlers" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "gorm.io/driver/sqlite" "gorm.io/gorm" ) var testDB *gorm.DB func init() { // Initialize test database var err error testDB, err = gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) if err != nil { panic("failed to connect to test database") } // Run migrations err = testDB.AutoMigrate( &models.Tenant{}, &models.User{}, &models.OIDCIdentity{}, &models.SocialIdentity{}, &models.JobPosition{}, &models.Resume{}, &models.Application{}, ) if err != nil { panic("failed to migrate test database") } // Replace the main DB with test DB db.DB = testDB } func setupRouter() *gin.Engine { gin.SetMode(gin.TestMode) router := gin.New() // Health check endpoint router.GET("/health", handlers.HealthCheck) // API routes api := router.Group("/api/v1") { tenants := api.Group("/tenants") { tenants.POST("/", handlers.CreateTenant) tenants.GET("/", handlers.GetTenants) tenants.GET("/:id", handlers.GetTenant) } auth := api.Group("/auth") { auth.POST("/login", handlers.Login) auth.POST("/register", handlers.Register) } positions := api.Group("/positions") { positions.GET("/", handlers.GetPositions) positions.GET("/:id", handlers.GetPosition) positions.POST("/", handlers.CreatePosition) } applications := api.Group("/applications") { applications.GET("/", handlers.GetApplications) applications.POST("/", handlers.CreateApplication) } resumes := api.Group("/resumes") { resumes.POST("/", handlers.UploadResume) resumes.GET("/:id", handlers.GetResume) } } return router } func TestHealthCheck(t *testing.T) { router := setupRouter() 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 TestCreateTenant(t *testing.T) { router := setupRouter() tenantData := map[string]string{ "name": "Test Tenant", "slug": "test-tenant", "description": "A test tenant for testing purposes", } jsonData, _ := json.Marshal(tenantData) req, _ := http.NewRequest("POST", "/api/v1/tenants/", 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 TestGetTenants(t *testing.T) { router := setupRouter() req, _ := http.NewRequest("GET", "/api/v1/tenants/", nil) w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) } func TestCreateUser(t *testing.T) { // First create a tenant for the user var tenant models.Tenant tenantData := map[string]string{ "name": "Test Tenant", "slug": "test-tenant-user", "description": "A test tenant for user testing", } jsonData, _ := json.Marshal(tenantData) router := setupRouter() req, _ := http.NewRequest("POST", "/api/v1/tenants/", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusCreated, w.Code) err := json.Unmarshal(w.Body.Bytes(), &tenant) assert.NoError(t, err) // Now register a user userData := map[string]interface{}{ "tenant_id": tenant.ID.String(), "email": "test@example.com", "username": "testuser", "first_name": "Test", "last_name": "User", "phone": "1234567890", "role": "job_seeker", "password": "password123", } jsonData, _ = json.Marshal(userData) req, _ = http.NewRequest("POST", "/api/v1/auth/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 TestLogin(t *testing.T) { // First create a user for login test router := setupRouter() // Create a tenant first tenantData := map[string]string{ "name": "Test Tenant", "slug": "test-tenant-login", "description": "A test tenant for login testing", } jsonData, _ := json.Marshal(tenantData) req, _ := http.NewRequest("POST", "/api/v1/tenants/", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() router.ServeHTTP(w, req) var tenant models.Tenant err := json.Unmarshal(w.Body.Bytes(), &tenant) assert.NoError(t, err) // Create a user userData := map[string]interface{}{ "tenant_id": tenant.ID.String(), "email": "login@example.com", "username": "loginuser", "first_name": "Login", "last_name": "User", "phone": "0987654321", "role": "job_seeker", "password": "password123", } jsonData, _ = json.Marshal(userData) req, _ = http.NewRequest("POST", "/api/v1/auth/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) // Now try to login loginData := map[string]string{ "email": "login@example.com", "password": "password123", } jsonData, _ = json.Marshal(loginData) req, _ = http.NewRequest("POST", "/api/v1/auth/login", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w = httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) } func TestCreateJobPosition(t *testing.T) { router := setupRouter() // Create a tenant and user first tenantData := map[string]string{ "name": "Test Tenant", "slug": "test-tenant-position", "description": "A test tenant for position testing", } jsonData, _ := json.Marshal(tenantData) req, _ := http.NewRequest("POST", "/api/v1/tenants/", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() router.ServeHTTP(w, req) var tenant models.Tenant err := json.Unmarshal(w.Body.Bytes(), &tenant) assert.NoError(t, err) // Create a user userData := map[string]interface{}{ "tenant_id": tenant.ID.String(), "email": "position@example.com", "username": "positionuser", "first_name": "Position", "last_name": "User", "phone": "5555555555", "role": "job_provider", "password": "password123", } jsonData, _ = json.Marshal(userData) req, _ = http.NewRequest("POST", "/api/v1/auth/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) // Now create a job position positionData := map[string]interface{}{ "title": "Software Engineer", "description": "A software engineering position", "requirements": "3+ years of experience with Go", "location": "Remote", "employment_type": "full_time", "salary_min": 80000.0, "salary_max": 120000.0, "experience_level": "mid_level", } jsonData, _ = json.Marshal(positionData) req, _ = http.NewRequest("POST", "/api/v1/positions/", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") w = httptest.NewRecorder() router.ServeHTTP(w, req) assert.Equal(t, http.StatusCreated, w.Code) }