neon-sprawl/client/test/quest_definitions_client_te...

153 lines
4.7 KiB
GDScript

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 display_name: String = str(c.call("display_name_for", "prototype_quest_gather_intro"))
# Assert
assert_that(display_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 display_name: String = str(c.call("display_name_for", "unknown_quest_id"))
# Assert
assert_that(display_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()