354 lines
12 KiB
Bash
354 lines
12 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}"
|
|
API_USER="${API_USER:-brankol}"
|
|
API_PASSWORD="${API_PASSWORD:-branko_2025!}"
|
|
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"
|
|
|
|
# 9. device_list (New Test)
|
|
# based on name=devices_list
|
|
# &token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvYnN0ZXIiLCJleHAiOjE3NjQ3OTYwNzh9.t9rKVDRpSYOZGJMm2G0HYKSOOeaLypKwRGIJHehJBFE
|
|
# &user_id=32
|
|
# &user_name=robster
|
|
# &first=0
|
|
# &last=1000
|
|
# &privileges=-1
|
|
#
|
|
# robster test
|
|
device_list_payload=$(jq -n \
|
|
--arg fn "devices_list" \
|
|
--arg fid "0" \
|
|
--arg lid "1000" \
|
|
--arg priv "-1" \
|
|
--arg uid "32" \
|
|
--arg un "robster" \
|
|
--arg tk "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvYnN0ZXIiLCJleHAiOjE3NjQ3OTYwNzh9.t9rKVDRpSYOZGJMm2G0HYKSOOeaLypKwRGIJHehJBFE" \
|
|
'{function: $fn, name: $fn, user_id: $uid, user_name: $un, token: $tk, first: $fid, last: $lid, privileges: $priv}')
|
|
perform_test "devices_list" "$device_list_payload"
|
|
# brankol test
|
|
device_list_payload=$(jq -n \
|
|
--arg fn "devices_list" \
|
|
--arg fid "0" \
|
|
--arg lid "1000" \
|
|
--arg priv "-1" \
|
|
--arg un "$API_USER" \
|
|
--arg tk "$TOKEN" \
|
|
'{function: $fn, name: $fn, user_name: $un, token: $tk, first: $fid, last: $lid, privileges: $priv}')
|
|
# --arg uid "32" \
|
|
# --arg un "robster" \
|
|
# --arg tk "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvYnN0ZXIiLCJleHAiOjE3NjQ3OTYwNzh9.t9rKVDRpSYOZGJMm2G0HYKSOOeaLypKwRGIJHehJBFE" \
|
|
#'{name: $fn, user_id: $uid, user_name: $un, token: $tk, first: $fid, last: $lid, privileges: $priv}')
|
|
perform_test "devices_list" "$device_list_payload"
|
|
|
|
|
|
# device_list_payload=$(jq -n \
|
|
# --arg fn "devices_list" \
|
|
# --arg un "$API_USER" \
|
|
# --arg tk "$TOKEN" \
|
|
# --arg fid "0" \
|
|
# --arg lid "1000" \
|
|
# --arg priv "-1" \
|
|
# '{function: $fn, user_name: $un, token: $tk, first: $fid, last: $lid, privileges: $priv}')
|
|
# perform_test "devices_list" "$device_list_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
|
|
# ============================================================================== |