178 lines
4.2 KiB
Go
178 lines
4.2 KiB
Go
//go:build e2e
|
|
// +build e2e
|
|
|
|
package e2e
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/rede5/gohorsejobs/backend/internal/database"
|
|
"github.com/rede5/gohorsejobs/backend/internal/router"
|
|
)
|
|
|
|
var testServer *httptest.Server
|
|
|
|
// TestMain sets up the test environment for all E2E tests
|
|
func TestMain(m *testing.M) {
|
|
// Set environment variables for testing
|
|
setTestEnv()
|
|
|
|
// Initialize database connection
|
|
database.InitDB()
|
|
|
|
// Create test server
|
|
testServer = httptest.NewServer(router.NewRouter())
|
|
defer testServer.Close()
|
|
|
|
// Run tests
|
|
code := m.Run()
|
|
|
|
// Cleanup
|
|
cleanupTestData()
|
|
|
|
os.Exit(code)
|
|
}
|
|
|
|
// setTestEnv sets up environment variables for testing
|
|
// Uses the same database as development (loaded from .env in CI/CD or manually set)
|
|
func setTestEnv() {
|
|
// Only set if not already set (allows override via .env file)
|
|
// These are defaults for when running tests without sourcing .env
|
|
if os.Getenv("DB_HOST") == "" {
|
|
os.Setenv("DB_HOST", "db-60059.dc-sp-1.absamcloud.com")
|
|
}
|
|
if os.Getenv("DB_USER") == "" {
|
|
os.Setenv("DB_USER", "yuki")
|
|
}
|
|
if os.Getenv("DB_PASSWORD") == "" {
|
|
os.Setenv("DB_PASSWORD", "xl1zfmr6e9bb")
|
|
}
|
|
if os.Getenv("DB_NAME") == "" {
|
|
os.Setenv("DB_NAME", "gohorsejobs_dev")
|
|
}
|
|
if os.Getenv("DB_PORT") == "" {
|
|
os.Setenv("DB_PORT", "26868")
|
|
}
|
|
if os.Getenv("DB_SSLMODE") == "" {
|
|
os.Setenv("DB_SSLMODE", "require")
|
|
}
|
|
if os.Getenv("JWT_SECRET") == "" {
|
|
os.Setenv("JWT_SECRET", "gohorse-super-secret-key-2024-production")
|
|
}
|
|
}
|
|
|
|
// cleanupTestData removes test data from the database
|
|
func cleanupTestData() {
|
|
if database.DB != nil {
|
|
// Clean up in reverse order of dependencies
|
|
database.DB.Exec("DELETE FROM applications WHERE id > 0")
|
|
database.DB.Exec("DELETE FROM jobs WHERE title LIKE 'E2E Test%'")
|
|
database.DB.Exec("DELETE FROM companies WHERE name LIKE 'E2E Test%'")
|
|
}
|
|
}
|
|
|
|
// httpClient helper for making requests to test server
|
|
type testClient struct {
|
|
baseURL string
|
|
token string
|
|
}
|
|
|
|
func newTestClient() *testClient {
|
|
return &testClient{
|
|
baseURL: testServer.URL,
|
|
}
|
|
}
|
|
|
|
func (c *testClient) setAuthToken(token string) {
|
|
c.token = token
|
|
}
|
|
|
|
func (c *testClient) doRequest(method, path string, body interface{}) (*http.Response, error) {
|
|
var reqBody io.Reader
|
|
if body != nil {
|
|
jsonData, err := json.Marshal(body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
reqBody = bytes.NewReader(jsonData)
|
|
}
|
|
|
|
req, err := http.NewRequest(method, c.baseURL+path, reqBody)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
if c.token != "" {
|
|
req.Header.Set("Authorization", "Bearer "+c.token)
|
|
}
|
|
|
|
return http.DefaultClient.Do(req)
|
|
}
|
|
|
|
func (c *testClient) get(path string) (*http.Response, error) {
|
|
return c.doRequest("GET", path, nil)
|
|
}
|
|
|
|
func (c *testClient) post(path string, body interface{}) (*http.Response, error) {
|
|
return c.doRequest("POST", path, body)
|
|
}
|
|
|
|
func (c *testClient) put(path string, body interface{}) (*http.Response, error) {
|
|
return c.doRequest("PUT", path, body)
|
|
}
|
|
|
|
func (c *testClient) delete(path string) (*http.Response, error) {
|
|
return c.doRequest("DELETE", path, nil)
|
|
}
|
|
|
|
// parseJSON helper to decode JSON response
|
|
func parseJSON(resp *http.Response, target interface{}) error {
|
|
defer resp.Body.Close()
|
|
return json.NewDecoder(resp.Body).Decode(target)
|
|
}
|
|
|
|
// TestHealthCheck verifies the server is running
|
|
func TestHealthCheck(t *testing.T) {
|
|
client := newTestClient()
|
|
|
|
resp, err := client.get("/health")
|
|
if err != nil {
|
|
t.Fatalf("Failed to make request: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
}
|
|
|
|
// TestRootEndpoint verifies the API info endpoint
|
|
func TestRootEndpoint(t *testing.T) {
|
|
client := newTestClient()
|
|
|
|
resp, err := client.get("/")
|
|
if err != nil {
|
|
t.Fatalf("Failed to make request: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := parseJSON(resp, &result); err != nil {
|
|
t.Fatalf("Failed to parse JSON: %v", err)
|
|
}
|
|
|
|
if result["message"] != "🐴 GoHorseJobs API is running!" {
|
|
t.Errorf("Unexpected message: %v", result["message"])
|
|
}
|
|
}
|