110 lines
4.3 KiB
Python
110 lines
4.3 KiB
Python
"""Create a venue test game, then verify persistence with --verify after restart."""
|
|
|
|
import base64
|
|
import datetime
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
|
|
root = Path(__file__).resolve().parents[2] / "venue"
|
|
assert (root / "backend" / "evening_detective_server").is_file(), "Backend artifact missing"
|
|
assert (root / "backend" / "goose").is_file(), "Migration tool missing"
|
|
assert (root / "backend" / "dev-user.sql").is_file(), "Account bootstrap SQL missing"
|
|
assert (root / "frontend" / "dist" / "index.html").is_file(), "Frontend artifact missing"
|
|
assert list((root / "migrations").glob("*.sql")), "Migrations missing"
|
|
config = dict(
|
|
line.split("=", 1)
|
|
for line in (root / ".env").read_text().splitlines()
|
|
if line and not line.startswith("#")
|
|
)
|
|
base = "https://evening-detective.crabs-games.art"
|
|
token = ""
|
|
opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
|
|
|
|
|
|
def request(path, body=None, raw=False):
|
|
headers = {"Content-Type": "application/json"}
|
|
if token:
|
|
headers["Authorization"] = "Bearer " + token
|
|
req = urllib.request.Request(
|
|
base + path,
|
|
data=None if body is None else json.dumps(body).encode(),
|
|
headers=headers,
|
|
)
|
|
with opener.open(req, timeout=10) as response:
|
|
data = response.read()
|
|
return data if raw else json.loads(data)
|
|
|
|
|
|
def verify(state):
|
|
game = request(f'/api/games/{state["gameID"]}')["game"]
|
|
teams = game["teams"]
|
|
assert any(
|
|
team["ID"] == state["teamID"]
|
|
and team["participationStatus"] == "confirmed"
|
|
for team in teams
|
|
), "Test team or confirmed participation was not preserved"
|
|
assert request("/api/files/" + state["filename"], raw=True) == base64.b64decode(
|
|
state["data"]
|
|
), "Uploaded material was not preserved"
|
|
assert b'<div id="app">' in request("/games", raw=True), "SPA route failed"
|
|
|
|
|
|
try:
|
|
with opener.open("https://evening-detective-api.crabs-games.art/api/test/ping", timeout=10) as response:
|
|
assert response.status == 200, "HTTPS API domain failed"
|
|
token = request(
|
|
"/api/auth/login",
|
|
{
|
|
"email": config["VENUE_USER_EMAIL"],
|
|
"password": config["VENUE_USER_PASSWORD"],
|
|
},
|
|
)["accessToken"]
|
|
state_file = root / "packages" / "smoke.json"
|
|
if "--verify" in sys.argv:
|
|
state = json.loads(state_file.read_text())
|
|
else:
|
|
scenario = request("/api/scenario", {"name": "TEST venue smoke"})["ID"]
|
|
start = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=2)
|
|
game = request(
|
|
"/api/games",
|
|
{
|
|
"name": "TEST venue smoke",
|
|
"description": "Disposable offline environment check",
|
|
"startAt": start.isoformat(),
|
|
"scenarioID": scenario,
|
|
"format": "online",
|
|
},
|
|
)["ID"]
|
|
team = request(
|
|
"/api/teams",
|
|
{"gameID": game, "name": "TEST team", "participantsCount": 2},
|
|
)["ID"]
|
|
data = base64.b64encode(b"%PDF-1.4\n%venue-smoke\n%%EOF\n").decode()
|
|
filename = request(
|
|
"/api/files/upload", {"filename": "venue-smoke.pdf", "data": data}
|
|
)["filename"]
|
|
state = {"gameID": game, "teamID": team, "filename": filename, "data": data}
|
|
state_file.parent.mkdir(exist_ok=True)
|
|
state_file.write_text(json.dumps(state))
|
|
verify(state)
|
|
for path, body in [
|
|
("/api/auth/signup", {"username": "Test", "email": "test@venue.invalid", "acceptTerms": True, "acceptPrivacy": True}),
|
|
("/api/auth/refresh-password", {"email": config["VENUE_USER_EMAIL"]}),
|
|
]:
|
|
try:
|
|
request(path, body)
|
|
except urllib.error.HTTPError as error:
|
|
assert error.code == 400, "Unexpected disabled operation status"
|
|
assert json.loads(error.read())["code"] == 9, "Expected FailedPrecondition"
|
|
else:
|
|
raise AssertionError("Email-based account operation succeeded locally")
|
|
print("PASS: login, test game, confirmed team, material, SPA and disabled email operations")
|
|
except urllib.error.HTTPError as error:
|
|
# Do not print response bodies: authentication responses may contain credentials.
|
|
print(f"FAIL: venue API returned HTTP {error.code}", file=sys.stderr)
|
|
sys.exit(1)
|