261 lines
7.7 KiB
Bash
Executable File
261 lines
7.7 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Test script for universal storage API with presigned URL support
|
|
# Tests both the "backend decides" approach for S3 and local storage
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
source "$SCRIPT_DIR/../test-config.sh"
|
|
API_URL="${TEST_API_BASE%/api}"
|
|
BUCKET_NAME="test-universal-bucket"
|
|
TEST_FILE="test-upload.txt"
|
|
|
|
# Colors for output
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
echo "=== Universal Storage API Test ==="
|
|
echo ""
|
|
|
|
# Create test file
|
|
echo "This is a test file for universal storage upload" > $TEST_FILE
|
|
FILE_SIZE=$(stat -f%z "$TEST_FILE" 2>/dev/null || stat -c%s "$TEST_FILE" 2>/dev/null)
|
|
|
|
# Step 1: Login to get auth token
|
|
echo "1. Logging in..."
|
|
LOGIN_PAYLOAD=$(build_admin_login_payload "$TEST_ADMIN_USERNAME" "$TEST_ADMIN_PASSWORD")
|
|
LOGIN_RESPONSE=$(curl -s -X POST "$API_URL/api/auth/admin/sessions" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "$LOGIN_PAYLOAD")
|
|
|
|
TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.accessToken')
|
|
if [ "$TOKEN" == "null" ] || [ -z "$TOKEN" ]; then
|
|
echo -e "${RED}✗ Failed to login${NC}"
|
|
echo $LOGIN_RESPONSE | jq .
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN}✓ Logged in successfully${NC}"
|
|
|
|
# Step 2: Create bucket
|
|
echo ""
|
|
echo "2. Creating bucket '$BUCKET_NAME'..."
|
|
CREATE_RESPONSE=$(curl -s -X POST $API_URL/api/storage/buckets \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "{
|
|
\"bucketName\": \"$BUCKET_NAME\",
|
|
\"isPublic\": true
|
|
}")
|
|
|
|
echo $CREATE_RESPONSE | jq .
|
|
|
|
# Step 3: Request upload strategy
|
|
echo ""
|
|
echo "3. Requesting upload strategy (backend decides)..."
|
|
UPLOAD_STRATEGY=$(curl -s -X POST $API_URL/api/storage/buckets/$BUCKET_NAME/upload-strategy \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "{
|
|
\"filename\": \"$TEST_FILE\",
|
|
\"contentType\": \"text/plain\",
|
|
\"size\": $FILE_SIZE
|
|
}")
|
|
|
|
echo -e "${YELLOW}Upload Strategy Response:${NC}"
|
|
echo $UPLOAD_STRATEGY | jq .
|
|
|
|
# Extract strategy details
|
|
METHOD=$(echo $UPLOAD_STRATEGY | jq -r '.method')
|
|
UPLOAD_URL=$(echo $UPLOAD_STRATEGY | jq -r '.uploadUrl')
|
|
KEY=$(echo $UPLOAD_STRATEGY | jq -r '.key')
|
|
CONFIRM_REQUIRED=$(echo $UPLOAD_STRATEGY | jq -r '.confirmRequired')
|
|
|
|
if [ "$METHOD" == "null" ] || [ -z "$METHOD" ]; then
|
|
echo -e "${RED}✗ Failed to get upload strategy${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}✓ Got upload strategy:${NC}"
|
|
echo " - Method: $METHOD"
|
|
echo " - Upload URL: $UPLOAD_URL"
|
|
echo " - Key: $KEY"
|
|
echo " - Confirm Required: $CONFIRM_REQUIRED"
|
|
|
|
# Step 4: Upload based on strategy
|
|
echo ""
|
|
echo "4. Uploading file using $METHOD method..."
|
|
|
|
if [ "$METHOD" == "presigned" ]; then
|
|
echo "Using presigned URL upload (S3)..."
|
|
|
|
# Build multipart form data with fields from strategy
|
|
FIELDS=$(echo $UPLOAD_STRATEGY | jq -r '.fields')
|
|
FORM_FIELDS=""
|
|
|
|
if [ "$FIELDS" != "null" ] && [ "$FIELDS" != "{}" ]; then
|
|
for field in $(echo $FIELDS | jq -r 'to_entries[] | @base64'); do
|
|
_jq() {
|
|
echo ${field} | base64 --decode | jq -r ${1}
|
|
}
|
|
FIELD_NAME=$(_jq '.key')
|
|
FIELD_VALUE=$(_jq '.value')
|
|
FORM_FIELDS="$FORM_FIELDS -F $FIELD_NAME=$FIELD_VALUE"
|
|
done
|
|
fi
|
|
|
|
# Upload to S3
|
|
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST $UPLOAD_URL \
|
|
$FORM_FIELDS \
|
|
-F "file=@$TEST_FILE")
|
|
|
|
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -n1)
|
|
|
|
if [ "$HTTP_CODE" -ge "200" ] && [ "$HTTP_CODE" -lt "300" ]; then
|
|
echo -e "${GREEN}✓ File uploaded to S3 (HTTP $HTTP_CODE)${NC}"
|
|
else
|
|
echo -e "${RED}✗ S3 upload failed (HTTP $HTTP_CODE)${NC}"
|
|
echo "Response: $(echo "$UPLOAD_RESPONSE" | head -n-1)"
|
|
fi
|
|
|
|
elif [ "$METHOD" == "direct" ]; then
|
|
echo "Using direct upload (Local Storage)..."
|
|
|
|
# For local storage, upload directly to backend
|
|
if [[ "$UPLOAD_URL" == /* ]]; then
|
|
# Relative URL, prepend API_URL
|
|
FULL_URL="${API_URL}${UPLOAD_URL}"
|
|
else
|
|
FULL_URL="$UPLOAD_URL"
|
|
fi
|
|
|
|
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" -X PUT "$FULL_URL" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-F "file=@$TEST_FILE")
|
|
|
|
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -n1)
|
|
|
|
if [ "$HTTP_CODE" -ge "200" ] && [ "$HTTP_CODE" -lt "300" ]; then
|
|
echo -e "${GREEN}✓ File uploaded directly to backend (HTTP $HTTP_CODE)${NC}"
|
|
else
|
|
echo -e "${RED}✗ Direct upload failed (HTTP $HTTP_CODE)${NC}"
|
|
echo "Response: $(echo "$UPLOAD_RESPONSE" | head -n-1)"
|
|
fi
|
|
else
|
|
echo -e "${RED}✗ Unknown upload method: $METHOD${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 5: Confirm upload if required
|
|
if [ "$CONFIRM_REQUIRED" == "true" ]; then
|
|
echo ""
|
|
echo "5. Confirming upload..."
|
|
|
|
CONFIRM_RESPONSE=$(curl -s -X POST $API_URL/api/storage/buckets/$BUCKET_NAME/objects/$KEY/confirm-upload \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "{
|
|
\"size\": $FILE_SIZE,
|
|
\"contentType\": \"text/plain\"
|
|
}")
|
|
|
|
echo -e "${YELLOW}Confirmation Response:${NC}"
|
|
echo $CONFIRM_RESPONSE | jq .
|
|
|
|
CONFIRM_KEY=$(echo $CONFIRM_RESPONSE | jq -r '.key')
|
|
if [ "$CONFIRM_KEY" == "$KEY" ]; then
|
|
echo -e "${GREEN}✓ Upload confirmed successfully${NC}"
|
|
else
|
|
echo -e "${RED}✗ Upload confirmation failed${NC}"
|
|
fi
|
|
else
|
|
echo ""
|
|
echo "5. No confirmation required for $METHOD upload"
|
|
fi
|
|
|
|
# Step 6: Get download URL
|
|
echo ""
|
|
echo "6. Getting download URL..."
|
|
DOWNLOAD_STRATEGY=$(curl -s "${API_URL}/api/storage/buckets/${BUCKET_NAME}/download-strategy/objects/${KEY}" \
|
|
-H "Authorization: Bearer $TOKEN")
|
|
|
|
echo -e "${YELLOW}Download Strategy Response:${NC}"
|
|
echo $DOWNLOAD_STRATEGY | jq .
|
|
|
|
DOWNLOAD_METHOD=$(echo $DOWNLOAD_STRATEGY | jq -r '.method')
|
|
DOWNLOAD_URL=$(echo $DOWNLOAD_STRATEGY | jq -r '.url')
|
|
EXPIRES_AT=$(echo $DOWNLOAD_STRATEGY | jq -r '.expiresAt')
|
|
|
|
echo ""
|
|
echo -e "${GREEN}✓ Got download strategy:${NC}"
|
|
echo " - Method: $DOWNLOAD_METHOD"
|
|
echo " - URL: $DOWNLOAD_URL"
|
|
if [ "$EXPIRES_AT" != "null" ]; then
|
|
echo " - Expires: $EXPIRES_AT"
|
|
fi
|
|
|
|
# Step 7: Test download
|
|
echo ""
|
|
echo "7. Testing download..."
|
|
|
|
if [ "$DOWNLOAD_METHOD" == "presigned" ]; then
|
|
# Direct download from S3 with presigned URL
|
|
curl -s -o downloaded-$TEST_FILE "$DOWNLOAD_URL"
|
|
elif [ "$DOWNLOAD_METHOD" == "direct" ]; then
|
|
# Download from backend
|
|
if [[ "$DOWNLOAD_URL" == /* ]]; then
|
|
FULL_DOWNLOAD_URL="${API_URL}${DOWNLOAD_URL}"
|
|
else
|
|
FULL_DOWNLOAD_URL="$DOWNLOAD_URL"
|
|
fi
|
|
|
|
curl -s -o downloaded-$TEST_FILE "$FULL_DOWNLOAD_URL" \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
fi
|
|
|
|
if cmp -s "$TEST_FILE" "downloaded-$TEST_FILE"; then
|
|
echo -e "${GREEN}✓ Downloaded file matches original${NC}"
|
|
else
|
|
echo -e "${RED}✗ Downloaded file doesn't match${NC}"
|
|
fi
|
|
|
|
# Step 8: List objects
|
|
echo ""
|
|
echo "8. Listing objects in bucket..."
|
|
LIST_RESPONSE=$(curl -s $API_URL/api/storage/buckets/$BUCKET_NAME/objects \
|
|
-H "Authorization: Bearer $TOKEN")
|
|
|
|
OBJECT_COUNT=$(echo $LIST_RESPONSE | jq '.objects | length')
|
|
echo -e "${GREEN}✓ Found $OBJECT_COUNT object(s) in bucket${NC}"
|
|
|
|
# Cleanup
|
|
echo ""
|
|
echo "9. Cleaning up..."
|
|
|
|
# Delete the uploaded object
|
|
DELETE_RESPONSE=$(curl -s -X DELETE $API_URL/api/storage/buckets/$BUCKET_NAME/objects/$KEY \
|
|
-H "Authorization: Bearer $TOKEN")
|
|
echo " - Deleted object: $KEY"
|
|
|
|
# Delete the bucket
|
|
DELETE_BUCKET_RESPONSE=$(curl -s -X DELETE $API_URL/api/storage/buckets/$BUCKET_NAME \
|
|
-H "Authorization: Bearer $TOKEN")
|
|
echo " - Deleted bucket: $BUCKET_NAME"
|
|
|
|
# Remove test files
|
|
rm -f $TEST_FILE downloaded-$TEST_FILE
|
|
|
|
echo ""
|
|
echo "=== Test Complete ==="
|
|
echo ""
|
|
echo -e "${YELLOW}Summary:${NC}"
|
|
echo "- The backend successfully returned upload/download strategies"
|
|
echo "- Upload method was: $METHOD"
|
|
echo "- Download method was: $DOWNLOAD_METHOD"
|
|
echo "- For S3: Uses presigned URLs (direct to S3)"
|
|
echo "- For Local: Uses direct upload to backend"
|
|
echo "- The SDK can use the same code for both backends!"
|