neon-sprawl/client/test/ability_cast_client_test.gd

130 lines
4.4 KiB
GDScript

extends GdUnitTestSuite
# main.gd sets base_url/dev_player_id on AbilityCastClient from the same authority block as
# HotbarLoadoutClient (NEO-31).
const CastClient := preload("res://scripts/ability_cast_client.gd")
class MockHttpTransport:
extends Node
signal request_completed(
result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray
)
var last_url: String = ""
var last_body: String = ""
var last_method: HTTPClient.Method = HTTPClient.METHOD_GET
var _queue: Array[Dictionary] = []
func enqueue(result: int, code: int, body: String) -> void:
_queue.append({"result": result, "code": code, "body": body})
func request(
url: String,
_custom_headers: PackedStringArray = PackedStringArray(),
method: HTTPClient.Method = HTTPClient.METHOD_GET,
request_data: String = ""
) -> Error:
last_url = url
last_method = method
last_body = request_data
if _queue.is_empty():
return ERR_UNAVAILABLE
var r: Dictionary = _queue.pop_front()
request_completed.emit(
r["result"], r["code"], PackedStringArray(), str(r["body"]).to_utf8_buffer()
)
return OK
class HoldFirstThenAutoTransport:
extends Node
signal request_completed(
result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray
)
var request_count: int = 0
var last_body: String = ""
var _first: bool = true
func request(
_url: String,
_custom_headers: PackedStringArray = PackedStringArray(),
_method: HTTPClient.Method = HTTPClient.METHOD_GET,
request_data: String = ""
) -> Error:
request_count += 1
last_body = request_data
var body_json := '{"schemaVersion":1,"accepted":true}'
var body_bytes: PackedByteArray = body_json.to_utf8_buffer()
if _first:
_first = false
call_deferred("_emit", body_bytes)
else:
request_completed.emit(HTTPRequest.RESULT_SUCCESS, 200, PackedStringArray(), body_bytes)
return OK
func _emit(body_bytes: PackedByteArray) -> void:
request_completed.emit(HTTPRequest.RESULT_SUCCESS, 200, PackedStringArray(), body_bytes)
func _make_client(transport: Node) -> Node:
var c: Node = CastClient.new()
c.set("injected_http", transport)
auto_free(transport)
auto_free(c)
add_child(c)
return c
func test_request_cast_posts_expected_payload_with_null_target() -> void:
var transport := MockHttpTransport.new()
transport.enqueue(HTTPRequest.RESULT_SUCCESS, 200, '{"schemaVersion":1,"accepted":true}')
var c := _make_client(transport)
var started: bool = bool(c.call("request_cast", 2, "prototype_guard", null))
assert_that(started).is_true()
assert_that(transport.last_url).contains("/ability-cast")
assert_that(transport.last_method).is_equal(HTTPClient.METHOD_POST)
var parsed: Variant = JSON.parse_string(transport.last_body)
assert_that(parsed is Dictionary).is_true()
var body: Dictionary = parsed
assert_that(int(body.get("schemaVersion", 0))).is_equal(1)
assert_that(int(body.get("slotIndex", -1))).is_equal(2)
assert_that(body.get("abilityId")).is_equal("prototype_guard")
assert_that(body.get("targetId", "missing")).is_equal(null)
func test_request_cast_posts_target_id_string_when_set() -> void:
var transport := MockHttpTransport.new()
transport.enqueue(HTTPRequest.RESULT_SUCCESS, 200, '{"schemaVersion":1,"accepted":true}')
var c := _make_client(transport)
(
assert_that(bool(c.call("request_cast", 0, "prototype_pulse", "prototype_target_alpha")))
. is_true()
)
var parsed: Variant = JSON.parse_string(transport.last_body)
var body: Dictionary = parsed
assert_that(body.get("targetId")).is_equal("prototype_target_alpha")
func test_request_cast_returns_false_when_http_request_fails_to_start() -> void:
# Arrange: empty queue → transport.request returns ERR_UNAVAILABLE (same as failed start).
var transport := MockHttpTransport.new()
var c := _make_client(transport)
# Act
var started: bool = bool(c.call("request_cast", 0, "prototype_pulse", null))
# Assert
assert_that(started).is_false()
func test_request_cast_while_busy_is_ignored() -> void:
var transport := HoldFirstThenAutoTransport.new()
var c := _make_client(transport)
assert_that(bool(c.call("request_cast", 0, "prototype_pulse", null))).is_true()
assert_that(bool(c.call("request_cast", 1, "prototype_guard", null))).is_false()
await get_tree().process_frame
await get_tree().process_frame
assert_that(transport.request_count).is_equal(1)
var parsed: Variant = JSON.parse_string(transport.last_body)
var body: Dictionary = parsed
assert_that(int(body.get("slotIndex", -1))).is_equal(0)