Files
dockercraft/tests/test_forge.sh
T
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

237 lines
8.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Tests for Minecraft Forge API
# Covers: Forge promotions API, version resolution, download URL, old/new forge logic
# Usage: ./tests/test_forge.sh [mc_version]
source "$(dirname "$0")/test_utils.sh"
MC_VERSION="${1:-$(get_latest_mc_version)}"
if [[ -z "$MC_VERSION" ]]; then
echo "Could not determine MC version"
exit 1
fi
echo -e "\n${BOLD}Forge API Tests (MC ${MC_VERSION})${NC}"
echo ""
# ---------- Forge promotions API -------------------------------------------
test_forge_promotions_reachable() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
assert_not_empty "$body" "Promotions body should not be empty"
assert_json_valid "$body" "Promotions should be valid JSON"
}
test_forge_promotions_has_promos() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
assert_json_field "$body" '.promos' "Should have .promos field"
}
test_forge_promos_is_object() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local type
type=$(echo "$body" | jq -r '.promos | type')
assert_equals "$type" "object" ".promos should be a JSON object"
}
test_forge_promos_has_known_key() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local known_key="1.20.4-latest"
local found
found=$(echo "$body" | jq -r ".promos[\"${known_key}\"] // empty")
if [[ -n "$found" && "$found" != "null" ]]; then
return 0
else
echo "ASSERT FAILED: promos should have '1.20.4-latest' key"
return 1
fi
}
test_forge_promos_value_format() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local known_key="1.20.4-latest"
local version
version=$(echo "$body" | jq -r ".promos[\"${known_key}\"] // empty")
# Forge versions look like "20.4.234" or "14.23.5.2860"
assert_matches "$version" "^[0-9]+\.[0-9]+\.[0-9]+" \
"Forge version '${version}' should look like x.y.z"
}
# ---------- Forge download URL construction --------------------------------
test_forge_download_url_format() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local version
version=$(echo "$body" | jq -r '.promos["1.20.4-latest"] // empty')
if [[ -z "$version" ]]; then
echo "Could not determine Forge version for 1.20.4"
return 1
fi
local expected_url="https://maven.minecraftforge.net/net/minecraftforge/forge/1.20.4-${version}/forge-1.20.4-${version}-installer.jar"
assert_not_empty "$expected_url" "Download URL should not be empty"
assert_matches "$expected_url" "maven.minecraftforge.net.*installer\.jar" \
"URL should point to Forge maven installer"
}
test_forge_download_url_reachable() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local version
version=$(echo "$body" | jq -r '.promos["1.20.4-latest"] // empty')
if [[ -z "$version" ]]; then
echo "Could not determine Forge version for 1.20.4"
return 1
fi
local url="https://maven.minecraftforge.net/net/minecraftforge/forge/1.20.4-${version}/forge-1.20.4-${version}-installer.jar"
assert_http_ok "$url" "Forge installer URL should return HTTP 200"
}
# ---------- Old vs New Forge version logic ---------------------------------
# Forge >= 1.17.1 uses the new launcher (unix_args.txt)
# Forge < 1.17.1 uses the old launcher (server.jar symlink)
test_forge_new_version_boundary() {
# This replicates the logic from common.sh newForge()
local test_version="1.17.1"
local result
result=$(printf '%s\n' "1.17.1" "$test_version" | sort -V | head -n1)
assert_equals "$result" "1.17.1" "1.17.1 >= 1.17.1 (boundary case)"
}
test_forge_old_version_is_old() {
local test_version="1.16.5"
local result
result=$(printf '%s\n' "1.17.1" "$test_version" | sort -V | head -n1)
# When sort -V puts test_version first, it's < 1.17.1
assert_equals "$result" "$test_version" "1.16.5 < 1.17.1 (old forge)"
}
test_forge_new_version_is_new() {
local test_version="1.20.4"
local result
result=$(printf '%s\n' "1.17.1" "$test_version" | sort -V | head -n1)
# When sort -V puts 1.17.1 first, test_version is >= 1.17.1
assert_equals "$result" "1.17.1" "1.20.4 >= 1.17.1 (new forge)"
}
test_forge_1_17_exactly_is_old() {
local test_version="1.17"
local result
result=$(printf '%s\n' "1.17.1" "$test_version" | sort -V | head -n1)
# 1.17 < 1.17.1
assert_equals "$result" "$test_version" "1.17 < 1.17.1 (old forge, edge case)"
}
test_forge_1_18_is_new() {
local test_version="1.18"
local result
result=$(printf '%s\n' "1.17.1" "$test_version" | sort -V | head -n1)
assert_equals "$result" "1.17.1" "1.18 >= 1.17.1 (new forge)"
}
test_forge_1_21_is_new() {
local test_version="1.21.1"
local result
result=$(printf '%s\n' "1.17.1" "$test_version" | sort -V | head -n1)
assert_equals "$result" "1.17.1" "1.21.1 >= 1.17.1 (new forge)"
}
# ---------- Forge Maven metadata -------------------------------------------
test_forge_maven_metadata_reachable() {
local body
body=$(api_get "https://maven.minecraftforge.net/net/minecraftforge/forge/maven-metadata.xml")
assert_not_empty "$body" "Forge maven metadata should be reachable"
}
test_forge_maven_metadata_is_xml() {
local body
body=$(api_get "https://maven.minecraftforge.net/net/minecraftforge/forge/maven-metadata.xml")
assert_contains "$body" "<metadata>" "Should be valid XML"
}
test_forge_maven_has_versions() {
local body
body=$(api_get "https://maven.minecraftforge.net/net/minecraftforge/forge/maven-metadata.xml")
assert_contains "$body" "<versions>" "Should have <versions> element"
}
# ---------- Forge version resolution for specific MC versions --------------
test_forge_supports_1_20_4() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local version
version=$(echo "$body" | jq -r '.promos["1.20.4-latest"] // empty')
assert_not_empty "$version" "Forge should support MC 1.20.4"
}
test_forge_supports_1_19_2() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local version
version=$(echo "$body" | jq -r '.promos["1.19.2-latest"] // empty')
assert_not_empty "$version" "Forge should support MC 1.19.2"
}
test_forge_supports_1_12_2() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local version
version=$(echo "$body" | jq -r '.promos["1.12.2-latest"] // empty')
assert_not_empty "$version" "Forge should support MC 1.12.2 (classic version)"
}
test_forge_latest_matches_current_mc() {
local body
body=$(api_get "https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json")
local version
version=$(echo "$body" | jq -r ".promos[\"${MC_VERSION}-latest\"] // empty")
# This may not exist for all MC versions, so we treat it as informational
if [[ -n "$version" && "$version" != "null" ]]; then
echo "Forge ${MC_VERSION}-latest = ${version}"
return 0
else
echo "No forge ${MC_VERSION}-latest in promos (may be expected)"
return 77 # skip
fi
}
# ---------- Run all tests --------------------------------------------------
run_test "Forge promotions API is reachable" test_forge_promotions_reachable
run_test "Promotions JSON has .promos field" test_forge_promotions_has_promos
run_test ".promos is a JSON object" test_forge_promos_is_object
run_test "Promos has '1.20.4-latest' key" test_forge_promos_has_known_key
run_test "Promos value has Forge version format" test_forge_promos_value_format
run_test "Download URL matches Forge maven pattern" test_forge_download_url_format
run_test "Download URL returns HTTP 200" test_forge_download_url_reachable
run_test "1.17.1 boundary case (new forge)" test_forge_new_version_boundary
run_test "1.16.5 is old forge" test_forge_old_version_is_old
run_test "1.20.4 is new forge" test_forge_new_version_is_new
run_test "1.17 is old forge (edge case)" test_forge_1_17_exactly_is_old
run_test "1.18 is new forge" test_forge_1_18_is_new
run_test "1.21.1 is new forge" test_forge_1_21_is_new
run_test "Forge maven metadata is reachable" test_forge_maven_metadata_reachable
run_test "Maven metadata is valid XML" test_forge_maven_metadata_is_xml
run_test "Maven metadata has versions" test_forge_maven_has_versions
run_test "Forge supports MC 1.20.4" test_forge_supports_1_20_4
run_test "Forge supports MC 1.19.2" test_forge_supports_1_19_2
run_test "Forge supports MC 1.12.2 (classic)" test_forge_supports_1_12_2
run_test "Forge latest matches current MC version" test_forge_latest_matches_current_mc
print_summary