Files
step3/tests/settings_screen_test.gd
T
hz 489b9c3d7c Fix text zoom not actually syncing, and expose it in Settings
Two real gaps meant the account-synced zoom (from the previous
"sync through the account" change) never reached the screen:
_load_cache() updated AccountProfileService.preferences but never
emitted profile_changed, so question_player.gd/ccs_service.gd (already
built and listening before login even happens) never found out a
cached value had loaded. And nothing forced a server refresh
right after login - it only fired if the user happened to open the
profile/progress screen, so a fresh device/session had no path to
the true synced value at all.

main.gd now calls AccountProfileService.refresh() once per login
(not on every silent token refresh) so the real preferences GET
always runs right after signing in, on any device.

Also added Question bank/CCS case text size steppers to the Settings
screen next to dark mode, per user request, reusing the same
AccountProfileService/CCSService plumbing as the in-screen A-/A+
buttons.
2026-07-23 04:37:45 -05:00

70 lines
2.7 KiB
GDScript

extends SceneTree
var failures := 0
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
var account_profile = root.get_node("AccountProfileService")
var ccs_service = root.get_node("CCSService")
var prior_preferences: Dictionary = account_profile.preferences.duplicate(true)
var prior_ccs_scale: float = ccs_service.text_scale
account_profile.preferences["questionTextScale"] = 1.0
ccs_service.text_scale = 1.0
var host := Control.new()
root.add_child(host)
var screen = load("res://scripts/ui/settings_screen.gd").new()
screen.main = host
host.add_child(screen)
await process_frame
_assert(screen.question_scale_value_label != null, "settings should expose a question bank text size control")
_assert(screen.ccs_scale_value_label != null, "settings should expose a CCS case text size control")
_assert(screen.question_scale_value_label.text == "100%", "question bank text size should start at 100%")
_assert(screen.ccs_scale_value_label.text == "100%", "CCS case text size should start at 100%")
_assert(_find_button(screen, "A+", 0) != null, "question bank row should have an A+ button")
_assert(_find_button(screen, "A+", 1) != null, "CCS row should have an A+ button")
var prior_profile_api_url: String = ProjectSettings.get_setting("step3/profile_api_url", "")
ProjectSettings.set_setting("step3/profile_api_url", "http://127.0.0.1:1")
# Call the handlers directly rather than emitting Button.pressed - the real
# signal path also fires UISoundService's click sound, whose OGG playback
# doesn't release cleanly before this short-lived headless process exits.
screen._adjust_question_text_scale(0.1)
_assert(is_equal_approx(float(account_profile.preferences.get("questionTextScale", 1.0)), 1.1), "question bank A+ should increase the synced scale")
_assert(screen.question_scale_value_label.text == "110%", "question bank text size label should reflect the new scale")
screen._adjust_ccs_text_scale(0.1)
_assert(is_equal_approx(ccs_service.text_scale, 1.1), "CCS A+ should increase the shared CCS text scale")
_assert(screen.ccs_scale_value_label.text == "110%", "CCS text size label should reflect the new scale")
ProjectSettings.set_setting("step3/profile_api_url", prior_profile_api_url)
host.queue_free()
await process_frame
account_profile.preferences = prior_preferences
ccs_service.text_scale = prior_ccs_scale
quit(1 if failures > 0 else 0)
func _find_button(root_node: Node, text: String, occurrence: int) -> Button:
var found := 0
for node in root_node.find_children("*", "Button", true, false):
if node.text == text:
if found == occurrence:
return node
found += 1
return null
func _assert(condition: bool, message: String) -> void:
if condition:
return
failures += 1
push_error(message)