Restrict progression features to UAT
This commit is contained in:
@@ -9,6 +9,7 @@ signal award_received(amount: int, reason: String)
|
||||
signal ledger_changed
|
||||
|
||||
const EndpointConfig := preload("res://scripts/autoload/api_endpoint_config.gd")
|
||||
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
||||
const DEFAULT_URL := "https://us3q.ranaze.com/api/credits"
|
||||
|
||||
var credits: int = 0
|
||||
@@ -86,7 +87,8 @@ func apply_award_response(parsed: Dictionary) -> void:
|
||||
continue
|
||||
var award: Dictionary = award_variant
|
||||
var amount := int(award.get("amount", 0))
|
||||
if amount > 0:
|
||||
var reason_code := str(award.get("reasonCode", award.get("reason_code", "")))
|
||||
if amount > 0 and (FeatureFlags.progression_enabled() or not FeatureFlags.is_progression_reward(reason_code)):
|
||||
award_received.emit(amount, str(award.get("description", "Learning reward")))
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
extends RefCounted
|
||||
|
||||
|
||||
static func progression_enabled() -> bool:
|
||||
return str(ProjectSettings.get_setting("step3/deployment_environment", "development")).to_lower() == "uat"
|
||||
|
||||
|
||||
static func is_progression_reward(reason_code: String) -> bool:
|
||||
return reason_code in [
|
||||
"mastery_practicing",
|
||||
"mastery_strong",
|
||||
"mastery_mastered",
|
||||
"session_goal_complete",
|
||||
"daily_mission_complete",
|
||||
"weekly_goal_complete",
|
||||
"rank_promotion",
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
uid://bve4tb6xllsnf
|
||||
@@ -1,6 +1,7 @@
|
||||
extends VBoxContainer
|
||||
|
||||
const Style := preload("res://scripts/ui/ui_style.gd")
|
||||
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
||||
|
||||
var main: Control
|
||||
var selected_system := "All Systems"
|
||||
@@ -14,6 +15,7 @@ var targeted_setup := false
|
||||
var goal_option: OptionButton
|
||||
var target_label: Label
|
||||
var pending_launch := false
|
||||
var goal_row: HBoxContainer
|
||||
|
||||
func _ready() -> void:
|
||||
set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
@@ -32,7 +34,8 @@ func _ready() -> void:
|
||||
Style.set_label(system_label, 22, Style.CYAN)
|
||||
add_child(system_label)
|
||||
|
||||
var goal_row := HBoxContainer.new()
|
||||
goal_row = HBoxContainer.new()
|
||||
goal_row.visible = FeatureFlags.progression_enabled()
|
||||
var goal_label := Label.new()
|
||||
goal_label.text = "Finish line"
|
||||
goal_row.add_child(goal_label)
|
||||
@@ -88,7 +91,7 @@ func _ready() -> void:
|
||||
|
||||
|
||||
func on_show(payload: Variant = null) -> void:
|
||||
if typeof(payload) == TYPE_DICTIONARY:
|
||||
if typeof(payload) == TYPE_DICTIONARY and FeatureFlags.progression_enabled():
|
||||
targeted_setup = bool(payload.get("mastery_target", false))
|
||||
selected_system = str(payload.get("step3_system", "All Systems"))
|
||||
requested_count = int(payload.get("question_count", 10))
|
||||
@@ -102,7 +105,7 @@ func on_show(payload: Variant = null) -> void:
|
||||
else:
|
||||
goal_option.set_meta("mastery_target", false)
|
||||
targeted_setup = false
|
||||
selected_system = str(payload) if payload != null else "All Systems"
|
||||
selected_system = str(payload.get("step3_system", "All Systems")) if typeof(payload) == TYPE_DICTIONARY else (str(payload) if payload != null else "All Systems")
|
||||
_refresh_setup()
|
||||
|
||||
|
||||
@@ -130,6 +133,10 @@ func _start_block() -> void:
|
||||
if not QuestionBankService.has_questions():
|
||||
status_label.text = "Questions have not loaded from the API yet."
|
||||
return
|
||||
if not FeatureFlags.progression_enabled():
|
||||
BlockSessionService.start_block(selected_system, int(size_spin.value), mode_option.get_item_text(mode_option.selected))
|
||||
main.show_screen("player")
|
||||
return
|
||||
pending_launch = true
|
||||
start_button.disabled = true
|
||||
status_label.text = "Preparing your study goal..."
|
||||
|
||||
@@ -6,6 +6,7 @@ const ActivityChart := preload("res://scripts/ui/dashboard_activity_chart.gd")
|
||||
const DashboardSparkline := preload("res://scripts/ui/dashboard_sparkline.gd")
|
||||
const DashboardSegmentBar := preload("res://scripts/ui/dashboard_segment_bar.gd")
|
||||
const DashboardInfoBadge := preload("res://scripts/ui/dashboard_info_badge.gd")
|
||||
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
||||
|
||||
var main: Control
|
||||
var scroll: ScrollContainer
|
||||
@@ -93,9 +94,11 @@ func _build() -> void:
|
||||
stat_card_grid.add_theme_constant_override("h_separation", 12)
|
||||
stat_card_grid.add_theme_constant_override("v_separation", 12)
|
||||
content.add_child(stat_card_grid)
|
||||
mission_content = VBoxContainer.new()
|
||||
mission_content.add_theme_constant_override("separation", 10)
|
||||
content.add_child(_card(mission_content, 16))
|
||||
mission_content = null
|
||||
if FeatureFlags.progression_enabled():
|
||||
mission_content = VBoxContainer.new()
|
||||
mission_content.add_theme_constant_override("separation", 10)
|
||||
content.add_child(_card(mission_content, 16))
|
||||
|
||||
qbank_sparkline = DashboardSparkline.new()
|
||||
qbank_sparkline.custom_minimum_size = Vector2(0, 34)
|
||||
@@ -147,7 +150,7 @@ func _build() -> void:
|
||||
performance.add_child(trend_chart)
|
||||
performance.add_child(HSeparator.new())
|
||||
var system_header := HBoxContainer.new()
|
||||
system_header.add_child(_section_title("System mastery path"))
|
||||
system_header.add_child(_section_title("System mastery path" if FeatureFlags.progression_enabled() else "Performance by system"))
|
||||
var header_space := Control.new()
|
||||
header_space.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
system_header.add_child(header_space)
|
||||
@@ -166,9 +169,11 @@ func _build() -> void:
|
||||
right_column.add_theme_constant_override("separation", 12)
|
||||
right_column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
analytics_grid.add_child(right_column)
|
||||
rank_content = VBoxContainer.new()
|
||||
rank_content.add_theme_constant_override("separation", 9)
|
||||
right_column.add_child(_card(rank_content, 16))
|
||||
rank_content = null
|
||||
if FeatureFlags.progression_enabled():
|
||||
rank_content = VBoxContainer.new()
|
||||
rank_content.add_theme_constant_override("separation", 9)
|
||||
right_column.add_child(_card(rank_content, 16))
|
||||
focus_content = VBoxContainer.new()
|
||||
focus_content.add_theme_constant_override("separation", 10)
|
||||
right_column.add_child(_card(focus_content, 16))
|
||||
@@ -196,9 +201,11 @@ func _build() -> void:
|
||||
weekly_summary.add_theme_constant_override("separation", 10)
|
||||
weekly_row.add_child(weekly_summary)
|
||||
weekly.add_child(HSeparator.new())
|
||||
weekly_goal_content = VBoxContainer.new()
|
||||
weekly_goal_content.add_theme_constant_override("separation", 8)
|
||||
weekly.add_child(weekly_goal_content)
|
||||
weekly_goal_content = null
|
||||
if FeatureFlags.progression_enabled():
|
||||
weekly_goal_content = VBoxContainer.new()
|
||||
weekly_goal_content.add_theme_constant_override("separation", 8)
|
||||
weekly.add_child(weekly_goal_content)
|
||||
lower_grid.add_child(_card(weekly, 16))
|
||||
recent_list = VBoxContainer.new()
|
||||
recent_list.add_theme_constant_override("separation", 6)
|
||||
@@ -225,16 +232,22 @@ func _render() -> void:
|
||||
_render_readiness_card(data)
|
||||
_render_accuracy_card(data)
|
||||
trend_chart.set_series(data.get("performanceTrend", []), trend_mode, UIThemeService.is_dark_mode())
|
||||
_render_systems(data.get("systems", []))
|
||||
_render_focus(data.get("systems", []))
|
||||
if FeatureFlags.progression_enabled():
|
||||
_render_systems(data.get("systems", []))
|
||||
_render_focus(data.get("systems", []))
|
||||
else:
|
||||
_render_systems_legacy(data.get("systems", []))
|
||||
_render_focus_legacy(data.get("systems", []))
|
||||
_render_review(data)
|
||||
_render_rank(data.get("progression", {}))
|
||||
if FeatureFlags.progression_enabled():
|
||||
_render_rank(data.get("progression", {}))
|
||||
var weekly: Array = data.get("weeklyActivity", [])
|
||||
activity_chart.set_days(weekly, UIThemeService.is_dark_mode())
|
||||
_render_weekly(data, weekly)
|
||||
_render_recent(data.get("recentActivity", []))
|
||||
_render_missions()
|
||||
_render_weekly_goal()
|
||||
if FeatureFlags.progression_enabled():
|
||||
_render_missions()
|
||||
_render_weekly_goal()
|
||||
|
||||
|
||||
func _render_rank(value: Variant) -> void:
|
||||
@@ -845,6 +858,10 @@ func _start_review_queue(step3_system: String = "") -> void:
|
||||
pending_review_launch = true
|
||||
_show_loading_message("Preparing your review queue...")
|
||||
set_meta("pending_review_system", step3_system)
|
||||
if not FeatureFlags.progression_enabled():
|
||||
review_queue_service.start_pass(step3_system)
|
||||
_render_review(DashboardService.data)
|
||||
return
|
||||
if not StudySessionService.session_started.is_connected(_on_review_session_started):
|
||||
StudySessionService.session_started.connect(_on_review_session_started)
|
||||
if not StudySessionService.session_failed.is_connected(_on_review_session_failed):
|
||||
|
||||
+11
-6
@@ -4,6 +4,7 @@ const Style := preload("res://scripts/ui/ui_style.gd")
|
||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||
const NavigationRoutes := preload("res://scripts/ui/navigation_routes.gd")
|
||||
const CreditsBadge := preload("res://scripts/ui/credits_badge.gd")
|
||||
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
||||
|
||||
var screens := {}
|
||||
var _account_profile_synced := false
|
||||
@@ -39,7 +40,8 @@ func _ready() -> void:
|
||||
Style.apply_app_theme(self)
|
||||
_build_ui()
|
||||
CreditsService.award_received.connect(_show_coin_award)
|
||||
StudySessionService.session_completed.connect(_on_study_session_completed)
|
||||
if FeatureFlags.progression_enabled():
|
||||
StudySessionService.session_completed.connect(_on_study_session_completed)
|
||||
theme_service.theme_changed.connect(_on_theme_changed)
|
||||
resized.connect(_update_responsive_layout)
|
||||
_update_responsive_layout()
|
||||
@@ -47,6 +49,8 @@ func _ready() -> void:
|
||||
|
||||
|
||||
func _on_study_session_completed(summary: Dictionary) -> void:
|
||||
if not FeatureFlags.progression_enabled():
|
||||
return
|
||||
WeeklyGoalService.refresh()
|
||||
call_deferred("show_screen", "session_summary", summary)
|
||||
|
||||
@@ -293,11 +297,12 @@ func _build_ui() -> void:
|
||||
screens_container.add_child(review)
|
||||
screens["review"] = review
|
||||
|
||||
var session_summary := preload("res://scripts/ui/session_summary.gd").new()
|
||||
session_summary.name = "SessionSummary"
|
||||
session_summary.main = self
|
||||
screens_container.add_child(session_summary)
|
||||
screens["session_summary"] = session_summary
|
||||
if FeatureFlags.progression_enabled():
|
||||
var session_summary := preload("res://scripts/ui/session_summary.gd").new()
|
||||
session_summary.name = "SessionSummary"
|
||||
session_summary.main = self
|
||||
screens_container.add_child(session_summary)
|
||||
screens["session_summary"] = session_summary
|
||||
|
||||
var review_queue_results := preload("res://scripts/ui/review_queue_results.gd").new()
|
||||
review_queue_results.name = "ReviewQueueResults"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
extends Control
|
||||
|
||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
||||
|
||||
var main: Control
|
||||
var scroll: ScrollContainer
|
||||
@@ -96,7 +97,9 @@ func _build() -> void:
|
||||
right.add_theme_constant_override("separation", 14)
|
||||
columns.add_child(right)
|
||||
right.add_child(_outcome_card())
|
||||
right.add_child(_progression_card())
|
||||
progression_content = null
|
||||
if FeatureFlags.progression_enabled():
|
||||
right.add_child(_progression_card())
|
||||
right.add_child(_connected_accounts_card())
|
||||
right.add_child(_account_actions_card())
|
||||
_refresh_back_to_session_visibility()
|
||||
@@ -288,7 +291,8 @@ func _render() -> void:
|
||||
_set_metric("cases", str(int(data.get("ccsCasesCompleted", 0))))
|
||||
_set_metric("streak", "%d days" % int(data.get("currentStreak", 0)))
|
||||
_render_systems(data.get("systems", []))
|
||||
_render_progression(data.get("progression", {}))
|
||||
if FeatureFlags.progression_enabled():
|
||||
_render_progression(data.get("progression", {}))
|
||||
_render_outcome()
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ const FlashcardPrefillDialog := preload("res://scripts/ui/flashcard_prefill_dial
|
||||
const CalculatorPanel := preload("res://scripts/ui/calculator_panel.gd")
|
||||
const SlotMachinePanel := preload("res://scripts/ui/rz_slot_machine_screen.gd")
|
||||
const CreditsBadge := preload("res://scripts/ui/credits_badge.gd")
|
||||
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
||||
const CLEAR_HIGHLIGHT_DARK_ICON := preload("res://assets/icons/medmind/clear-highlight-dark.svg")
|
||||
const CLEAR_HIGHLIGHT_LIGHT_ICON := preload("res://assets/icons/medmind/clear-highlight-light.svg")
|
||||
const LABS_DARK_ICON := preload("res://assets/icons/medmind/labs-dark.svg")
|
||||
@@ -1224,7 +1225,7 @@ func _process(delta: float) -> void:
|
||||
return
|
||||
if visible and BlockSessionService.block_started and BlockSessionService.session_kind == "core":
|
||||
_update_timer_bar()
|
||||
var duration_goal := str(StudySessionService.progress.get("goalType", "")) == "duration"
|
||||
var duration_goal := FeatureFlags.progression_enabled() and str(StudySessionService.progress.get("goalType", "")) == "duration"
|
||||
if visible and BlockSessionService.block_started and (BlockSessionService.mode == "Timed" or duration_goal) and (report_overlay == null or not report_overlay.visible):
|
||||
BlockSessionService.seconds_remaining = max(0.0, BlockSessionService.seconds_remaining - delta)
|
||||
var shown_seconds := int(ceil(BlockSessionService.seconds_remaining))
|
||||
@@ -2081,10 +2082,10 @@ func _open_reference_url(url: String) -> void:
|
||||
|
||||
|
||||
func _advance_or_finish() -> void:
|
||||
if not StudySessionService.summary.is_empty():
|
||||
if FeatureFlags.progression_enabled() and not StudySessionService.summary.is_empty():
|
||||
StudySessionService.emit_deferred_summary()
|
||||
return
|
||||
if str(StudySessionService.progress.get("goalType", "")) == "duration" and BlockSessionService.seconds_remaining <= 0:
|
||||
if FeatureFlags.progression_enabled() and str(StudySessionService.progress.get("goalType", "")) == "duration" and BlockSessionService.seconds_remaining <= 0:
|
||||
StudySessionService.check_completion()
|
||||
return
|
||||
if BlockSessionService.move_next():
|
||||
@@ -2111,7 +2112,7 @@ func _finish() -> void:
|
||||
|
||||
|
||||
func _exit_run() -> void:
|
||||
if StudySessionService.is_active() and BlockSessionService.session_kind != "simulation":
|
||||
if FeatureFlags.progression_enabled() and StudySessionService.is_active() and BlockSessionService.session_kind != "simulation":
|
||||
StudySessionService.finish_early()
|
||||
if BlockSessionService.session_kind == "bookmark":
|
||||
BlockSessionService.finish_block()
|
||||
@@ -2165,7 +2166,7 @@ func _set_timer_display(total_seconds: int) -> void:
|
||||
func _is_session_timer_visible() -> bool:
|
||||
if BlockSessionService.session_kind == "core" or BlockSessionService.session_kind == "simulation":
|
||||
return true
|
||||
if str(StudySessionService.progress.get("goalType", "")) == "duration":
|
||||
if FeatureFlags.progression_enabled() and str(StudySessionService.progress.get("goalType", "")) == "duration":
|
||||
return true
|
||||
return BlockSessionService.mode == "Timed"
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
extends VBoxContainer
|
||||
|
||||
const Brand := preload("res://scripts/ui/medmind_style.gd")
|
||||
const FeatureFlags := preload("res://scripts/config/feature_flags.gd")
|
||||
|
||||
var main: Control
|
||||
var title_label: Label
|
||||
@@ -84,6 +85,9 @@ func _start_another() -> void:
|
||||
another_button.disabled = true
|
||||
status_label.text = "Preparing another review pass..."
|
||||
status_label.visible = true
|
||||
if not FeatureFlags.progression_enabled():
|
||||
ReviewQueueService.start_pass("", 20)
|
||||
return
|
||||
if not StudySessionService.session_started.is_connected(_on_review_session_started):
|
||||
StudySessionService.session_started.connect(_on_review_session_started)
|
||||
if not StudySessionService.session_failed.is_connected(_on_review_session_failed):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user