feat: implement core Go application with web server

- Add Go modules with required dependencies (Gin, UUID, JWT, etc.)
- Implement main web server with landing page endpoint
- Add comprehensive API endpoints for health and status
- Include proper error handling and request validation
- Set up CORS middleware and security headers
This commit is contained in:
YourDreamNameHere
2025-11-20 16:36:28 -05:00
parent aa93326897
commit 89443f213b
57 changed files with 14404 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
package integration
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
// Integration Test Suite
type IntegrationTestSuite struct {
suite.Suite
baseURL string
httpClient *http.Client
authToken string
testUserID string
}
func (suite *IntegrationTestSuite) SetupSuite() {
// Configuration for integration tests
suite.baseURL = "http://localhost:8080"
suite.httpClient = &http.Client{
Timeout: 30 * time.Second,
}
// Wait for the application to be ready
suite.waitForApplication()
}
func (suite *IntegrationTestSuite) TearDownSuite() {
// Cleanup if needed
}
func (suite *IntegrationTestSuite) waitForApplication() {
maxAttempts := 30
attempt := 0
for attempt < maxAttempts {
resp, err := suite.httpClient.Get(suite.baseURL + "/health")
if err == nil && resp.StatusCode == http.StatusOK {
resp.Body.Close()
return
}
if resp != nil {
resp.Body.Close()
}
attempt++
time.Sleep(2 * time.Second)
}
suite.T().Fatal("Application not ready after timeout")
}
func (suite *IntegrationTestSuite) makeRequest(method, endpoint string, body interface{}, headers map[string]string) (*http.Response, error) {
var reqBody *bytes.Buffer
if body != nil {
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, err
}
reqBody = bytes.NewBuffer(jsonBody)
} else {
reqBody = bytes.NewBuffer(nil)
}
req, err := http.NewRequest(method, suite.baseURL+endpoint, reqBody)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
if suite.authToken != "" {
req.Header.Set("Authorization", "Bearer "+suite.authToken)
}
for key, value := range headers {
req.Header.Set(key, value)
}
return suite.httpClient.Do(req)
}
func (suite *IntegrationTestSuite) TestApplicationHealth() {
resp, err := suite.makeRequest("GET", "/health", nil, nil)
suite.NoError(err)
suite.Equal(http.StatusOK, resp.StatusCode)
var health map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&health)
resp.Body.Close()
suite.NoError(err)
suite.Equal("healthy", health["status"])
}
func (suite *IntegrationTestSuite) TestUserRegistrationAndLogin() {
// Test user registration
userData := map[string]interface{}{
"email": "testuser@example.com",
"first_name": "Test",
"last_name": "User",
"password": "testpassword123",
}
resp, err := suite.makeRequest("POST", "/api/v1/register", userData, nil)
suite.NoError(err)
suite.Equal(http.StatusCreated, resp.StatusCode)
var registerResponse map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&registerResponse)
resp.Body.Close()
suite.NoError(err)
suite.Equal("User created successfully", registerResponse["message"])
// Test user login
loginData := map[string]interface{}{
"email": "testuser@example.com",
"password": "testpassword123",
}
resp, err = suite.makeRequest("POST", "/api/v1/login", loginData, nil)
suite.NoError(err)
suite.Equal(http.StatusOK, resp.StatusCode)
var loginResponse map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&loginResponse)
resp.Body.Close()
suite.NoError(err)
suite.NotEmpty(loginResponse["token"])
suite.authToken = loginResponse["token"].(string)
}
func (suite *IntegrationTestSuite) TestProtectedEndpoints() {
// First, login to get auth token
suite.TestUserRegistrationAndLogin()
// Test getting user profile
resp, err := suite.makeRequest("GET", "/api/v1/profile", nil, nil)
suite.NoError(err)
suite.Equal(http.StatusOK, resp.StatusCode)
var profileResponse map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&profileResponse)
resp.Body.Close()
suite.NoError(err)
suite.NotNil(profileResponse["user"])
user := profileResponse["user"].(map[string]interface{})
suite.Equal("testuser@example.com", user["email"])
suite.Equal("Test", user["first_name"])
suite.Equal("User", user["last_name"])
}
func (suite *IntegrationTestSuite) TestPricingEndpoint() {
resp, err := suite.makeRequest("GET", "/api/v1/pricing", nil, nil)
suite.NoError(err)
suite.Equal(http.StatusOK, resp.StatusCode)
var pricingResponse map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&pricingResponse)
resp.Body.Close()
suite.NoError(err)
suite.NotNil(pricingResponse["plans"])
plans := pricingResponse["plans"].([]interface{})
suite.Len(plans, 1)
plan := plans[0].(map[string]interface{})
suite.Equal("Sovereign Hosting", plan["name"])
suite.Equal(float64(25000), plan["price"]) // $250.00 in cents
suite.Equal("usd", plan["currency"])
}
func (suite *IntegrationTestSuite) TestCheckoutSession() {
// Test creating a checkout session
checkoutData := map[string]interface{}{
"domain_name": "testdomain.com",
"email": "customer@example.com",
}
resp, err := suite.makeRequest("POST", "/api/v1/checkout", checkoutData, nil)
suite.NoError(err)
suite.Equal(http.StatusOK, resp.StatusCode)
var checkoutResponse map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&checkoutResponse)
resp.Body.Close()
suite.NoError(err)
suite.NotNil(checkoutResponse["checkout_url"])
suite.Contains(checkoutResponse["checkout_url"].(string), "checkout.stripe.com")
}
func (suite *IntegrationTestSuite) TestErrorHandling() {
// Test invalid registration data
invalidUserData := map[string]interface{}{
"email": "invalid-email",
"first_name": "",
"last_name": "",
"password": "123", // Too short
}
resp, err := suite.makeRequest("POST", "/api/v1/register", invalidUserData, nil)
suite.NoError(err)
suite.Equal(http.StatusBadRequest, resp.StatusCode)
var errorResponse map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&errorResponse)
resp.Body.Close()
suite.NoError(err)
suite.NotNil(errorResponse["error"])
// Test invalid login credentials
invalidLoginData := map[string]interface{}{
"email": "nonexistent@example.com",
"password": "wrongpassword",
}
resp, err = suite.makeRequest("POST", "/api/v1/login", invalidLoginData, nil)
suite.NoError(err)
suite.Equal(http.StatusUnauthorized, resp.StatusCode)
// Test protected endpoint without auth
resp, err = suite.makeRequest("GET", "/api/v1/profile", nil, nil)
suite.NoError(err)
suite.Equal(http.StatusUnauthorized, resp.StatusCode)
}
func (suite *IntegrationTestSuite) TestRateLimiting() {
// This test would require configuring rate limits for testing
// For now, we'll just make multiple requests to ensure basic functionality
for i := 0; i < 5; i++ {
resp, err := suite.makeRequest("GET", "/api/v1/pricing", nil, nil)
suite.NoError(err)
suite.Equal(http.StatusOK, resp.StatusCode)
resp.Body.Close()
}
}
func (suite *IntegrationTestSuite) TestCORSEnabled() {
// Test CORS headers
headers := map[string]string{
"Origin": "http://localhost:3000",
}
resp, err := suite.makeRequest("OPTIONS", "/api/v1/pricing", nil, headers)
suite.NoError(err)
suite.True(resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNoContent)
// Check CORS headers
assert.Equal(suite.T(), "http://localhost:3000", resp.Header.Get("Access-Control-Allow-Origin"))
assert.Contains(suite.T(), resp.Header.Get("Access-Control-Allow-Methods"), "GET")
assert.Contains(suite.T(), resp.Header.Get("Access-Control-Allow-Headers"), "Content-Type")
resp.Body.Close()
}
// Run the integration test suite
func TestIntegrationSuite(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration tests in short mode")
}
suite.Run(t, new(IntegrationTestSuite))
}