183 lines
4.9 KiB
GDScript
183 lines
4.9 KiB
GDScript
extends GdUnitTestSuite
|
|
|
|
## NEO-142: `FactionStandingClient` GET parse + failure signals.
|
|
|
|
const FactionStandingClient := preload("res://scripts/faction_standing_client.gd")
|
|
|
|
var _standing_capture: Dictionary = {}
|
|
|
|
|
|
func _capture_standing(snapshot: Dictionary) -> void:
|
|
_standing_capture = snapshot
|
|
|
|
|
|
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
|
|
|
|
|
|
class PendingSyncHttpTransport:
|
|
extends Node
|
|
signal request_completed(
|
|
result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray
|
|
)
|
|
var request_count: int = 0
|
|
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:
|
|
request_count += 1
|
|
return OK
|
|
|
|
func complete_pending() -> void:
|
|
request_completed.emit(
|
|
HTTPRequest.RESULT_SUCCESS,
|
|
response_code,
|
|
PackedStringArray(),
|
|
body_json.to_utf8_buffer()
|
|
)
|
|
|
|
|
|
static func _default_standing_json() -> String:
|
|
return (
|
|
'{"schemaVersion":1,"playerId":"dev-local-1","factions":['
|
|
+ '{"id":"prototype_faction_grid_operators","standing":0},'
|
|
+ '{"id":"prototype_faction_rust_collective","standing":0}'
|
|
+ "]}"
|
|
)
|
|
|
|
|
|
static func _post_operator_chain_standing_json() -> String:
|
|
return (
|
|
'{"schemaVersion":1,"playerId":"dev-local-1","factions":['
|
|
+ '{"id":"prototype_faction_rust_collective","standing":0},'
|
|
+ '{"id":"prototype_faction_grid_operators","standing":15}'
|
|
+ "]}"
|
|
)
|
|
|
|
|
|
func _make_client(transport: Node) -> Node:
|
|
var c: Node = FactionStandingClient.new()
|
|
c.set("injected_http", transport)
|
|
auto_free(transport)
|
|
auto_free(c)
|
|
add_child(c)
|
|
return c
|
|
|
|
|
|
func test_parse_faction_standing_json_reads_grid_operators_row() -> void:
|
|
# Arrange
|
|
var json := _post_operator_chain_standing_json()
|
|
# Act
|
|
var snapshot: Variant = FactionStandingClient.parse_faction_standing_json(json)
|
|
# Assert
|
|
assert_that(snapshot is Dictionary).is_true()
|
|
assert_that(
|
|
FactionStandingClient.standing_for(
|
|
FactionStandingClient.GRID_OPERATORS_ID, snapshot as Dictionary
|
|
)
|
|
).is_equal(15)
|
|
|
|
|
|
func test_parse_faction_standing_json_rejects_bad_schema() -> void:
|
|
# Arrange
|
|
var json := '{"schemaVersion":2,"playerId":"dev-local-1","factions":[]}'
|
|
# Act
|
|
var snapshot: Variant = FactionStandingClient.parse_faction_standing_json(json)
|
|
# Assert
|
|
assert_that(snapshot).is_null()
|
|
|
|
|
|
func test_standing_for_defaults_to_zero_when_row_missing() -> void:
|
|
# Arrange
|
|
var snapshot := {"schemaVersion": 1, "playerId": "dev-local-1", "factions": []}
|
|
# Act
|
|
var standing: int = FactionStandingClient.standing_for(
|
|
FactionStandingClient.GRID_OPERATORS_ID, snapshot
|
|
)
|
|
# Assert
|
|
assert_that(standing).is_equal(0)
|
|
|
|
|
|
func test_display_name_for_prototype_factions() -> void:
|
|
# Arrange
|
|
# Act
|
|
var grid_label := FactionStandingClient.display_name_for(
|
|
FactionStandingClient.GRID_OPERATORS_ID
|
|
)
|
|
var rust_label := FactionStandingClient.display_name_for(
|
|
FactionStandingClient.RUST_COLLECTIVE_ID
|
|
)
|
|
# Assert
|
|
assert_str(grid_label).is_equal("Grid Operators")
|
|
assert_str(rust_label).is_equal("Rust Collective")
|
|
|
|
|
|
func test_request_sync_emits_faction_standing_received() -> void:
|
|
# Arrange
|
|
_standing_capture = {}
|
|
var transport := MockHttpTransport.new()
|
|
transport.body_json = _default_standing_json()
|
|
var c := _make_client(transport)
|
|
c.connect("faction_standing_received", Callable(self, "_capture_standing"))
|
|
monitor_signals(c)
|
|
# Act
|
|
c.call("request_sync_from_server")
|
|
# Assert
|
|
assert_signal(c).is_emitted("faction_standing_received", any())
|
|
assert_that(_standing_capture.has("factions")).is_true()
|
|
assert_that(transport.last_url).contains("/faction-standing")
|
|
|
|
|
|
func test_http_404_emits_faction_standing_sync_failed() -> void:
|
|
# Arrange
|
|
var transport := MockHttpTransport.new()
|
|
transport.response_code = 404
|
|
var c := _make_client(transport)
|
|
monitor_signals(c)
|
|
# Act
|
|
c.call("request_sync_from_server")
|
|
# Assert
|
|
assert_signal(c).is_emitted(
|
|
"faction_standing_sync_failed", "HTTP 404 (player unknown)"
|
|
)
|
|
|
|
|
|
func test_request_sync_queues_while_busy_and_flushes_after_completion() -> void:
|
|
# Arrange
|
|
var transport := PendingSyncHttpTransport.new()
|
|
transport.body_json = _default_standing_json()
|
|
var c := _make_client(transport)
|
|
# Act
|
|
c.call("request_sync_from_server")
|
|
c.call("request_sync_from_server")
|
|
# Assert
|
|
assert_that(transport.request_count).is_equal(1)
|
|
transport.complete_pending()
|
|
assert_that(transport.request_count).is_equal(2)
|