extends SceneTree # Exercises the client-side "system vs. user" flashcard split added to the hub screen: deck # summaries splitting into My/Official groups in the deck selector, Edit/Archive controls being # absent on system-owned note rows, and "New Card" refusing to target a system deck. Mirrors # flashcard_theme_responsive_test.gd's instantiation pattern (added to the tree so _ready() runs). var failures := 0 func _initialize() -> void: call_deferred("_run") func _run() -> void: var host := Control.new() host.size = Vector2(1280, 800) root.add_child(host) var Hub := load("res://scripts/ui/flashcards_hub.gd") var hub = Hub.new() hub.size = host.size host.add_child(hub) await process_frame # ---------- Deck selector splits into "My Decks" / "Official Decks" ---------- var summaries := [ {"deck": {"id": "deck-mine", "name": "My Cardio Deck", "isSystem": false}, "total": 5, "mastered": 0, "due": 1, "new": 2}, {"deck": {"id": "deck-system", "name": "Step 3 Essentials", "isSystem": true}, "total": 10, "mastered": 3, "due": 0, "new": 4}, ] hub._on_decks_changed(summaries) _assert(hub.deck_ids.size() == hub.deck_selector.item_count, "deck_ids should stay index-aligned with the OptionButton's items (including separators)") var my_header_index := -1 var official_header_index := -1 var mine_item_index := -1 var system_item_index := -1 for i in hub.deck_selector.item_count: if hub.deck_selector.is_item_separator(i): if hub.deck_selector.get_item_text(i) == "My Decks": my_header_index = i elif hub.deck_selector.get_item_text(i) == "Official Decks": official_header_index = i elif hub.deck_selector.get_item_text(i) == "My Cardio Deck": mine_item_index = i elif hub.deck_selector.get_item_text(i) == "Step 3 Essentials": system_item_index = i _assert(my_header_index >= 0, "a 'My Decks' separator header should be present") _assert(official_header_index >= 0, "an 'Official Decks' separator header should be present") _assert(mine_item_index > my_header_index, "the user's own deck should be listed under the 'My Decks' header") _assert(system_item_index > official_header_index, "the system deck should be listed under the 'Official Decks' header") _assert(str(hub.deck_ids[mine_item_index]) == "deck-mine", "deck_ids should still resolve the correct id for the user's own deck") _assert(str(hub.deck_ids[system_item_index]) == "deck-system", "deck_ids should still resolve the correct id for the system deck") _assert(hub._is_system_deck("deck-system"), "_is_system_deck should report true for the seeded system deck") _assert(not hub._is_system_deck("deck-mine"), "_is_system_deck should report false for the user's own deck") # ---------- System note rows have no Edit/Archive controls, plus an "Official" badge ---------- hub.notes = [ {"id": "note-mine", "type": "basic", "prompt": "Mine", "answer": "A", "tags": [], "isSystem": false}, {"id": "note-system", "type": "basic", "prompt": "System", "answer": "A", "tags": [], "isSystem": true}, ] hub._render_notes() await process_frame var mine_row := hub.list_container.get_child(0) as BoxContainer var mine_actions := mine_row.get_child(2) as HBoxContainer _assert(mine_actions.get_child_count() == 2, "the user's own note row should show both Edit and Archive") var system_row := hub.list_container.get_child(2) as BoxContainer var system_actions := system_row.get_child(2) as HBoxContainer _assert(system_actions.get_child_count() == 0, "a system note row should show no Edit/Archive controls at all") var system_header_row := (system_row.get_child(1) as VBoxContainer).get_child(0) as HBoxContainer var found_official_badge := false for child in system_header_row.get_children(): if child is Label and (child as Label).text == "Official": found_official_badge = true _assert(found_official_badge, "a system note row should show an 'Official' badge") # ---------- "New Card" against a system-selected deck falls back to the default deck ---------- hub.decks = summaries var system_index: int = hub.deck_ids.find("deck-system") hub.deck_selector.select(system_index) hub._open_editor("", {}) _assert(hub.editor_target_deck_id.is_empty(), "opening the editor for a brand-new card while a system deck is selected should fall back to the default deck instead") hub._close_editor() var mine_index: int = hub.deck_ids.find("deck-mine") hub.deck_selector.select(mine_index) hub._open_editor("", {}) _assert(hub.editor_target_deck_id == "deck-mine", "opening the editor for a brand-new card while the user's own deck is selected should target that deck") hub.free() host.queue_free() await process_frame quit(1 if failures > 0 else 0) func _assert(condition: bool, message: String) -> void: if condition: return failures += 1 push_error(message)