113 lines
3.2 KiB
GDScript
113 lines
3.2 KiB
GDScript
extends GdUnitTestSuite
|
|
|
|
## NEO-74: `RecipeDefinitionsClient` GET parse + `recipes_ready` signal.
|
|
## `main.gd` repopulates craft panel on item `definitions_ready` even when inventory GET failed.
|
|
|
|
const RecipeDefinitionsClient := preload("res://scripts/recipe_definitions_client.gd")
|
|
|
|
var _recipes_capture: Array = []
|
|
|
|
|
|
func _capture_recipes(recipes: Array) -> void:
|
|
_recipes_capture = recipes
|
|
|
|
|
|
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 _two_recipes_json() -> String:
|
|
return (
|
|
'{"schemaVersion":1,"recipes":['
|
|
+ '{"id":"make_armor_quick","displayName":"Quick Armor","recipeKind":"make",'
|
|
+ '"requiredSkillId":"refine","inputs":[],"outputs":[]},'
|
|
+ '{"id":"refine_scrap_standard","displayName":"Refine Scrap (Standard)",'
|
|
+ '"recipeKind":"process","requiredSkillId":"refine",'
|
|
+ '"inputs":[{"itemId":"scrap_metal_bulk","quantity":5}],'
|
|
+ '"outputs":[{"itemId":"refined_plate_stock","quantity":1}]}'
|
|
+ "]}"
|
|
)
|
|
|
|
|
|
func _make_client(transport: Node) -> Node:
|
|
var c: Node = RecipeDefinitionsClient.new()
|
|
c.set("injected_http", transport)
|
|
auto_free(transport)
|
|
auto_free(c)
|
|
add_child(c)
|
|
return c
|
|
|
|
|
|
func test_parse_recipes_json_reads_array() -> void:
|
|
# Arrange
|
|
var json := _two_recipes_json()
|
|
# Act
|
|
var recipes: Variant = RecipeDefinitionsClient.parse_recipes_json(json)
|
|
# Assert
|
|
assert_that(recipes is Array).is_true()
|
|
assert_that((recipes as Array).size()).is_equal(2)
|
|
|
|
|
|
func test_request_sync_emits_recipes_ready_in_order() -> void:
|
|
# Arrange
|
|
_recipes_capture = []
|
|
var transport := MockHttpTransport.new()
|
|
transport.body_json = _two_recipes_json()
|
|
var c := _make_client(transport)
|
|
c.connect("recipes_ready", Callable(self, "_capture_recipes"))
|
|
monitor_signals(c)
|
|
# Act
|
|
c.call("request_sync_from_server")
|
|
# Assert
|
|
assert_signal(c).is_emitted("recipes_ready")
|
|
assert_that(_recipes_capture.size()).is_equal(2)
|
|
assert_that(str(_recipes_capture[0].get("id", ""))).is_equal("make_armor_quick")
|
|
assert_that(transport.last_url).contains("/recipe-definitions")
|
|
|
|
|
|
func test_schema_mismatch_emits_recipes_sync_failed() -> void:
|
|
# Arrange
|
|
var transport := MockHttpTransport.new()
|
|
transport.body_json = '{"schemaVersion":99,"recipes":[]}'
|
|
var c := _make_client(transport)
|
|
monitor_signals(c)
|
|
# Act
|
|
c.call("request_sync_from_server")
|
|
# Assert
|
|
assert_signal(c).is_emitted("recipes_sync_failed")
|
|
|
|
|
|
func test_http_error_emits_recipes_sync_failed_with_status() -> void:
|
|
# Arrange
|
|
var transport := MockHttpTransport.new()
|
|
transport.response_code = 503
|
|
var c := _make_client(transport)
|
|
var got: Array = []
|
|
c.connect("recipes_sync_failed", func(reason: String) -> void: got.append(reason))
|
|
# Act
|
|
c.call("request_sync_from_server")
|
|
# Assert
|
|
assert_that(got.size()).is_equal(1)
|
|
assert_that(str(got[0])).contains("503")
|