Normalizza il periodo nel backend quando l'app invia "Q1" via cable, così advance_period aggiorna regia e overlay; rimuove i controlli cronometro dalla regia e rende più tollerante il decode iOS al resume sessione. Co-authored-by: Cursor <cursoragent@cursor.com>
135 lines
5.6 KiB
Bash
Executable File
135 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# E2E iOS: build Debug sul simulatore, API locale, smoke Riprendi diretta + close_set.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
IOS_DIR="$ROOT/native/ios"
|
|
API="${API:-http://localhost:3000}"
|
|
SIM_ID="${SIM_ID:-48A837E2-845E-4043-B168-B8D4FDCAAE21}"
|
|
DERIVED="$IOS_DIR/build/DerivedData"
|
|
|
|
cd "$IOS_DIR"
|
|
python3 generate_xcodeproj.py
|
|
|
|
echo "== Build simulatore (API=$API) =="
|
|
xcodebuild \
|
|
-project MatchLiveTv.xcodeproj \
|
|
-scheme MatchLiveTv \
|
|
-destination "platform=iOS Simulator,id=$SIM_ID" \
|
|
-derivedDataPath "$DERIVED" \
|
|
-configuration Debug \
|
|
API_BASE_URL="$API" \
|
|
ONLY_ACTIVE_ARCH=YES ARCHS=arm64 EXCLUDED_ARCHS=x86_64 \
|
|
build 2>&1 | tail -5
|
|
|
|
APP="$DERIVED/Build/Products/Debug-iphonesimulator/MatchLiveTv.app"
|
|
test -d "$APP"
|
|
|
|
echo "== Install + launch =="
|
|
xcrun simctl install "$SIM_ID" "$APP"
|
|
xcrun simctl launch "$SIM_ID" com.matchlivetv.match-live-tv
|
|
|
|
echo "== API: sessione live + score volley + Riprendi diretta =="
|
|
LOGIN=$(curl -sf -X POST "$API/api/v1/auth/login" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email":"coach@matchlivetv.test","password":"password123"}')
|
|
TOKEN=$(echo "$LOGIN" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
|
|
AUTH="Authorization: Bearer $TOKEN"
|
|
|
|
TEAM_ID=$(curl -sf -H "$AUTH" "$API/api/v1/teams" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['id'])")
|
|
|
|
# Libera slot diretta concorrente (limite piano dev)
|
|
while read -r SID; do
|
|
[[ -n "$SID" ]] && curl -sf -X PATCH -H "$AUTH" "$API/api/v1/sessions/$SID/stop" > /dev/null || true
|
|
done < <(curl -sf -H "$AUTH" "$API/api/v1/teams/$TEAM_ID/matches" | python3 -c "
|
|
import sys, json
|
|
for m in json.load(sys.stdin):
|
|
sid = m.get('active_session_id')
|
|
if sid:
|
|
print(sid)
|
|
")
|
|
|
|
MATCH=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/teams/$TEAM_ID/matches" \
|
|
-d '{"opponent_name":"E2E iOS","sport_key":"pallavolo"}')
|
|
MATCH_ID=$(echo "$MATCH" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
|
|
SESSION=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/matches/$MATCH_ID/sessions" \
|
|
-d '{"platform":"matchlivetv","privacy_status":"unlisted","quality_preset":"720p_30_2.5mbps"}')
|
|
SESSION_ID=$(echo "$SESSION" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
curl -sf -X PATCH -H "$AUTH" "$API/api/v1/sessions/$SESSION_ID/start" > /dev/null
|
|
|
|
# Porta il tabellone a 26-12
|
|
for _ in $(seq 1 26); do
|
|
curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/sessions/$SESSION_ID/score_action" \
|
|
-d '{"score_action":"home_point"}' > /dev/null
|
|
done
|
|
for _ in $(seq 1 12); do
|
|
curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/sessions/$SESSION_ID/score_action" \
|
|
-d '{"score_action":"away_point"}' > /dev/null
|
|
done
|
|
|
|
CLOSE=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/sessions/$SESSION_ID/score_action" \
|
|
-d '{"score_action":"close_set"}')
|
|
|
|
python3 - <<PY
|
|
import json, sys
|
|
close = json.loads('''$CLOSE''')
|
|
score = close.get("score") or {}
|
|
assert close.get("set_won") is True, close
|
|
assert score.get("home_sets") == 1, score
|
|
assert score.get("current_set") == 2, score
|
|
assert score.get("home_points") == 0 and score.get("away_points") == 0, score
|
|
partials = score.get("set_partials") or []
|
|
assert any(p.get("home") == 26 and p.get("away") == 12 for p in partials), partials
|
|
print("close_set OK:", score.get("home_sets"), "-", score.get("away_sets"), "set", score.get("current_set"))
|
|
PY
|
|
|
|
# Simula Riprendi diretta (GET session detail)
|
|
RESUME=$(curl -sf -H "$AUTH" "$API/api/v1/sessions/$SESSION_ID")
|
|
python3 - <<PY
|
|
import json
|
|
s = json.loads('''$RESUME''')
|
|
score = s.get("score") or {}
|
|
assert s.get("status") in ("live", "connecting", "reconnecting", "idle"), s.get("status")
|
|
assert score.get("board_type") in ("volley", "racket", "basket", "timed", "generic", "timer"), score
|
|
assert score.get("current_set") == 2, score
|
|
print("GET /sessions/:id OK — Riprendi diretta payload valido (volley)")
|
|
PY
|
|
|
|
echo "== API: sessione basket in pausa + Riprendi diretta =="
|
|
BASKET_MATCH=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/teams/$TEAM_ID/matches" \
|
|
-d '{"opponent_name":"E2E Basket","sport_key":"basket"}')
|
|
BASKET_MATCH_ID=$(echo "$BASKET_MATCH" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
|
|
BASKET_SESSION=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/matches/$BASKET_MATCH_ID/sessions" \
|
|
-d '{"platform":"matchlivetv","privacy_status":"unlisted","quality_preset":"720p_30_2.5mbps"}')
|
|
BASKET_SESSION_ID=$(echo "$BASKET_SESSION" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
curl -sf -X PATCH -H "$AUTH" "$API/api/v1/sessions/$BASKET_SESSION_ID/start" > /dev/null
|
|
for _ in $(seq 1 5); do
|
|
curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
"$API/api/v1/sessions/$BASKET_SESSION_ID/score_action" \
|
|
-d '{"score_action":"home_point"}' > /dev/null
|
|
done
|
|
curl -sf -X PATCH -H "$AUTH" "$API/api/v1/sessions/$BASKET_SESSION_ID/pause" > /dev/null
|
|
|
|
BASKET_RESUME=$(curl -sf -H "$AUTH" "$API/api/v1/sessions/$BASKET_SESSION_ID")
|
|
python3 - <<PY
|
|
import json
|
|
s = json.loads('''$BASKET_RESUME''')
|
|
score = s.get("score") or {}
|
|
assert s.get("status") == "paused", s.get("status")
|
|
assert score.get("board_type") == "basket", score
|
|
assert score.get("home_points") == 5, score
|
|
assert score.get("period", "").startswith("Q"), score.get("period")
|
|
print("GET /sessions/:id OK — Riprendi diretta payload valido (basket)")
|
|
PY
|
|
|
|
echo "== E2E iOS completato: app avviata sul simulatore, API scoring/resume OK =="
|