#!/bin/bash # Landing Page Cookbook Test Script # Tests the full landing page flow from cookbooks/landing-page.md # # Usage: # ./cookbooks/scripts/landing-test.sh run # Run the full flow # ./cookbooks/scripts/landing-test.sh teardown # Clean up test resources # ./cookbooks/scripts/landing-test.sh status # Check current status set -euo pipefail # Configuration API_URL="${RDEV_API_URL:-https://rdev.masq-ops.orchard9.ai}" API_KEY="${RDEV_API_KEY:?RDEV_API_KEY environment variable required}" PROJECT_NAME="${1:-landing-test}" TEMPLATE="astro-landing" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[OK]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } api_call() { local method="$1" local endpoint="$2" local data="${3:-}" if [[ -n "$data" ]]; then curl -s -X "$method" "${API_URL}${endpoint}" \ -H "X-API-Key: ${API_KEY}" \ -H "Content-Type: application/json" \ -d "$data" else curl -s -X "$method" "${API_URL}${endpoint}" \ -H "X-API-Key: ${API_KEY}" fi } check_health() { log_info "Checking API health..." local response response=$(curl -s "${API_URL}/health") if echo "$response" | jq -e '.data.status == "ok"' > /dev/null 2>&1; then log_success "API is healthy" return 0 else log_error "API health check failed" echo "$response" | jq . return 1 fi } run_flow() { local project_name="${1:-landing-test}" local custom_subdomain="${2:-}" echo "" echo "==========================================" echo " Landing Page Cookbook Test" echo " Project: $project_name" if [[ -n "$custom_subdomain" ]]; then echo " Custom subdomain: $custom_subdomain" fi echo "==========================================" echo "" # Step 0: Health check check_health || exit 1 echo "" # Step 1: Create project log_info "Step 1: Creating project with $TEMPLATE template..." local create_payload="{ \"name\": \"$project_name\", \"description\": \"Cookbook test: landing page flow\", \"template\": \"$TEMPLATE\"" if [[ -n "$custom_subdomain" ]]; then create_payload="$create_payload, \"custom_subdomain\": \"$custom_subdomain\"" fi create_payload="$create_payload }" local create_response create_response=$(api_call POST "/project" "$create_payload") if echo "$create_response" | jq -e '.error' > /dev/null 2>&1; then log_error "Failed to create project" echo "$create_response" | jq . exit 1 fi log_success "Project created" echo "$create_response" | jq '{ project_id: .data.project_id, slug: .data.slug, git_url: .data.git.html_url, domain: .data.domain, url: .data.url, domains: .data.domains, next_steps: .data.next_steps }' # Extract domain info local primary_domain local slug primary_domain=$(echo "$create_response" | jq -r '.data.domain') slug=$(echo "$create_response" | jq -r '.data.slug // empty') if [[ -n "$slug" ]]; then log_success "Auto-generated slug: $slug" fi # Check for manual steps local next_steps next_steps=$(echo "$create_response" | jq -r '.data.next_steps[]?' 2>/dev/null || echo "") if [[ -n "$next_steps" ]]; then echo "" log_warn "Some steps require manual intervention:" echo "$create_response" | jq -r '.data.next_steps[]' echo "" log_info "Check API logs for details: ./scripts/logs.sh -e" fi echo "" # Step 2: List all domains log_info "Step 2: Listing all project domains..." local domains_response domains_response=$(api_call GET "/projects/$project_name/domains") if echo "$domains_response" | jq -e '.error' > /dev/null 2>&1; then log_warn "Could not list domains" echo "$domains_response" | jq . else local domain_count domain_count=$(echo "$domains_response" | jq -r '.data.total') log_success "Found $domain_count domain(s)" echo "$domains_response" | jq '.data.domains[] | {domain, type, verified}' fi echo "" # Step 3: Verify project status log_info "Step 3: Verifying project status..." sleep 2 # Give DNS/Gitea a moment local status_response status_response=$(api_call GET "/project/$project_name") if echo "$status_response" | jq -e '.error' > /dev/null 2>&1; then log_warn "Could not fetch project status" echo "$status_response" | jq . else log_success "Project status retrieved" echo "$status_response" | jq '{ name: .data.name, slug: .data.slug, domain: .data.domain, url: .data.url, domains: .data.domains, git: .data.git.html_url, deployment: .data.deployment }' fi echo "" # Step 4: Check DNS log_info "Step 4: Checking DNS resolution..." if host "$primary_domain" > /dev/null 2>&1; then log_success "DNS resolves: $primary_domain" host "$primary_domain" | head -1 else log_warn "DNS not yet resolving: $primary_domain (may take a few minutes)" fi echo "" # Step 5: Summary echo "==========================================" echo " Summary" echo "==========================================" echo "" echo " Git repo: $(echo "$create_response" | jq -r '.data.git.html_url')" if [[ -n "$slug" ]]; then echo " Slug: $slug" fi echo " Primary: https://$primary_domain" echo "" echo " All domains:" echo "$domains_response" | jq -r '.data.domains[]? | " - \(.domain) (\(.type))"' 2>/dev/null || echo " (none listed)" echo "" echo " Next steps:" echo " 1. If CI/template failed, check logs: ./scripts/logs.sh -e" echo " 2. Push code to trigger CI build" echo " 3. Monitor pipeline: curl -s -H 'X-API-Key: \$RDEV_API_KEY' $API_URL/projects/$project_name/pipelines | jq" echo " 4. Verify site: curl -I https://$primary_domain" echo "" echo " Add custom domain:" echo " curl -X POST -H 'X-API-Key: \$RDEV_API_KEY' -H 'Content-Type: application/json' \\" echo " -d '{\"domain\":\"my-site.threesix.ai\"}' \\" echo " $API_URL/projects/$project_name/domains" echo "" echo " Teardown:" echo " ./cookbooks/scripts/landing-test.sh teardown $project_name" echo "" } teardown() { local project_name="${1:-landing-test}" echo "" echo "==========================================" echo " Teardown: $project_name" echo "==========================================" echo "" # First, list domains that will be deleted log_info "Checking domains to be deleted..." local domains_response domains_response=$(api_call GET "/projects/$project_name/domains") if echo "$domains_response" | jq -e '.data.total' > /dev/null 2>&1; then local domain_count domain_count=$(echo "$domains_response" | jq -r '.data.total') log_info "Will delete $domain_count domain(s):" echo "$domains_response" | jq -r '.data.domains[]? | " - \(.domain)"' echo "" fi log_info "Deleting project $project_name..." local response response=$(api_call DELETE "/project/$project_name") if echo "$response" | jq -e '.data.status == "deleted"' > /dev/null 2>&1; then log_success "Project deleted" echo "$response" | jq . elif echo "$response" | jq -e '.error.code == "NOT_FOUND"' > /dev/null 2>&1; then log_warn "Project not found (already deleted?)" else log_error "Failed to delete project" echo "$response" | jq . exit 1 fi echo "" log_info "Note: Gitea repo is preserved for safety. Delete manually if needed:" echo " https://git.threesix.ai/jordan/$project_name/settings" echo "" } status() { local project_name="${1:-landing-test}" echo "" log_info "Fetching status for: $project_name" echo "" local response response=$(api_call GET "/project/$project_name") if echo "$response" | jq -e '.error' > /dev/null 2>&1; then log_error "Project not found or error" echo "$response" | jq . exit 1 fi echo "$response" | jq '{ name: .data.name, description: .data.description, slug: .data.slug, domain: .data.domain, url: .data.url, domains: .data.domains, git: .data.git, deployment: .data.deployment }' echo "" log_info "Listing all domains..." local domains_response domains_response=$(api_call GET "/projects/$project_name/domains") if echo "$domains_response" | jq -e '.data.domains' > /dev/null 2>&1; then echo "$domains_response" | jq '.data.domains' fi } # Main case "${1:-}" in run) shift run_flow "${1:-landing-test}" "${2:-}" ;; teardown) shift teardown "${1:-landing-test}" ;; status) shift status "${1:-landing-test}" ;; *) echo "Usage: $0 {run|teardown|status} [project-name] [custom-subdomain]" echo "" echo "Commands:" echo " run [name] [subdomain] Create project and run full flow" echo " teardown [name] Delete project and clean up" echo " status [name] Check current project status" echo "" echo "Features tested:" echo " - Auto-generated random slug (8-char) for primary domain" echo " - Optional custom subdomain (e.g., 'my-app' -> my-app.threesix.ai)" echo " - Multi-domain listing via /projects/{id}/domains" echo " - DNS record creation and cleanup" echo "" echo "Environment:" echo " RDEV_API_URL API endpoint (default: https://rdev.masq-ops.orchard9.ai)" echo " RDEV_API_KEY API key (required)" echo "" echo "Examples:" echo " $0 run # Test with auto-slug only" echo " $0 run my-landing # Test with custom project name" echo " $0 run my-landing my-site # Also create my-site.threesix.ai" echo " $0 status my-landing # Check status and domains" echo " $0 teardown my-landing # Clean up (deletes all domains)" exit 1 ;; esac