166 lines
8.0 KiB
GDScript
166 lines
8.0 KiB
GDScript
extends SceneTree
|
|
|
|
const PageContext = preload("res://foundation/page_context.gd")
|
|
const ReadinessPageView = preload("res://entry/views/readiness_page_view.gd")
|
|
|
|
var failures: Array[String] = []
|
|
var intents: Array[Dictionary] = []
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
|
|
# Single target size (owner policy): every screen is authored at 1280x720.
|
|
root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_KEEP
|
|
root.content_scale_size = Vector2i(1280, 720)
|
|
root.size = Vector2i(1280, 720)
|
|
var view := ReadinessPageView.new()
|
|
view.name = "ReadinessViewContractFixture"
|
|
view.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
view.configure_presentation({"safe_area": 24, "text_scale": 1.0, "locale": "en"})
|
|
view.mount(PageContext.new({
|
|
"page_id": "readiness_review",
|
|
"caller_id": "party_line",
|
|
"return_page_id": "party_line",
|
|
"return_focus_path": "ReadinessBack",
|
|
}))
|
|
view.intent_emitted.connect(_record_intent)
|
|
root.add_child(view)
|
|
view.render(_fixture_view_data(false))
|
|
await process_frame
|
|
|
|
var context = view.get("context")
|
|
expect(context != null and String(context.get("page_id")) == "readiness_review", "mount stores a copied PageContext")
|
|
expect(view.find_child("ReadinessMasterMatte", true, false) != null, "View owns the Readiness matte")
|
|
expect(view.find_child("ReadinessMasterCanvas", true, false) != null, "View owns the normalized 16:9 canvas")
|
|
expect(view.find_child("ReadinessStaticMaster", true, false) != null, "View owns the static master")
|
|
expect(view.find_child("ReadinessSummaryBand", true, false) != null, "View owns the frozen-facts summary band")
|
|
expect(view.find_child("ReadinessWarning", true, false) != null and view.find_child("ReadinessWarningRow2", true, false) != null, "View renders warning rows")
|
|
var cord := view.find_child("ReadinessFormationCord", true, false) as Control
|
|
var effects := view.find_child("ReadinessFormationEffects", true, false) as Control
|
|
expect(cord != null and effects != null and cord.z_index == 25 and effects.z_index == 35, "View preserves PartyLineTrack layer z-order")
|
|
for position in range(4):
|
|
var member := view.find_child("ReadinessPosition%d" % position, true, false) as Control
|
|
expect(member != null and member.z_index == 30, "View renders ReadinessPosition%d between track layers" % position)
|
|
|
|
var settings := view.find_child("ReadinessSettings", true, false) as Button
|
|
var member_button := view.find_child("ReadinessPosition1", true, false) as Button
|
|
var warning := view.find_child("ReadinessWarning", true, false) as Button
|
|
var revise := view.find_child("ReadinessRevise", true, false) as Button
|
|
var back := view.find_child("ReadinessBack", true, false) as Button
|
|
var accept := view.find_child("ReadinessAccept", true, false) as Button
|
|
var risk := view.find_child("ReadinessRisk", true, false) as Button
|
|
expect(settings != null and not settings.disabled, "Settings intent is enabled")
|
|
expect(member_button != null and not member_button.disabled, "member review intent is enabled")
|
|
expect(warning != null and not warning.disabled, "warning review intent is enabled")
|
|
expect(revise != null and back != null and accept != null and not accept.disabled and risk != null and risk.disabled, "ordered command state is reflected")
|
|
|
|
for button in [settings, member_button, warning, revise, back, accept]:
|
|
if button != null:
|
|
button.emit_signal("pressed")
|
|
await process_frame
|
|
expect(intents.size() == 6, "ordered page emits six enabled intents exactly once")
|
|
expect(intents[0].get("intent_id") == "settings", "Settings intent is named")
|
|
expect(intents[1].get("intent_id") == "review_member" and intents[1].get("payload", {}).get("recruit_id") == "r-2", "member intent carries Recruit identity")
|
|
expect(intents[2].get("intent_id") == "review_warnings", "warning intent is named")
|
|
expect(intents[3].get("intent_id") == "revise", "Revise intent is named")
|
|
expect(intents[4].get("intent_id") == "back", "Back intent is named")
|
|
expect(intents[5].get("intent_id") == "accept", "Accept intent is named")
|
|
|
|
view.render(_fixture_view_data(true))
|
|
await process_frame
|
|
var ready_accept := view.find_child("ReadinessAccept", true, false) as Button
|
|
var ready_risk := view.find_child("ReadinessRisk", true, false) as Button
|
|
expect(ready_accept != null and ready_accept.disabled and ready_risk != null and not ready_risk.disabled, "ready command state is reflected")
|
|
if ready_risk != null:
|
|
ready_risk.emit_signal("pressed")
|
|
await process_frame
|
|
expect(intents.size() == 7 and intents[6].get("intent_id") == "risk", "Risk intent is named")
|
|
|
|
view.render({"ok": false, "locale": "en", "notice": "Readiness unavailable"})
|
|
await process_frame
|
|
expect(view.find_child("ReadinessInvalidOverlay", true, false) != null, "View renders invalid state from supplied data")
|
|
expect(view.find_child("ReadinessMasterOverlay", true, false) == null, "invalid render removes the interactive overlay")
|
|
|
|
var source := FileAccess.get_file_as_string("res://entry/views/readiness_page_view.gd")
|
|
expect(not source.contains("FormationRiskService"), "View does not import FormationRiskService")
|
|
expect(not source.contains("Save"), "View does not own Save semantics")
|
|
expect(not source.contains("RuntimeContentRegistry"), "View does not resolve RuntimeContentRegistry")
|
|
expect(not source.contains("current_screen"), "View does not own route state")
|
|
expect(not source.contains("entry_shell.gd"), "View does not import EntryShell")
|
|
expect(not source.contains("res://compat/"), "View does not import compatibility facade")
|
|
|
|
view.queue_free()
|
|
await process_frame
|
|
if failures.is_empty():
|
|
print("ABG_M37_READINESS_VIEW_CONTRACT_OK mount=true normalized_canvas=true static_master=true party=4 track_layers=25,30,35 warnings=3 intents=settings,review_member,review_warnings,revise,back,accept,risk invalid=true forbidden_imports=true")
|
|
quit(0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func _record_intent(intent_id: String, payload: Dictionary) -> void:
|
|
intents.append({"intent_id": intent_id, "payload": payload})
|
|
|
|
|
|
func _fixture_view_data(ready: bool) -> Dictionary:
|
|
return {
|
|
"ok": true,
|
|
"page_id": "readiness_review",
|
|
"locale": "en",
|
|
"company": {"company_id": "company-001", "owned_count": 4, "line_capacity": 4},
|
|
"contract": {"contract_id": "CTR-R1-01", "difficulty": "stormbound", "line_capacity": 4},
|
|
"formation": {
|
|
"status": "ready" if ready else "ordered",
|
|
"state": "ready" if ready else "ordered",
|
|
"orientation": "rear_left_front_right",
|
|
"front_position": 0,
|
|
"coverage": {"protection": 2, "long_reach": 2, "sustain": 1, "control": 1},
|
|
},
|
|
"order": {
|
|
"front_to_rear_ids": ["r-1", "r-2", "r-3", "r-4"],
|
|
"order_hash": "order-hash-001",
|
|
"front_recruit": _recruit("r-1", "PF-B01", "Ari"),
|
|
"ordered_recruits": [
|
|
{"position": 0, "recruit_id": "r-1", "recruit": _recruit("r-1", "PF-B01", "Ari"), "relation": {}},
|
|
{"position": 1, "recruit_id": "r-2", "recruit": _recruit("r-2", "PF-B05", "Bram"), "relation": {}},
|
|
{"position": 2, "recruit_id": "r-3", "recruit": _recruit("r-3", "PF-B07", "Cera"), "relation": {}},
|
|
{"position": 3, "recruit_id": "r-4", "recruit": _recruit("r-4", "PF-B03", "Dain"), "relation": {}},
|
|
],
|
|
},
|
|
"warnings": {"rows": [
|
|
{"text": "NO GUARD", "severity": "warning", "owner": "coverage"},
|
|
{"text": "Outcome not guaranteed", "severity": "notice", "owner": "risk"},
|
|
{"text": "Reserve: none", "severity": "info", "owner": "formation"},
|
|
]},
|
|
"receipt": {"present": ready, "latest": {"receipt_hash": "receipt-hash-001"}},
|
|
"commands": {
|
|
"settings_enabled": true,
|
|
"member_review_enabled": true,
|
|
"warning_review_enabled": true,
|
|
"revise_enabled": true,
|
|
"back_enabled": true,
|
|
"accept_enabled": not ready,
|
|
"risk_enabled": ready,
|
|
},
|
|
}
|
|
|
|
|
|
func _recruit(recruit_id: String, profession_id: String, name: String) -> Dictionary:
|
|
return {
|
|
"recruit_id": recruit_id,
|
|
"profession_id": profession_id,
|
|
"rendered_name_snapshot": {"en": name},
|
|
}
|
|
|
|
|
|
func expect(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append("M37 Readiness View: %s" % message)
|
|
|