Restrict progression features to UAT

This commit is contained in:
hz
2026-08-04 08:08:47 -05:00
parent c140b9a96c
commit 976cb70d4a
13 changed files with 216 additions and 37 deletions
+18
View File
@@ -8,6 +8,8 @@ func _initialize() -> void:
func _run() -> void:
var prior_environment: String = ProjectSettings.get_setting("step3/deployment_environment", "development")
ProjectSettings.set_setting("step3/deployment_environment", "uat")
var dashboard_service = root.get_node("DashboardService")
var mission_service = root.get_node("DailyMissionService")
var weekly_goal_service = root.get_node("WeeklyGoalService")
@@ -51,9 +53,25 @@ func _run() -> void:
_assert(dashboard.trend_chart.points.size() == 30, "chart should retain all 30 calendar points")
dashboard.queue_free()
await process_frame
ProjectSettings.set_setting("step3/deployment_environment", "prd")
var production_dashboard = load("res://scripts/ui/dashboard_screen.gd").new()
production_dashboard.size = Vector2(1280, 900)
root.add_child(production_dashboard)
await process_frame
production_dashboard._render()
await process_frame
_assert(production_dashboard.mission_content == null, "production should omit daily mission UI")
_assert(production_dashboard.weekly_goal_content == null, "production should omit weekly goal UI")
_assert(production_dashboard.rank_content == null, "production should omit clinical progression UI")
_assert(production_dashboard.mastery_rows.is_empty(), "production should render legacy system performance instead of mastery actions")
_assert(production_dashboard.system_list.get_child_count() == 14, "production should retain the system performance breakdown")
production_dashboard.queue_free()
dashboard_service.data = prior_data
mission_service.state = prior_missions
weekly_goal_service.state = prior_weekly_goal
ProjectSettings.set_setting("step3/deployment_environment", prior_environment)
await process_frame
quit(1 if failures > 0 else 0)
+3 -5
View File
@@ -206,7 +206,7 @@ func _test_resolved_followup_stays_expanded_and_toggles() -> void:
_assert(content.find_child("FollowupOption_A", true, false) != null, "the resolved follow-up should retain its selected option")
_assert(content.find_child("FollowupOption_B", true, false) != null, "the resolved follow-up should retain its correct option")
var verdict := content.find_child("FollowupVerdict", true, false) as Label
_assert(verdict != null and verdict.text == "Incorrect", "the resolved follow-up should show whether the answer was correct")
_assert(verdict != null and verdict.text.is_empty(), "an incorrect follow-up should rely on its red answer treatment instead of redundant verdict text")
if toggle != null:
toggle.pressed.emit()
_assert(bool(player.followup_states["B"].get("collapsed", false)), "the minimize toggle should collapse the follow-up")
@@ -297,10 +297,8 @@ func _test_review_followup_is_optional_and_single_attempt() -> void:
player.review_followups_section.add_child(player.review_followups_content)
player._render_review_followups()
_assert(not player.next_button.disabled, "optional review follow-ups must not lock Next")
player._answer_review_followup(0, "B")
_assert(bool(player.review_followup_states[0].get("answered", false)), "a review follow-up should record its first response")
player._answer_review_followup(0, "A")
_assert(player.review_followup_states[0].get("selected_choice_id", "") == "B", "review follow-ups should accept only one attempt")
_assert(not player.review_followups_section.visible, "generic post-answer review follow-ups should remain retired")
_assert(player.review_followup_states.is_empty(), "retired generic follow-ups should not create answer state")
player.review_followups_section.free()
player.next_button.free()
player.free()
+104
View File
@@ -0,0 +1,104 @@
extends SceneTree
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
var failures := 0
class ScreenHost extends Control:
var shown_screen := ""
func show_screen(screen_name: String, _payload: Variant = null) -> void:
shown_screen = screen_name
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
var prior_environment: String = ProjectSettings.get_setting("step3/deployment_environment", "development")
ProjectSettings.set_setting("step3/deployment_environment", "uat")
_assert(FeatureFlags.progression_enabled(), "UAT should enable progression")
for environment in ["prd", "production", "development", "unknown"]:
ProjectSettings.set_setting("step3/deployment_environment", environment)
_assert(not FeatureFlags.progression_enabled(), "%s should not enable progression" % environment)
ProjectSettings.set_setting("step3/deployment_environment", "prd")
var received: Array = []
var credits = root.get_node("CreditsService")
var prior_credits: int = credits.credits
var prior_loaded: bool = credits.loaded
var capture := func(amount: int, reason: String): received.append([amount, reason])
credits.award_received.connect(capture)
credits.apply_award_response({"credits": {"credits": 123}, "creditAwards": [{
"amount": 10, "reasonCode": "rank_promotion", "description": "Advanced rank"
}]})
_assert(received.is_empty(), "production should suppress progression award notifications")
_assert(credits.credits == 123, "production should still apply balances containing progression awards")
credits.apply_award_response({"creditAwards": [{
"amount": 2, "reasonCode": "qbank_difficult_correct", "description": "Difficult question correct"
}]})
_assert(received.size() == 1, "production should retain ordinary learning reward notifications")
credits.award_received.disconnect(capture)
credits.credits = prior_credits
credits.loaded = prior_loaded
var production_setup = load("res://scripts/ui/block_setup.gd").new()
var screen_host := ScreenHost.new()
root.add_child(screen_host)
production_setup.main = screen_host
root.add_child(production_setup)
await process_frame
_assert(not production_setup.goal_row.visible, "production block setup should hide progression finish lines")
var question_bank = root.get_node("QuestionBankService")
var prior_questions: Array = question_bank.questions.duplicate(true)
question_bank.questions = [_sample_question()]
production_setup.selected_system = "All Systems"
production_setup.size_spin.value = 5
production_setup._start_block()
_assert(screen_host.shown_screen == "player", "production should launch a classic block directly")
_assert(root.get_node("StudySessionService").active_session_id.is_empty(), "production classic blocks should not create progression sessions")
root.get_node("BlockSessionService").finish_block()
question_bank.questions = prior_questions
production_setup.queue_free()
screen_host.queue_free()
var production_profile = load("res://scripts/ui/progress_profile.gd").new()
root.add_child(production_profile)
await process_frame
_assert(production_profile.progression_content == null, "production profile should omit clinical progression")
production_profile.queue_free()
ProjectSettings.set_setting("step3/deployment_environment", "uat")
var uat_setup = load("res://scripts/ui/block_setup.gd").new()
root.add_child(uat_setup)
await process_frame
_assert(uat_setup.goal_row.visible, "UAT block setup should retain progression finish lines")
uat_setup.queue_free()
ProjectSettings.set_setting("step3/deployment_environment", prior_environment)
await process_frame
quit(1 if failures > 0 else 0)
func _sample_question() -> Dictionary:
var choices: Array = []
for index in 5:
choices.append({"id": String.chr(65 + index), "text": "Choice %d" % index})
return {
"external_id": "progression-flag-test",
"system": "Cardiovascular",
"stem": "Test stem",
"lead_in": "Choose an answer.",
"choices": choices,
"correct_choice_id": "A",
}
func _assert(condition: bool, message: String) -> void:
if condition:
return
failures += 1
push_error(message)
@@ -0,0 +1 @@
uid://cl00e10sgfqei