extends GdUnitTestSuite ## NEO-122: `QuestDefinitionsClient` GET parse + display names. const QuestDefinitionsClient := preload("res://scripts/quest_definitions_client.gd") var _quests_capture: Array = [] func _capture_quests(quests: Array) -> void: _quests_capture = quests class MockHttpTransport: extends Node signal request_completed( result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray ) var last_url: String = "" var response_code: int = 200 var body_json: String = "" func request( url: String, _custom_headers: PackedStringArray = PackedStringArray(), _method: HTTPClient.Method = HTTPClient.METHOD_GET, _request_data: String = "" ) -> Error: last_url = url request_completed.emit( HTTPRequest.RESULT_SUCCESS, response_code, PackedStringArray(), body_json.to_utf8_buffer() ) return OK static func _four_quests_json() -> String: return ( '{"schemaVersion":1,"quests":[' + '{"id":"prototype_quest_gather_intro","displayName":"Intro: Salvage Run",' + '"prerequisiteQuestIds":[],"steps":[]},' + '{"id":"prototype_quest_refine_intro","displayName":"Intro: Refine Stock",' + '"prerequisiteQuestIds":["prototype_quest_gather_intro"],"steps":[]},' + '{"id":"prototype_quest_combat_intro","displayName":"Intro: Clear the Pocket",' + '"prerequisiteQuestIds":[],"steps":[]},' + '{"id":"prototype_quest_operator_chain","displayName":"Operator Chain",' + '"prerequisiteQuestIds":["prototype_quest_gather_intro",' + '"prototype_quest_refine_intro","prototype_quest_combat_intro"],"steps":[]}' + "]}" ) static func _grid_contract_quests_json() -> String: return ( '{"schemaVersion":1,"quests":[' + '{"id":"prototype_quest_grid_contract","displayName":"Grid Contract",' + '"prerequisiteQuestIds":["prototype_quest_operator_chain"],' + '"factionGateRules":[{"factionId":"prototype_faction_grid_operators","minStanding":15}],' + '"steps":[]}]}' ) func _make_client(transport: Node) -> Node: var c: Node = QuestDefinitionsClient.new() c.set("injected_http", transport) auto_free(transport) auto_free(c) add_child(c) return c func test_parse_quests_json_reads_four_quests() -> void: # Arrange var json := _four_quests_json() # Act var quests: Variant = QuestDefinitionsClient.parse_quests_json(json) # Assert assert_that(quests is Array).is_true() assert_that((quests as Array).size()).is_equal(4) func test_request_sync_emits_definitions_ready() -> void: # Arrange _quests_capture = [] var transport := MockHttpTransport.new() transport.body_json = _four_quests_json() var c := _make_client(transport) c.connect("definitions_ready", Callable(self, "_capture_quests")) monitor_signals(c) # Act c.call("request_sync_from_server") # Assert assert_signal(c).is_emitted("definitions_ready", any()) assert_that(_quests_capture.size()).is_equal(4) assert_that(transport.last_url).contains("/quest-definitions") func test_display_name_for_returns_catalog_display_name() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = _four_quests_json() var c := _make_client(transport) c.call("request_sync_from_server") await get_tree().process_frame # Act var name: String = str(c.call("display_name_for", "prototype_quest_gather_intro")) # Assert assert_that(name).is_equal("Intro: Salvage Run") func test_display_name_for_falls_back_to_raw_id() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = _four_quests_json() var c := _make_client(transport) c.call("request_sync_from_server") await get_tree().process_frame # Act var name: String = str(c.call("display_name_for", "unknown_quest_id")) # Assert assert_that(name).is_equal("unknown_quest_id") func test_faction_gate_rules_for_returns_cached_gate_rows() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = _grid_contract_quests_json() var c := _make_client(transport) c.call("request_sync_from_server") await get_tree().process_frame # Act var rules: Array = c.call("faction_gate_rules_for", "prototype_quest_grid_contract") as Array # Assert assert_that(rules.size()).is_equal(1) var rule: Dictionary = rules[0] assert_that(str(rule.get("factionId", ""))).is_equal("prototype_faction_grid_operators") assert_that(int(rule.get("minStanding", -1))).is_equal(15) func test_faction_gate_rules_for_returns_empty_when_quest_missing() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = _grid_contract_quests_json() var c := _make_client(transport) c.call("request_sync_from_server") await get_tree().process_frame # Act var rules: Array = c.call("faction_gate_rules_for", "prototype_quest_gather_intro") as Array # Assert assert_that(rules.is_empty()).is_true()