167 lines
5.2 KiB
GDScript
167 lines
5.2 KiB
GDScript
extends GdUnitTestSuite
|
|
|
|
## NEO-73: allowed resource-node interact triggers inventory + skill refresh.
|
|
|
|
const IxClient := preload("res://scripts/interaction_request_client.gd")
|
|
const InventoryClient := preload("res://scripts/inventory_client.gd")
|
|
const SkillProgressionClient := preload("res://scripts/skill_progression_client.gd")
|
|
const Picker := preload("res://scripts/prototype_interactable_picker.gd")
|
|
|
|
|
|
class MockInteractTransport:
|
|
extends Node
|
|
signal request_completed(
|
|
result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray
|
|
)
|
|
var last_body: String = ""
|
|
var body_json: String = '{"schemaVersion":1,"allowed":true}'
|
|
var response_code: int = 200
|
|
|
|
func request(
|
|
_url: String,
|
|
_custom_headers: PackedStringArray = PackedStringArray(),
|
|
_method: HTTPClient.Method = HTTPClient.METHOD_POST,
|
|
request_data: String = ""
|
|
) -> Error:
|
|
last_body = request_data
|
|
var body_bytes: PackedByteArray = body_json.to_utf8_buffer()
|
|
request_completed.emit(
|
|
HTTPRequest.RESULT_SUCCESS, response_code, PackedStringArray(), body_bytes
|
|
)
|
|
return OK
|
|
|
|
|
|
class SpySyncClient:
|
|
extends Node
|
|
var sync_calls: int = 0
|
|
|
|
func request_sync_from_server() -> void:
|
|
sync_calls += 1
|
|
|
|
|
|
class GatherRefreshHarness:
|
|
extends Node
|
|
var inventory_sync_calls: int = 0
|
|
var skill_sync_calls: int = 0
|
|
var pending_gather_interactable_id: String = ""
|
|
var awaiting_inventory_finalize: bool = false
|
|
var _inventory: SpySyncClient
|
|
var _skill: SpySyncClient
|
|
var _ix: Node
|
|
|
|
func setup(parent: Node, ix_transport: Node) -> void:
|
|
_inventory = SpySyncClient.new()
|
|
_skill = SpySyncClient.new()
|
|
_ix = IxClient.new()
|
|
_ix.set("injected_http", ix_transport)
|
|
parent.add_child(_ix)
|
|
parent.add_child(_inventory)
|
|
parent.add_child(_skill)
|
|
_ix.connect("interaction_result_received", Callable(self, "_on_interaction_result"))
|
|
|
|
func queue_resource_gather(interactable_id: String) -> void:
|
|
pending_gather_interactable_id = interactable_id
|
|
awaiting_inventory_finalize = false
|
|
|
|
func _clear_gather_session() -> void:
|
|
pending_gather_interactable_id = ""
|
|
awaiting_inventory_finalize = false
|
|
|
|
func _on_interaction_result(
|
|
interactable_id: String, allowed: bool, _reason_code: String
|
|
) -> void:
|
|
if pending_gather_interactable_id.is_empty():
|
|
return
|
|
if interactable_id != pending_gather_interactable_id:
|
|
if awaiting_inventory_finalize:
|
|
return
|
|
_clear_gather_session()
|
|
return
|
|
if not Picker.is_resource_node_id([], interactable_id):
|
|
_clear_gather_session()
|
|
return
|
|
if not allowed:
|
|
_clear_gather_session()
|
|
return
|
|
awaiting_inventory_finalize = true
|
|
_inventory.request_sync_from_server()
|
|
_skill.request_sync_from_server()
|
|
|
|
func post_resource_alpha() -> void:
|
|
queue_resource_gather("prototype_resource_node_alpha")
|
|
_ix.call("post_interact_id", "prototype_resource_node_alpha")
|
|
|
|
func emit_terminal_allowed() -> void:
|
|
_ix.set("_current_interactable_id", "prototype_terminal")
|
|
var body_bytes: PackedByteArray = '{"schemaVersion":1,"allowed":true}'.to_utf8_buffer()
|
|
_ix.call("_on_request_completed", 0, 200, PackedStringArray(), body_bytes)
|
|
|
|
|
|
func test_allowed_resource_interact_triggers_both_refreshes() -> void:
|
|
# Arrange
|
|
var transport := MockInteractTransport.new()
|
|
var harness := GatherRefreshHarness.new()
|
|
auto_free(transport)
|
|
auto_free(harness)
|
|
add_child(harness)
|
|
harness.setup(self, transport)
|
|
monitor_signals(harness._ix)
|
|
# Act
|
|
harness.post_resource_alpha()
|
|
# Assert
|
|
assert_signal(harness._ix).is_emitted("interaction_result_received")
|
|
assert_that(harness._inventory.sync_calls).is_equal(1)
|
|
assert_that(harness._skill.sync_calls).is_equal(1)
|
|
|
|
|
|
func test_denied_resource_interact_skips_refreshes() -> void:
|
|
# Arrange
|
|
var transport := MockInteractTransport.new()
|
|
transport.body_json = '{"schemaVersion":1,"allowed":false,"reasonCode":"node_depleted"}'
|
|
var harness := GatherRefreshHarness.new()
|
|
auto_free(transport)
|
|
auto_free(harness)
|
|
add_child(harness)
|
|
harness.setup(self, transport)
|
|
# Act
|
|
harness.post_resource_alpha()
|
|
# Assert
|
|
assert_that(harness._inventory.sync_calls).is_equal(0)
|
|
assert_that(harness._skill.sync_calls).is_equal(0)
|
|
|
|
|
|
func test_terminal_result_clears_orphaned_gather_pending() -> void:
|
|
# Arrange
|
|
var transport := MockInteractTransport.new()
|
|
var harness := GatherRefreshHarness.new()
|
|
auto_free(transport)
|
|
auto_free(harness)
|
|
add_child(harness)
|
|
harness.setup(self, transport)
|
|
harness.queue_resource_gather("prototype_resource_node_alpha")
|
|
# Act
|
|
harness.emit_terminal_allowed()
|
|
# Assert
|
|
assert_that(harness.pending_gather_interactable_id).is_empty()
|
|
assert_that(harness.awaiting_inventory_finalize).is_false()
|
|
assert_that(harness._inventory.sync_calls).is_equal(0)
|
|
assert_that(harness._skill.sync_calls).is_equal(0)
|
|
|
|
|
|
func test_terminal_after_gather_success_keeps_awaiting_inventory() -> void:
|
|
# Arrange
|
|
var transport := MockInteractTransport.new()
|
|
var harness := GatherRefreshHarness.new()
|
|
auto_free(transport)
|
|
auto_free(harness)
|
|
add_child(harness)
|
|
harness.setup(self, transport)
|
|
# Act
|
|
harness.post_resource_alpha()
|
|
harness.emit_terminal_allowed()
|
|
# Assert
|
|
assert_that(harness.awaiting_inventory_finalize).is_true()
|
|
assert_that(harness.pending_gather_interactable_id).is_equal("prototype_resource_node_alpha")
|
|
assert_that(harness._inventory.sync_calls).is_equal(1)
|
|
assert_that(harness._skill.sync_calls).is_equal(1)
|