xpeditis2.0/apps/backend/test-csv-api.sh
2025-10-24 16:01:09 +02:00

300 lines
9.7 KiB
Bash

#!/bin/bash
# CSV Rate API Test Script
# This script tests all CSV rate endpoints
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
API_URL="http://localhost:4000"
TOKEN=""
ADMIN_TOKEN=""
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}CSV Rate API Test Script${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
# Function to print test header
print_test() {
echo -e "${YELLOW}[TEST $1] $2${NC}"
}
# Function to print success
print_success() {
echo -e "${GREEN}$1${NC}"
}
# Function to print error
print_error() {
echo -e "${RED}$1${NC}"
}
# Function to print info
print_info() {
echo -e "${BLUE}$1${NC}"
}
# Step 1: Get authentication token
print_test "1" "Authenticating as regular user"
LOGIN_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "test4@xpeditis.com",
"password": "SecurePassword123"
}')
TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.accessToken')
if [ "$TOKEN" != "null" ] && [ -n "$TOKEN" ]; then
print_success "Regular user authenticated"
print_info "Token: ${TOKEN:0:20}..."
else
print_error "Failed to authenticate regular user"
echo "Response: $LOGIN_RESPONSE"
exit 1
fi
echo ""
# Step 2: Test GET /rates/companies
print_test "2" "GET /rates/companies - Get available companies"
COMPANIES_RESPONSE=$(curl -s -X GET "$API_URL/api/v1/rates/companies" \
-H "Authorization: Bearer $TOKEN")
echo "$COMPANIES_RESPONSE" | jq '.'
COMPANIES_COUNT=$(echo $COMPANIES_RESPONSE | jq '.total')
if [ "$COMPANIES_COUNT" -eq 5 ]; then
print_success "Got 5 companies (including Test Maritime Express)"
else
print_error "Expected 5 companies, got $COMPANIES_COUNT"
fi
echo ""
# Step 3: Test GET /rates/filters/options
print_test "3" "GET /rates/filters/options - Get filter options"
FILTERS_RESPONSE=$(curl -s -X GET "$API_URL/api/v1/rates/filters/options" \
-H "Authorization: Bearer $TOKEN")
echo "$FILTERS_RESPONSE" | jq '.'
print_success "Filter options retrieved"
echo ""
# Step 4: Test POST /rates/search-csv - Basic search
print_test "4" "POST /rates/search-csv - Basic rate search (NLRTM → USNYC)"
SEARCH_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/rates/search-csv" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25.5,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL"
}')
echo "$SEARCH_RESPONSE" | jq '.'
TOTAL_RESULTS=$(echo $SEARCH_RESPONSE | jq '.totalResults')
print_info "Total results: $TOTAL_RESULTS"
# Check if Test Maritime Express is in results
HAS_TEST_MARITIME=$(echo $SEARCH_RESPONSE | jq '.results[] | select(.companyName == "Test Maritime Express") | .companyName' | wc -l)
if [ "$HAS_TEST_MARITIME" -gt 0 ]; then
print_success "Test Maritime Express found in results"
# Get Test Maritime Express price
TEST_PRICE=$(echo $SEARCH_RESPONSE | jq '.results[] | select(.companyName == "Test Maritime Express") | .totalPrice.amount' | head -1)
print_info "Test Maritime Express price: \$$TEST_PRICE"
else
print_error "Test Maritime Express NOT found in results"
fi
# Count unique companies in results
UNIQUE_COMPANIES=$(echo $SEARCH_RESPONSE | jq -r '.results[].companyName' | sort -u | wc -l)
print_info "Results from $UNIQUE_COMPANIES different companies"
if [ "$UNIQUE_COMPANIES" -ge 3 ]; then
print_success "Multiple companies in comparator ✓"
else
print_error "Expected multiple companies, got $UNIQUE_COMPANIES"
fi
echo ""
# Step 5: Test POST /rates/search-csv - Filter by company
print_test "5" "POST /rates/search-csv - Filter by Test Maritime Express only"
FILTER_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/rates/search-csv" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25.5,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL",
"filters": {
"companies": ["Test Maritime Express"]
}
}')
echo "$FILTER_RESPONSE" | jq '.results[0:3]'
FILTER_COMPANIES=$(echo $FILTER_RESPONSE | jq -r '.results[].companyName' | sort -u)
if [ "$FILTER_COMPANIES" == "Test Maritime Express" ]; then
print_success "Company filter working correctly"
else
print_error "Company filter not working - got: $FILTER_COMPANIES"
fi
echo ""
# Step 6: Test POST /rates/search-csv - Filter by price range
print_test "6" "POST /rates/search-csv - Filter by price range (\$900-\$1200)"
PRICE_FILTER_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/rates/search-csv" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25.5,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL",
"filters": {
"minPrice": 900,
"maxPrice": 1200,
"currency": "USD"
}
}')
PRICE_RESULTS=$(echo $PRICE_FILTER_RESPONSE | jq '.totalResults')
print_info "Results in price range \$900-\$1200: $PRICE_RESULTS"
# Verify all results are in range
MIN_PRICE=$(echo $PRICE_FILTER_RESPONSE | jq '[.results[].totalPrice.amount] | min')
MAX_PRICE=$(echo $PRICE_FILTER_RESPONSE | jq '[.results[].totalPrice.amount] | max')
if (( $(echo "$MIN_PRICE >= 900" | bc -l) )) && (( $(echo "$MAX_PRICE <= 1200" | bc -l) )); then
print_success "Price filter working correctly (range: \$$MIN_PRICE - \$$MAX_PRICE)"
else
print_error "Price filter not working - got range: \$$MIN_PRICE - \$$MAX_PRICE"
fi
echo ""
# Step 7: Test POST /rates/search-csv - Filter by transit days
print_test "7" "POST /rates/search-csv - Filter by max transit days (≤23 days)"
TRANSIT_FILTER_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/rates/search-csv" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25.5,
"weightKG": 3500,
"containerType": "LCL",
"filters": {
"maxTransitDays": 23
}
}')
TRANSIT_RESULTS=$(echo $TRANSIT_FILTER_RESPONSE | jq '.totalResults')
print_info "Results with transit ≤23 days: $TRANSIT_RESULTS"
MAX_TRANSIT=$(echo $TRANSIT_FILTER_RESPONSE | jq '[.results[].transitDays] | max')
if [ "$MAX_TRANSIT" -le 23 ]; then
print_success "Transit filter working correctly (max: $MAX_TRANSIT days)"
else
print_error "Transit filter not working - max transit: $MAX_TRANSIT days"
fi
echo ""
# Step 8: Test POST /rates/search-csv - Filter by surcharges
print_test "8" "POST /rates/search-csv - Filter for rates without surcharges (all-in prices)"
SURCHARGE_FILTER_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/rates/search-csv" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25.5,
"weightKG": 3500,
"containerType": "LCL",
"filters": {
"withoutSurcharges": true
}
}')
SURCHARGE_RESULTS=$(echo $SURCHARGE_FILTER_RESPONSE | jq '.totalResults')
print_info "Results without surcharges: $SURCHARGE_RESULTS"
# Verify all results have hasSurcharges=false
HAS_SURCHARGES=$(echo $SURCHARGE_FILTER_RESPONSE | jq '.results[] | select(.hasSurcharges == true)' | wc -l)
if [ "$HAS_SURCHARGES" -eq 0 ]; then
print_success "Surcharge filter working correctly"
else
print_error "Surcharge filter not working - found $HAS_SURCHARGES results with surcharges"
fi
echo ""
# Step 9: Comparison test - Show all companies for same route
print_test "9" "COMPARATOR TEST - Show all 5 companies for NLRTM → USNYC"
COMPARISON_RESPONSE=$(curl -s -X POST "$API_URL/api/v1/rates/search-csv" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL"
}')
echo "Company Comparison Table:"
echo "========================="
echo "$COMPARISON_RESPONSE" | jq -r '.results[] | "\(.companyName): $\(.totalPrice.amount) \(.totalPrice.currency) - \(.transitDays) days - Match: \(.matchScore)%"' | head -10
COMPANY_LIST=$(echo $COMPARISON_RESPONSE | jq -r '.results[].companyName' | sort -u)
print_info "Companies in results:"
echo "$COMPANY_LIST"
# Check if Test Maritime Express has lowest price
LOWEST_PRICE_COMPANY=$(echo $COMPARISON_RESPONSE | jq -r '[.results[] | {company: .companyName, price: .totalPrice.amount}] | sort_by(.price) | .[0].company')
if [ "$LOWEST_PRICE_COMPANY" == "Test Maritime Express" ]; then
print_success "Test Maritime Express has the lowest price ✓"
LOWEST_PRICE=$(echo $COMPARISON_RESPONSE | jq -r '[.results[]] | sort_by(.totalPrice.amount) | .[0].totalPrice.amount')
print_info "Lowest price: \$$LOWEST_PRICE (Test Maritime Express)"
else
print_error "Expected Test Maritime Express to have lowest price, but got: $LOWEST_PRICE_COMPANY"
fi
echo ""
echo -e "${BLUE}========================================${NC}"
echo -e "${GREEN}✓ All public endpoint tests completed!${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo "Next steps:"
echo "1. Run admin tests with an admin account"
echo "2. Test CSV upload functionality"
echo "3. Test CSV validation endpoint"
echo ""
echo "For admin tests, you need to:"
echo "1. Create an admin user or promote existing user to ADMIN role"
echo "2. Authenticate to get admin JWT token"
echo "3. Run admin endpoints (upload, validate, delete)"