well-api/test_welldrysense_api.sh
2025-12-13 12:21:31 -08:00

305 lines
9.7 KiB
Bash

#!/bin/bash
# ==============================================================================
# WellDrySense API Test Suite (Bash Version)
# Functionality: Exercises Job APIs including Create, List, Edit, Details, Weather,
# Sensor Data, and performs Database Cleanup.
# ==============================================================================
# --- Configuration ---
# Load .env file if it exists
if [ -f .env ]; then
export $(cat .env | xargs)
fi
# Defaults (can be overridden by env vars)
PORT="${PORT:-8002}"
BASE_URL="http://localhost:$PORT/api/well_api"
API_USER="${API_USER:-jpeters}"
API_PASSWORD="${API_PASSWORD:-WellJson}"
DB_NAME="${DB_NAME:-wellnuo}"
DB_USER="${DB_USER:-postgres}"
DB_HOST="${DB_HOST:-localhost}"
DB_PORT="${DB_PORT:-5432}"
# DB_PASSWORD should be set in .env or exported
# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Global Variables
TOKEN=""
USER_ID=""
JOB_ID=""
# Check for jq
if ! command -v jq &> /dev/null; then
echo -e "${RED}Error: 'jq' is not installed. Please install it to run this script.${NC}"
exit 1
fi
echo -e "${BLUE}=== Setting up WellDrySense Test Suite on Port $PORT ===${NC}"
# ==============================================================================
# Helper Functions
# ==============================================================================
# Function to print section headers
print_header() {
echo -e "\n${BLUE}----------------------------------------------------------------${NC}"
echo -e "${BLUE}[Test] $1${NC}"
}
# Function to perform a POST request
# Usage: perform_test "Test Name" "JSON_PAYLOAD_STRING"
perform_test() {
local test_name="$1"
local json_payload="$2"
print_header "$test_name"
# 1. Print Request
echo "# Request:"
echo "$json_payload" | jq '.'
# 2. Convert JSON to Form Data for curl (flattening simple objects)
# Note: This simple conversion handles top-level keys.
# Complex nested JSON strings (like 'devices') need to be passed as strings in the input JSON.
local form_data=""
# Extract keys and values and build form string
while IFS="=" read -r key value; do
if [ -n "$key" ]; then
# URL encode the value
encoded_value=$(printf '%s' "$value" | jq -sRr @uri)
if [ -z "$form_data" ]; then
form_data="${key}=${encoded_value}"
else
form_data="${form_data}&${key}=${encoded_value}"
fi
fi
done < <(echo "$json_payload" | jq -r "to_entries|map(\"\(.key)=\(.value)\")|.[]")
# 3. Execute Request
response=$(curl -s -X POST "$BASE_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "$form_data")
# 4. Print Response
echo -e "\n# Response:"
if [ -z "$response" ]; then
echo "(Empty Response)"
echo -e "${RED}FAIL${NC}"
return 1
else
echo "$response" | jq '.' 2>/dev/null || echo "$response"
fi
# 5. Evaluate Pass/Fail based on "ok": 1
ok_val=$(echo "$response" | jq -r '.ok // .status // 0')
# Handle different response structures (some return {status: 200}, some {ok: 1})
if [ "$ok_val" == "1" ] || [ "$ok_val" == "200" ] || [ "$ok_val" == "success" ]; then
echo -e "${GREEN}PASS${NC}"
# Extract Job ID if this was the create step
if [ "$test_name" == "job_create" ]; then
JOB_ID=$(echo "$response" | jq -r '.job_id')
echo "-> Captured Job ID: $JOB_ID"
fi
return 0
else
error_msg=$(echo "$response" | jq -r '.error // .message // "Unknown error"')
echo -e "${RED}FAIL: $error_msg${NC}"
return 1
fi
}
# ==============================================================================
# Test Execution
# ==============================================================================
# 1. Login / Credentials
# ----------------------
login_payload=$(jq -n \
--arg fn "credentials" \
--arg un "$API_USER" \
--arg ps "$API_PASSWORD" \
--arg cid "bash-suite" \
--arg nonce "test-nonce" \
'{function: $fn, user_name: $un, ps: $ps, clientId: $cid, nonce: $nonce}')
print_header "Login"
echo "# Request:"
echo "$login_payload" | jq '.'
# Special handling for login to capture token
response=$(curl -s -X POST "$BASE_URL" -d "function=credentials&user_name=$API_USER&ps=$API_PASSWORD&clientId=bash-suite&nonce=test-nonce")
echo -e "\n# Response:"
echo "$response" | jq '.'
TOKEN=$(echo "$response" | jq -r '.access_token // .data.access_token')
USER_ID=$(echo "$response" | jq -r '.user_id // .data.user_id')
if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then
echo -e "${GREEN}PASS${NC} (User ID: $USER_ID)"
else
echo -e "${RED}FATAL: Login failed. Check credentials.${NC}"
exit 1
fi
# 2. Create Job
# ----------------------
# Note: We pass JSON strings for complex fields like 'devices' and 'alerts_config'
devices_json='[{"mac": "TEST_MAC_VIRTUAL", "location": "Lab"}]'
alerts_json='{"temp_high": 30}'
create_payload=$(jq -n \
--arg fn "job_create" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
--arg cn "TEST_SUITE_CUSTOMER_BASH" \
--arg as "123 Bash Script Ln" \
--arg ac "Shellville" \
--arg dev "$devices_json" \
--arg lat "34.05" \
--arg lng "-118.25" \
'{function: $fn, user_name: $un, token: $tk, customer_name: $cn, address_street: $as, address_city: $ac, devices: $dev, lat: $lat, lng: $lng}')
perform_test "job_create" "$create_payload" || exit 1
# 3. Job List
# ----------------------
list_payload=$(jq -n \
--arg fn "job_list" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
'{function: $fn, user_name: $un, token: $tk}')
perform_test "job_list" "$list_payload"
# 3. Job List 2 (with added search)
# ----------------------
list_payload=$(jq -n \
--arg fn "job_list2" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
--arg sch "" \
'{function: $fn, user_name: $un, token: $tk, search: $sch}')
perform_test "job_list2" "$list_payload"
# 4. Job Details
# ----------------------
details_payload=$(jq -n \
--arg fn "job_details" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
--arg jid "$JOB_ID" \
'{function: $fn, user_name: $un, token: $tk, job_id: $jid}')
perform_test "job_details" "$details_payload"
# 5. Job Edit (Stop Job)
# ----------------------
edit_payload=$(jq -n \
--arg fn "job_edit" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
--arg jid "$JOB_ID" \
--arg st "Stopped" \
--arg dt "2025-12-31T23:59:59" \
'{function: $fn, user_name: $un, token: $tk, job_id: $jid, job_status: $st, date_to: $dt}')
perform_test "job_edit" "$edit_payload"
# 6. Available Devices (two versions, with direct SQL and via GetProximityList)
# ----------------------
avail_payload=$(jq -n \
--arg fn "job_available_devices" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
'{function: $fn, user_name: $un, token: $tk}')
perform_test "job_available_devices" "$avail_payload"
# 6. Available Devices (Alternative Test using job_available_devices2, which is using GetProximityList)
avail_payload=$(jq -n \
--arg fn "job_available_devices2" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
'{function: $fn, user_name: $un, token: $tk}')
perform_test "job_available_devices2" "$avail_payload"
# 6. Available Devices(made reusing job_user_all_devices2, adding filter and search)
avail_payload=$(jq -n \
--arg fn "job_devices" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
--arg fl "all" \
--arg sch "" \
'{function: $fn, user_name: $un, token: $tk, filter: $fl, search: $sch}')
perform_test "job_devices" "$avail_payload"
# 7. Job Weather
# ----------------------
weather_payload=$(jq -n \
--arg fn "job_weather" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
--arg jid "$JOB_ID" \
'{function: $fn, user_name: $un, token: $tk, job_id: $jid}')
perform_test "job_weather" "$weather_payload"
# 8. Job Sensor Bucketed Data (New Test)
# ----------------------
# Using dynamic dates for the test
DATE_FROM=$(date +%Y-%m-%d)
DATE_TO=$(date +%Y-%m-%d)
sensor_payload=$(jq -n \
--arg fn "get_job_sensor_bucketed_data" \
--arg un "$API_USER" \
--arg tk "$TOKEN" \
--arg jid "$JOB_ID" \
--arg sens "temperature" \
--arg dt "$DATE_FROM" \
--arg dtt "$DATE_TO" \
--arg bs "15m" \
'{function: $fn, user_name: $un, token: $tk, job_id: $jid, sensor: $sens, date: $dt, to_date: $dtt, bucket_size: $bs}')
perform_test "get_job_sensor_bucketed_data" "$sensor_payload"
# ==============================================================================
# Cleanup
# ==============================================================================
print_header "Cleanup"
if [ -n "$JOB_ID" ]; then
echo "-> Deleting Job ID: $JOB_ID from database..."
# Use PGPASSWORD for non-interactive auth if set
export PGPASSWORD="${DB_PASSWORD}"
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "DELETE FROM public.jobs WHERE job_id = $JOB_ID;" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo -e "${GREEN}Cleanup successful. Database restored.${NC}"
else
echo -e "${RED}Cleanup failed. Please manually delete job_id $JOB_ID from public.jobs.${NC}"
echo "Command attempted: psql -h $DB_HOST -U $DB_USER -d $DB_NAME -c \"DELETE FROM public.jobs WHERE job_id = $JOB_ID;\""
fi
else
echo "No Job ID created, skipping cleanup."
fi
echo -e "\n${BLUE}=== Test Suite Finished ===${NC}"
# ==============================================================================
# well-api.py modifications to support WellDrySense API on port 1998
# ==============================================================================