Files
modbison/scripts/smoke_test_auth.gd
claude-checkpoint-tooling 0ecc16d963 Registration: replace date-of-birth field with a simple 18+ confirmation
The register form collected and validated an actual date of birth just to
throw it away (backend never stored it beyond a nullable column). Per the
roadmap note: don't collect/store DOB right now, just get a client-side
"I am 18 or older" confirmation. RegisterRequest.date_of_birth (str) is now
over_18 (bool); the endpoint rejects over_18=false with 400 same as before.
calculate_age() is kept (unused by /register now) since real DOB collection
is coming back in a future pass and deleting it broke test_auth_age_gate.py's
import for no benefit.

Frontend: DOBEdit LineEdit replaced with an Over18Check CheckBox; api_client.gd's
register() now takes a bool instead of a date string. All Godot callers
(smoke_test_auth/e2e/world_list/main_menu_ui/main_menu_full_flow) and backend
test files updated to match. Full suite verified against a live backend:
61/61 pytest, 6/6 Godot smoke tests (33 individual assertions), all passing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M6rUEynmv2QmweocAQYARN
2026-08-20 16:25:27 +00:00

133 lines
4.4 KiB
GDScript

extends SceneTree
## Headless smoke test for the AuthPanel login/register flow.
##
## Run with:
## godot --headless --path . --script res://scripts/smoke_test_auth.gd
##
## Requires the backend to be running (default base URL
## `application/agp/api_base_url` -> http://127.0.0.1:8000).
##
## Tests:
## 1. Register a unique user → 201 + token stored.
## 2. Register the same user again → 409 "Username already registered".
## 3. Register with over_18=false → 400 "Must be 18 or older".
## 4. Login with correct credentials → 200 + token stored.
## 5. Login with wrong password → 401 "Incorrect username or password".
## 6. Login with non-existent user → 401 "Incorrect username or password".
##
## Exits 0 on full pass, 1 on any failure.
const API_BASE := "http://127.0.0.1:8000"
const TEST_USERNAME := "smoke_test_user_%d"
const TEST_EMAIL := "smoke_%d@test.example.com"
const TEST_PASSWORD := "SmokeTest123!"
func _initialize() -> void:
_run()
func _run() -> void:
# Wait for autoloads to be ready.
await process_frame
var api := root.get_node("ApiClient") as ApiClient
assert(api != null, "ApiClient autoload not found")
var passed: int = 0
var failed: int = 0
# --- Test 1: Register a unique user ---
randomize()
var unique_id: int = int(Time.get_unix_time_from_system() * 1000) + randi() % 100000
var username := "smoke_%d" % unique_id
var email := "smoke_%d@test.example.com" % unique_id
print("\n=== Test 1: Register unique user ===")
var result := await api.register(username, email, TEST_PASSWORD, true)
if _check("register returns ok", result.ok) \
and _check("register status is 201", result.status == 201) \
and _check("register stores token", api.has_token()):
passed += 1
else:
failed += 1
print(" detail: ", result.detail)
# --- Test 2: Register same user again (duplicate) ---
print("\n=== Test 2: Duplicate username ===")
result = await api.register(username, email, TEST_PASSWORD, true)
if _check("duplicate register not ok", not result.ok) \
and _check("duplicate status is 409", result.status == 409) \
and _check("duplicate detail mentions username",
"username" in result.detail.to_lower()):
passed += 1
else:
failed += 1
print(" detail: ", result.detail)
# --- Test 3: Register with over_18=false ---
print("\n=== Test 3: over_18=false registration ===")
var child_username := "child_%d" % unique_id
var child_email := "child_%d@test.example.com" % unique_id
result = await api.register(child_username, child_email, TEST_PASSWORD, false)
if _check("over_18=false register not ok", not result.ok) \
and _check("over_18=false status is 400", result.status == 400) \
and _check("over_18=false detail mentions age",
"18" in result.detail):
passed += 1
else:
failed += 1
print(" detail: ", result.detail)
# --- Test 4: Login with correct credentials ---
print("\n=== Test 4: Correct login ===")
result = await api.login(username, TEST_PASSWORD)
if _check("login returns ok", result.ok) \
and _check("login status is 200", result.status == 200) \
and _check("login stores token", api.has_token()):
passed += 1
else:
failed += 1
print(" detail: ", result.detail)
# --- Test 5: Login with wrong password ---
print("\n=== Test 5: Wrong password ===")
result = await api.login(username, "WrongPassword!")
if _check("wrong pwd login not ok", not result.ok) \
and _check("wrong pwd status is 401", result.status == 401) \
and _check("wrong pwd detail",
"Incorrect" in result.detail or "incorrect" in result.detail):
passed += 1
else:
failed += 1
print(" detail: ", result.detail)
# --- Test 6: Login with non-existent user ---
print("\n=== Test 6: Non-existent user ===")
result = await api.login("nonexistent_user_xyz", TEST_PASSWORD)
if _check("missing user login not ok", not result.ok) \
and _check("missing user status is 401", result.status == 401) \
and _check("missing user detail",
"Incorrect" in result.detail or "incorrect" in result.detail):
passed += 1
else:
failed += 1
print(" detail: ", result.detail)
# --- Summary ---
print("\n=== SMOKE RESULT: %d/%d passed ===" % [passed, passed + failed])
if failed > 0:
quit(1)
else:
print("SMOKE RESULT: ALL PASS")
quit(0)
func _check(description: String, condition: bool) -> bool:
if condition:
print(" PASS: ", description)
return true
else:
printerr(" FAIL: ", description)
return false