Files
jeremy 5688b30892 fix: migrate PaperMC to v3 API, fix NeoForge beta fallback, add test suite
- Migrate Paper loader from sunset v2 API to v3 (fill.papermc.io)
- Fix NeoForge: fall back to beta versions when no stable exists (set -e + grep)
- Fix setEula/setperms ordering (was writing eula.txt before /data was writable)
- Fix setEula/serverInfoWrite to use absolute paths (/data/server/)
- Add VOLUME directive removal (was shadowing bind mounts)
- Add comprehensive API test suite (110 tests across 6 suites)
- Move test.sh to tests/integration.sh, switch to named volumes
- Add Docker build cache to CI workflows
- Add .editorconfig, expand .gitignore, improve README docs
2026-08-21 12:49:27 -04:00

253 lines
8.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Tests for Bedrock Dedicated Server download API
# Covers: Primary API, fallback API, version parsing
# Usage: ./tests/test_bedrock.sh
source "$(dirname "$0")/test_utils.sh"
echo -e "\n${BOLD}Bedrock API Tests${NC}"
echo ""
BEDROCK_API_URL="https://net.web.minecraft-services.net/api/v1.0/download/links"
BEDROCK_FALLBACK_URL="https://raw.githubusercontent.com/kittizz/bedrock-server-downloads/refs/heads/main/bedrock-server-downloads.json"
# ---------- Primary API (minecraft-services.net) ---------------------------
test_bedrock_primary_api_reachable() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
assert_not_empty "$body" "Bedrock primary API body should not be empty"
}
test_bedrock_primary_api_is_json() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
assert_json_valid "$body" "Primary API response should be valid JSON"
}
test_bedrock_primary_api_has_result() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
assert_json_field "$body" '.result' "Should have .result field"
}
test_bedrock_primary_api_has_links() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
assert_json_field "$body" '.result.links' "Should have .result.links array"
}
test_bedrock_primary_api_links_is_array() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
local type
type=$(echo "$body" | jq -r '.result.links | type')
assert_equals "$type" "array" ".result.links should be an array"
}
test_bedrock_primary_has_linux_entry() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
local found
found=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
if [[ -n "$found" && "$found" != "null" ]]; then
return 0
else
echo "ASSERT FAILED: No serverBedrockLinux entry found"
return 1
fi
}
test_bedrock_primary_linux_url_format() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
local url
url=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
assert_matches "$url" "bedrock-server-.*\.zip$" \
"Linux download URL should end with bedrock-server-{version}.zip"
}
test_bedrock_primary_linux_url_reachable() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
local url
url=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
if [[ -z "$url" ]]; then
echo "No Linux download URL found"
return 1
fi
# Just check HTTP HEAD to avoid downloading the full zip
local http_code
http_code=$(curl -sL -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 30 \
-A "Mozilla/5.0 (X11; Linux x86_64)" -I "$url") || true
assert_equals "$http_code" "200" "Bedrock download URL should return HTTP 200"
}
test_bedrock_primary_has_windows_entry() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
local found
found=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockWin") | .downloadUrl // empty')
if [[ -n "$found" && "$found" != "null" ]]; then
return 0
else
echo "No serverBedrockWin entry found (may be expected on some API versions)"
return 77 # skip
fi
}
test_bedrock_primary_download_type_values() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
local types
types=$(echo "$body" | jq -r '.result.links[].downloadType' | sort -u)
assert_not_empty "$types" "Should have at least one download type"
}
# ---------- Version parsing from URL ---------------------------------------
test_bedrock_version_from_url() {
local body
body=$(api_get_ua "$BEDROCK_API_URL")
local url
url=$(echo "$body" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl // empty')
if [[ -z "$url" ]]; then
echo "No Linux download URL found"
return 1
fi
# Extract version from URL (same regex as bedrock.sh)
local ver
ver=$(echo "$url" | grep -oP 'bedrock-server-\K[\d.]+(?=\.zip)')
assert_not_empty "$ver" "Should extract version from URL"
assert_matches "$ver" "^[0-9]+\.[0-9]+\.[0-9]+" \
"Version '${ver}' should look like x.y.z"
}
# ---------- Fallback API (GitHub) ------------------------------------------
test_bedrock_fallback_api_reachable() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
assert_not_empty "$body" "Bedrock fallback API body should not be empty"
}
test_bedrock_fallback_api_is_json() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
assert_json_valid "$body" "Fallback API response should be valid JSON"
}
test_bedrock_fallback_has_release() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
assert_json_field "$body" '.release' "Should have .release field"
}
test_bedrock_fallback_release_is_object() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
local type
type=$(echo "$body" | jq -r '.release | type')
assert_equals "$type" "object" ".release should be a JSON object"
}
test_bedrock_fallback_release_has_entries() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
local count
count=$(echo "$body" | jq '.release | length')
if [[ "$count" -gt 0 ]]; then
return 0
else
echo "ASSERT FAILED: .release should have entries, got ${count}"
return 1
fi
}
test_bedrock_fallback_entry_has_linux_url() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
local first_key
first_key=$(echo "$body" | jq -r '.release | keys | .[0]')
local url
url=$(echo "$body" | jq -r ".release[\"${first_key}\"].linux.url // empty")
assert_not_empty "$url" "First release entry should have .linux.url"
}
test_bedrock_fallback_linux_url_format() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
local first_key
first_key=$(echo "$body" | jq -r '.release | keys | .[0]')
local url
url=$(echo "$body" | jq -r ".release[\"${first_key}\"].linux.url // empty")
assert_matches "$url" "bedrock-server-.*\.zip$" \
"Fallback URL should end with bedrock-server-{version}.zip"
}
test_bedrock_fallback_highest_version() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
# The script sorts by version and takes the last (highest) entry
local highest
highest=$(echo "$body" | jq -r '
.release | to_entries | sort_by(.key | split(".") | map(tonumber)) | last | .key
')
assert_not_empty "$highest" "Should find a highest version"
assert_matches "$highest" "^[0-9]+\.[0-9]+\.[0-9]+" \
"Highest version '${highest}' should look like x.y.z"
}
# ---------- Preview entry --------------------------------------------------
test_bedrock_fallback_has_preview() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
assert_json_field "$body" '.preview' "Should have .preview field"
}
test_bedrock_fallback_preview_is_object() {
local body
body=$(api_get "$BEDROCK_FALLBACK_URL")
local type
type=$(echo "$body" | jq -r '.preview | type')
assert_equals "$type" "object" ".preview should be a JSON object"
}
# ---------- Run all tests --------------------------------------------------
run_test "Primary API is reachable" test_bedrock_primary_api_reachable
run_test "Primary API response is valid JSON" test_bedrock_primary_api_is_json
run_test "Primary API has .result field" test_bedrock_primary_api_has_result
run_test "Primary API has .result.links" test_bedrock_primary_api_has_links
run_test ".result.links is an array" test_bedrock_primary_api_links_is_array
run_test "Has serverBedrockLinux entry" test_bedrock_primary_has_linux_entry
run_test "Linux download URL has correct format" test_bedrock_primary_linux_url_format
run_test "Linux download URL returns HTTP 200" test_bedrock_primary_linux_url_reachable
run_test "Has serverBedrockWin entry" test_bedrock_primary_has_windows_entry
run_test "Download types are present" test_bedrock_primary_download_type_values
run_test "Version can be parsed from download URL" test_bedrock_version_from_url
run_test "Fallback API (GitHub) is reachable" test_bedrock_fallback_api_reachable
run_test "Fallback API response is valid JSON" test_bedrock_fallback_api_is_json
run_test "Fallback has .release field" test_bedrock_fallback_has_release
run_test ".release is a JSON object" test_bedrock_fallback_release_is_object
run_test ".release has entries" test_bedrock_fallback_release_has_entries
run_test "First release entry has .linux.url" test_bedrock_fallback_entry_has_linux_url
run_test "Fallback URL has correct format" test_bedrock_fallback_linux_url_format
run_test "Fallback has a highest version" test_bedrock_fallback_highest_version
run_test "Fallback has .preview field" test_bedrock_fallback_has_preview
run_test ".preview is a JSON object" test_bedrock_fallback_preview_is_object
print_summary