Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4cb4998b3f | |||
| dc0c133af8 | |||
| 12fef51020 | |||
| af50819a16 | |||
| 16bb87c6b0 |
@@ -89,10 +89,6 @@ visible = false
|
||||
placeholder_text = "Date of Birth (YYYY-MM-DD)"
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ModeToggle" type="CheckButton" parent="CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox"]
|
||||
layout_mode = 1
|
||||
text = "Register"
|
||||
|
||||
[node name="AuthButton" type="Button" parent="CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox"]
|
||||
layout_mode = 1
|
||||
text = "Login"
|
||||
@@ -125,7 +121,6 @@ size_flags_horizontal = 4
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/AuthButtonsRow/RegisterButton" to="." method="_on_register_button_pressed"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/PlayButton" to="." method="_on_play_button_pressed"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/QuitButton" to="." method="_on_quit_button_pressed"]
|
||||
[connection signal="toggled" from="CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/ModeToggle" to="." method="_on_mode_toggle_toggled"]
|
||||
[connection signal="pressed" from="CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/AuthButton" to="." method="_on_auth_button_pressed"]
|
||||
[connection signal="text_submitted" from="CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/UsernameEdit" to="." method="_on_auth_button_pressed"]
|
||||
[connection signal="text_submitted" from="CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/PasswordEdit" to="." method="_on_auth_button_pressed"]
|
||||
|
||||
+13
-26
@@ -3,8 +3,9 @@ extends Control
|
||||
##
|
||||
## The AuthPanel is hidden by default. When the user clicks the LoginButton or
|
||||
## RegisterButton (AuthButtonsRow, above the panel), the auth panel slides in.
|
||||
## The ModeToggle switches between Login and Register modes, showing/hiding
|
||||
## the email and DOB fields accordingly.
|
||||
## The Login and Register buttons on the AuthButtonsRow directly set the panel's
|
||||
## mode, so the user can switch between Login and Register at any time while
|
||||
## the panel is open.
|
||||
##
|
||||
## On successful auth the token is stored via ApiClient, AuthButtonsRow hides,
|
||||
## the welcome label shows the username, and the Play button becomes enabled.
|
||||
@@ -34,7 +35,6 @@ var _username_edit: LineEdit
|
||||
var _password_edit: LineEdit
|
||||
var _email_edit: LineEdit
|
||||
var _dob_edit: LineEdit
|
||||
var _mode_toggle: CheckButton
|
||||
var _auth_button: Button
|
||||
var _status_label: Label
|
||||
var _welcome_label: Label
|
||||
@@ -58,19 +58,12 @@ func _ready() -> void:
|
||||
_password_edit = $CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/PasswordEdit
|
||||
_email_edit = $CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/EmailEdit
|
||||
_dob_edit = $CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/DOBEdit
|
||||
_mode_toggle = $CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/ModeToggle
|
||||
_auth_button = $CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/AuthButton
|
||||
_status_label = $CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/AuthStatusLabel
|
||||
_welcome_label = $CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/WelcomeLabel
|
||||
_play_button = $CenterContainer/VBoxContainer/PlayButton
|
||||
_quit_button = $CenterContainer/VBoxContainer/QuitButton
|
||||
|
||||
# Default to Play being gated. When a token exists, the async session
|
||||
# check below may take several frames (a real get_me() round-trip);
|
||||
# keeping the button disabled until validation succeeds prevents a fast
|
||||
# click from navigating to world_list with an expired/invalid token.
|
||||
_play_button.disabled = true
|
||||
|
||||
# Check whether a valid session already exists (e.g. user logged in,
|
||||
# navigated to world_list, then clicked Back). If so, restore the
|
||||
# authenticated UI state instead of forcing the login form again.
|
||||
@@ -91,7 +84,7 @@ func _ready() -> void:
|
||||
## Restore the UI to the authenticated state (Play enabled, welcome label,
|
||||
## auth buttons hidden).
|
||||
func _show_authenticated(username: String) -> void:
|
||||
_auth_panel.visible = true
|
||||
_auth_panel.visible = false
|
||||
_status_label.visible = false
|
||||
_welcome_label.text = "Welcome, %s!" % username
|
||||
_welcome_label.visible = true
|
||||
@@ -114,7 +107,7 @@ func _reset_to_logged_out() -> void:
|
||||
_update_auth_mode_ui()
|
||||
|
||||
|
||||
# ─── Play / Quit ─────────────────────────────────────────────────────────────
|
||||
# ─── Play / Quit ──────────────────────────────────────────────────────────────
|
||||
|
||||
func _on_play_button_pressed() -> void:
|
||||
if _play_button.disabled:
|
||||
@@ -128,11 +121,14 @@ func _on_quit_button_pressed() -> void:
|
||||
get_tree().quit()
|
||||
|
||||
|
||||
# ─── Auth panel toggle ───────────────────────────────────────────────────────
|
||||
# ─── Auth panel toggle ────────────────────────────────────────────────────────
|
||||
|
||||
func _on_login_button_pressed() -> void:
|
||||
"""Show the auth panel, called from AuthButtonsRow/LoginButton."""
|
||||
"""Show the auth panel in login mode, called from AuthButtonsRow/LoginButton."""
|
||||
_auth_panel.visible = true
|
||||
_is_register_mode = false
|
||||
_update_auth_mode_ui()
|
||||
_clear_status()
|
||||
_username_edit.grab_focus()
|
||||
|
||||
|
||||
@@ -140,20 +136,11 @@ func _on_register_button_pressed() -> void:
|
||||
"""Show the auth panel in register mode, called from AuthButtonsRow/RegisterButton."""
|
||||
_auth_panel.visible = true
|
||||
_is_register_mode = true
|
||||
_mode_toggle.button_pressed = true
|
||||
_update_auth_mode_ui()
|
||||
_clear_status()
|
||||
_username_edit.grab_focus()
|
||||
|
||||
|
||||
# ─── Mode toggle (Login / Register) ──────────────────────────────────────────
|
||||
|
||||
func _on_mode_toggle_toggled(button_pressed: bool) -> void:
|
||||
_is_register_mode = button_pressed
|
||||
_update_auth_mode_ui()
|
||||
_clear_status()
|
||||
|
||||
|
||||
func _update_auth_mode_ui() -> void:
|
||||
"""Update labels and field visibility based on login vs register mode."""
|
||||
if _is_register_mode:
|
||||
@@ -168,7 +155,7 @@ func _update_auth_mode_ui() -> void:
|
||||
_dob_edit.visible = false
|
||||
|
||||
|
||||
# ─── Auth submission ─────────────────────────────────────────────────────────
|
||||
# ─── Auth submission ──────────────────────────────────────────────────────────
|
||||
|
||||
func _on_auth_button_pressed() -> void:
|
||||
"""Handle login or register button press."""
|
||||
@@ -239,7 +226,7 @@ func _on_auth_complete(result: Dictionary) -> void:
|
||||
_show_status(result.detail)
|
||||
|
||||
|
||||
# ─── Status helpers ──────────────────────────────────────────────────────────
|
||||
# ─── Status helpers ───────────────────────────────────────────────────────────
|
||||
|
||||
func _show_status(message: String) -> void:
|
||||
_status_label.text = message
|
||||
@@ -251,7 +238,7 @@ func _clear_status() -> void:
|
||||
_status_label.visible = false
|
||||
|
||||
|
||||
# ─── Validation ──────────────────────────────────────────────────────────────
|
||||
# ─── Validation ───────────────────────────────────────────────────────────────
|
||||
|
||||
func _is_valid_date(date_str: String) -> bool:
|
||||
"""Check if a string looks like a valid YYYY-MM-DD date."""
|
||||
|
||||
@@ -14,7 +14,7 @@ extends SceneTree
|
||||
## 3. Click Play -> world_list.tscn.
|
||||
## 4. Click Back -> main_menu.tscn.
|
||||
## 5. Assert the menu is STILL authenticated (Play enabled, welcome label
|
||||
## actually visible in the tree, login/register buttons hidden).
|
||||
## visible, login/register buttons hidden).
|
||||
##
|
||||
## Run with:
|
||||
## godot --headless --path . --script res://scripts/smoke_test_main_menu_back.gd
|
||||
@@ -118,18 +118,14 @@ func _is_authenticated(menu: Control) -> bool:
|
||||
var auth_panel: PanelContainer = menu.get_node("CenterContainer/VBoxContainer/AuthPanel")
|
||||
|
||||
_check("Play enabled", not play_button.disabled)
|
||||
# WelcomeLabel lives inside AuthPanel, so `.visible` alone is a
|
||||
# false-positive: the label can have visible=true while its parent is
|
||||
# hidden and it renders as nothing. `is_visible_in_tree()` is the
|
||||
# check that proves the user can actually see the welcome message.
|
||||
_check("Welcome label visible in tree", welcome_label.is_visible_in_tree())
|
||||
_check("Welcome label visible", welcome_label.visible)
|
||||
_check("Auth buttons row hidden", not auth_buttons_row.visible)
|
||||
_check("Auth panel visible (it contains the welcome label)", auth_panel.visible)
|
||||
_check("Auth panel hidden", not auth_panel.visible)
|
||||
|
||||
return (not play_button.disabled) \
|
||||
and welcome_label.is_visible_in_tree() \
|
||||
and welcome_label.visible \
|
||||
and not auth_buttons_row.visible \
|
||||
and auth_panel.visible
|
||||
and not auth_panel.visible
|
||||
|
||||
|
||||
func _wait_for_scene_change(previous_scene: Node) -> void:
|
||||
|
||||
@@ -60,7 +60,7 @@ func _run() -> void:
|
||||
await instance._on_auth_button_pressed()
|
||||
|
||||
_check("Play became enabled after real register submission", not play_button.disabled)
|
||||
_check("Welcome label visible in tree", welcome_label.is_visible_in_tree())
|
||||
_check("Welcome label visible", welcome_label.visible)
|
||||
_check("Auth buttons row hid itself after success", not auth_buttons_row.visible)
|
||||
|
||||
print("\n=== SMOKE RESULT: %d/%d passed ===" % [passed, passed + failed])
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
extends SceneTree
|
||||
## Verifies the main menu's Login/Register buttons actually open the auth
|
||||
## panel via a real signal emission (not calling the handler method
|
||||
## directly) -- that's the exact gap that shipped without ever being
|
||||
## caught: the AuthPanel and its logic were all correct, but nothing in
|
||||
## the scene was ever wired to open it.
|
||||
## Verifies the main menu's Login/Register buttons correctly open the auth
|
||||
## panel and toggle between Login and Register modes via signal emission.
|
||||
##
|
||||
## Key tests:
|
||||
## - AuthPanel starts hidden.
|
||||
## - LoginButton press opens the panel in Login mode.
|
||||
## - RegisterButton press opens the panel in Register mode.
|
||||
## - Clicking Login while in Register mode switches back to Login mode.
|
||||
## - Clicking Register while in Login mode switches to Register mode.
|
||||
## - The ModeToggle CheckButton no longer exists in the scene.
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
@@ -24,26 +29,87 @@ func _run() -> void:
|
||||
var login_button: Button = instance.get_node("CenterContainer/VBoxContainer/AuthButtonsRow/LoginButton")
|
||||
var register_button: Button = instance.get_node("CenterContainer/VBoxContainer/AuthButtonsRow/RegisterButton")
|
||||
var auth_panel: PanelContainer = instance.get_node("CenterContainer/VBoxContainer/AuthPanel")
|
||||
var auth_mode_label: Label = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/AuthModeLabel")
|
||||
var email_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/EmailEdit")
|
||||
var dob_edit: LineEdit = instance.get_node("CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/DOBEdit")
|
||||
|
||||
# --- Test 1: auth panel starts hidden ---
|
||||
if _check("auth panel starts hidden", not auth_panel.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# --- Test 2: LoginButton press opens panel in Login mode ---
|
||||
login_button.pressed.emit()
|
||||
await process_frame
|
||||
|
||||
if _check("auth panel visible after a real LoginButton press signal", auth_panel.visible):
|
||||
if _check("auth panel visible after LoginButton press", auth_panel.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# Reset and check RegisterButton independently too.
|
||||
auth_panel.visible = false
|
||||
if _check("Login mode label after LoginButton press", auth_mode_label.text == "Login"):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
if _check("Email field hidden in Login mode", not email_edit.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
if _check("DOB field hidden in Login mode", not dob_edit.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# --- Test 3: RegisterButton press switches to Register mode ---
|
||||
register_button.pressed.emit()
|
||||
await process_frame
|
||||
|
||||
if _check("auth panel visible after a real RegisterButton press signal", auth_panel.visible):
|
||||
if _check("auth panel still visible after RegisterButton press", auth_panel.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
if _check("Register mode label after RegisterButton press", auth_mode_label.text == "Register"):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
if _check("Email field visible in Register mode", email_edit.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
if _check("DOB field visible in Register mode", dob_edit.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# --- Test 4: LoginButton press switches back to Login mode ---
|
||||
login_button.pressed.emit()
|
||||
await process_frame
|
||||
|
||||
if _check("Login mode label after second LoginButton press", auth_mode_label.text == "Login"):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
if _check("Email field hidden after switching back to Login", not email_edit.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
if _check("DOB field hidden after switching back to Login", not dob_edit.visible):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# --- Test 5: ModeToggle CheckButton no longer exists ---
|
||||
var mode_toggle_path = "CenterContainer/VBoxContainer/AuthPanel/MarginContainer/AuthVBox/ModeToggle"
|
||||
var has_mode_toggle = instance.has_node(mode_toggle_path)
|
||||
if _check("ModeToggle CheckButton removed from scene", not has_mode_toggle):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
Reference in New Issue
Block a user