extends GdUnitTestSuite ## NEO-85: `CombatTargetsClient` GET parse + target row lookup. const CombatTargetsClient := preload("res://scripts/combat_targets_client.gd") 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 _prototype_npc_snapshot_json() -> String: return ( '{"schemaVersion":1,"targets":[' + '{"targetId":"prototype_npc_melee","maxHp":100,"currentHp":75,"defeated":false},' + '{"targetId":"prototype_npc_ranged","maxHp":80,"currentHp":80,"defeated":false},' + '{"targetId":"prototype_npc_elite","maxHp":200,"currentHp":200,"defeated":false}' + "]}" ) func _make_client(transport: Node) -> Node: var c: Node = CombatTargetsClient.new() c.set("injected_http", transport) auto_free(transport) auto_free(c) add_child(c) return c func test_request_sync_gets_combat_targets_url() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = _prototype_npc_snapshot_json() var c := _make_client(transport) # Act c.call("request_sync_from_server") # Assert assert_that(transport.last_url).contains("/game/world/combat-targets") func test_targets_received_emits_parsed_snapshot() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = _prototype_npc_snapshot_json() var c := _make_client(transport) var got: Array = [] c.connect("targets_received", func(snapshot: Dictionary) -> void: got.append(snapshot)) # Act c.call("request_sync_from_server") # Assert assert_that(got.size()).is_equal(1) var snapshot: Dictionary = got[0] var targets: Variant = snapshot.get("targets", null) assert_that(targets is Array).is_true() assert_that((targets as Array).size()).is_equal(3) func test_target_row_returns_melee_hp_fields() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = _prototype_npc_snapshot_json() var c := _make_client(transport) var got: Array = [] c.connect("targets_received", func(snapshot: Dictionary) -> void: got.append(snapshot)) c.call("request_sync_from_server") var snapshot: Dictionary = got[0] # Act var row: Dictionary = c.call("target_row", "prototype_npc_melee", snapshot) as Dictionary # Assert assert_that(int(row.get("currentHp", 0))).is_equal(75) assert_that(int(row.get("maxHp", 0))).is_equal(100) assert_that(bool(row.get("defeated", false))).is_false() func test_invalid_schema_emits_sync_failed() -> void: # Arrange var transport := MockHttpTransport.new() transport.body_json = '{"schemaVersion":2,"targets":[]}' var c := _make_client(transport) var failed: Array = [] c.connect("targets_sync_failed", func(reason: String) -> void: failed.append(reason)) # Act c.call("request_sync_from_server") # Assert assert_that(failed.size()).is_equal(1) assert_that(str(failed[0])).contains("schemaVersion") func test_http_404_emits_sync_failed() -> void: # Arrange var transport := MockHttpTransport.new() transport.response_code = 404 transport.body_json = "" var c := _make_client(transport) var failed: Array = [] c.connect("targets_sync_failed", func(reason: String) -> void: failed.append(reason)) # Act c.call("request_sync_from_server") # Assert assert_that(failed.size()).is_equal(1) assert_that(str(failed[0])).is_equal("HTTP 404")