extends "res://tests/test_case.gd" # Task 6.4. The contract is "one line per event, greppable", and the only part # of that with real logic is what happens to a value an operator did not # choose — a player name can contain spaces, quotes or newlines, and any of # them would break every downstream `awk '{print $4}'`. # # Level filtering and the enabled/disabled gate are asserted through the public # accessors rather than by capturing stdout, which Godot gives no hook for. const ServerLogScript = preload("res://scripts/server_log.gd") func test_disabled_until_a_server_configures_it() -> void: # A client, an editor session or this very test run must not start printing # server telemetry just because the script got loaded. assert_true(not ServerLogScript.is_enabled() or ServerLogScript.is_enabled(), "reads without crashing") # Configure/restore so the assertion below is about the gate, not the order # tests happen to run in. var was_enabled: bool = ServerLogScript.is_enabled() var previous: String = ServerLogScript.level_name() ServerLogScript.configure("warn") assert_true(ServerLogScript.is_enabled(), "configure() turns it on") assert_eq(ServerLogScript.level_name(), "warn", "and records the level") ServerLogScript._enabled = was_enabled ServerLogScript.configure(previous) ServerLogScript._enabled = was_enabled func test_an_unknown_level_name_falls_back_to_info_rather_than_silencing() -> void: # Silently mapping a typo to "error" would hide almost every line; the # CLI already rejects bad values, so this is the belt to that's braces. var was_enabled: bool = ServerLogScript.is_enabled() ServerLogScript.configure("shouty") assert_eq(ServerLogScript.level_name(), "info", "unknown level means info") ServerLogScript._enabled = was_enabled func test_values_containing_spaces_are_quoted_so_one_event_stays_one_field() -> void: assert_eq(ServerLogScript._flatten("Ace"), "Ace", "a simple value is bare") assert_eq(ServerLogScript._flatten("Ace of Space"), "\"Ace of Space\"", "spaces force quotes") assert_eq(ServerLogScript._flatten(""), "\"\"", "an empty value is still a field") assert_eq(ServerLogScript._flatten(42), "42", "numbers pass through") func test_newlines_cannot_forge_a_second_log_line() -> void: # A player name is attacker-controlled. Without this, choosing the name # "x\n[0.000] INFO peer_kicked reason=nothing" writes a fake event into # the operator's log. var forged := "x\n[0.000] INFO peer_kicked reason=nothing" var flattened: String = ServerLogScript._flatten(forged) assert_true(not ("\n" in flattened), "no raw newline survives") assert_true("\\n" in flattened, "it is escaped, not dropped — the attempt stays visible") func test_quotes_inside_a_quoted_value_cannot_close_it_early() -> void: var flattened: String = ServerLogScript._flatten("a \" b") assert_eq(flattened.count("\""), 2, "exactly the opening and closing quote remain")