#!/bin/bash set -euo pipefail # Composable App E2E Test Script # Tests the composable monorepo template flow: # 1. Create project (skeleton) # 2. Add service component # 3. Add app component # 4. Optionally customize with Claude # 5. Deploy and verify # # Usage: ./cookbooks/scripts/composable-test.sh # Commands: run, status, teardown SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh" COMMAND="${1:-}" PROJECT_NAME="${2:-}" if [[ -z "$COMMAND" || -z "$PROJECT_NAME" ]]; then echo "Usage: $0 " echo "Commands:" echo " run - Create project with components and deploy" echo " status - Check project and component status" echo " teardown - Delete the project" exit 1 fi # Add a component and verify add_component() { local comp_type="$1" local comp_name="$2" local template="${3:-$comp_type}" echo "Adding $comp_type component: $comp_name (template: $template)" local payload payload=$(jq -n \ --arg type "$comp_type" \ --arg name "$comp_name" \ --arg template "$template" \ '{type: $type, name: $name, template: $template}') local result result=$(api_call POST "/projects/$PROJECT_NAME/components" "$payload") local path path=$(echo "$result" | jq -r '.data.path // .path // ""') if [[ -z "$path" ]]; then print_error "Failed to add component" echo "$result" | jq '.' return 1 fi local port port=$(echo "$result" | jq -r '.data.port // .port // "N/A"') print_success "Added $comp_type/$comp_name at $path (port: $port)" return 0 } run_flow() { print_header "Composable App E2E Test" echo "Project: $PROJECT_NAME" # Step 1: Create project (skeleton) print_header "Step 1: Creating project skeleton" local create_payload create_payload=$(jq -n \ --arg name "$PROJECT_NAME" \ --arg desc "Composable app E2E test" \ '{name: $name, description: $desc}') local create_result create_result=$(api_call POST "/projects" "$create_payload") echo "$create_result" | jq '.' local domain domain=$(echo "$create_result" | jq -r '.data.domain // .domain // ""') if [[ -z "$domain" ]]; then print_error "Failed to create project" exit 1 fi print_success "Project created with domain: $domain" # Step 2: Add backend service print_header "Step 2: Adding backend service" if ! add_component "service" "api" "service"; then exit 1 fi # Step 3: Add frontend app print_header "Step 3: Adding frontend app" if ! add_component "app" "web" "app-react"; then exit 1 fi # Step 4: List components print_header "Step 4: Verifying components" local components components=$(api_call GET "/projects/$PROJECT_NAME/components") echo "$components" | jq '.data // .' local comp_count comp_count=$(echo "$components" | jq '.data | length // 0') if [[ "$comp_count" -lt 2 ]]; then print_warning "Expected 2 components, got $comp_count" else print_success "All components added successfully" fi # Step 5: Wait for CI pipeline print_header "Step 5: Waiting for CI pipeline" if ! wait_for_pipeline "$PROJECT_NAME"; then print_warning "Pipeline may have issues, continuing to check site..." fi # Step 6: Wait for site print_header "Step 6: Verifying site is accessible" if ! wait_for_site "$domain"; then print_error "Site not accessible" exit 1 fi # Step 7: Test API endpoint print_header "Step 7: Testing API endpoint" local api_response api_response=$(curl -s "https://$domain/api/health" 2>/dev/null || echo '{"error":"failed"}') if echo "$api_response" | jq -e '.' > /dev/null 2>&1; then print_success "API responded with valid JSON" echo "$api_response" | jq '.' else print_warning "API health check returned non-JSON: $api_response" fi # Summary print_header "E2E Test Results" print_success "Project created: $PROJECT_NAME" print_success "Components added: $comp_count" echo "" echo "Site URL: https://$domain" echo "Git repo: https://git.threesix.ai/jordan/$PROJECT_NAME" echo "CI: https://ci.threesix.ai/jordan/$PROJECT_NAME" } check_status() { print_header "Project Status: $PROJECT_NAME" # Get project info echo "Project:" api_call GET "/projects/$PROJECT_NAME" | jq '.data // .' echo "" # Get components echo "Components:" api_call GET "/projects/$PROJECT_NAME/components" | jq '.data // .' echo "" # Get latest pipelines echo "Latest Pipelines:" api_call GET "/projects/$PROJECT_NAME/pipelines" | jq '.data[:3] // .' } teardown() { print_header "Tearing down: $PROJECT_NAME" local result result=$(api_call DELETE "/projects/$PROJECT_NAME") echo "$result" | jq '.' echo "" print_success "Project deleted. Gitea repo preserved." } case "$COMMAND" in run) run_flow ;; status) check_status ;; teardown) teardown ;; *) echo "Unknown command: $COMMAND" echo "Valid commands: run, status, teardown" exit 1 ;; esac