127 lines
6.3 KiB
GDScript
127 lines
6.3 KiB
GDScript
extends SceneTree
|
||
## E2E Server-Sektion: das ECHTE Panel gegen einen ECHTEN Match-Server
|
||
## (tests/run_server_sektion_e2e.sh). Env: SRV_PORT, SRV_TOKEN, SRV_SVMAP.
|
||
|
||
var _failures: Array[String] = []
|
||
var _checks := 0
|
||
|
||
|
||
func _check(cond: bool, label: String) -> void:
|
||
_checks += 1
|
||
if cond:
|
||
print(" ok - " + label)
|
||
else:
|
||
_failures.append(label)
|
||
print(" FAIL - " + label)
|
||
|
||
|
||
func _initialize() -> void:
|
||
var port := int(OS.get_environment("SRV_PORT"))
|
||
var token := OS.get_environment("SRV_TOKEN")
|
||
var load_res := SvmapIO.load_from_file(OS.get_environment("SRV_SVMAP"))
|
||
if not bool(load_res["ok"]):
|
||
print("FAIL: Beispiel-Map nicht ladbar: ", load_res["errors"])
|
||
quit(1)
|
||
return
|
||
var good_doc: Dictionary = load_res["data"]
|
||
|
||
var fake := Control.new()
|
||
fake.set_script(load("res://tests/support_fake_main.gd"))
|
||
fake.doc = good_doc
|
||
root.add_child(fake)
|
||
var panel: Control = load("res://src/ui/panels/server_panel.gd").new()
|
||
panel.store_path = "user://test_e2e_store.dat"
|
||
DirAccess.remove_absolute(ProjectSettings.globalize_path(panel.store_path))
|
||
panel.setup(fake)
|
||
panel.build()
|
||
root.add_child(panel)
|
||
await process_frame
|
||
|
||
# Server anlegen (wie der Dialog) – erst mit FALSCHEM Token
|
||
var id: String = panel.store.upsert({"name": "E2E", "host": "127.0.0.1", "port": port, "token": "falsch"})
|
||
panel._refresh_selector(id)
|
||
var ok: bool = await panel.connect_selected()
|
||
_check(not ok and not panel.connected and "Token" in panel.last_notice + panel._conn_label.text, "falsches Token -> verständliche Meldung")
|
||
# Unerreichbarer Port
|
||
var bad_id: String = panel.store.upsert({"name": "tot", "host": "127.0.0.1", "port": 1, "token": "x"})
|
||
panel._refresh_selector(bad_id)
|
||
ok = await panel.connect_selected()
|
||
_check(not ok and "Keine Verbindung" in panel._conn_label.text, "unerreichbarer Server -> 'Keine Verbindung'")
|
||
# Richtig
|
||
panel.store.upsert({"id": id, "name": "E2E", "host": "127.0.0.1", "port": port, "token": token})
|
||
panel._refresh_selector(id)
|
||
ok = await panel.connect_selected()
|
||
_check(ok and panel.connected, "Verbinden mit richtigem Token")
|
||
_check("Admin E2E" in panel._status_label.text and "Spieler: 0" in panel._status_label.text, "Übersicht zeigt Servername/Spieler: " + panel._status_label.text.replace("\n", " | ").substr(0, 90))
|
||
|
||
# Einstellungen
|
||
_check(panel._settings_editors.has("team_size") and panel._settings_editors.has("password"), "Einstellungsformular aus der API-Spec gebaut")
|
||
(panel._settings_editors["team_size"] as SpinBox).value = 3
|
||
(panel._settings_editors["mode"] as OptionButton).select(3)
|
||
(panel._settings_editors["server_name"] as LineEdit).text = "Neuer Name"
|
||
(panel._settings_editors["password"] as LineEdit).text = "pw123"
|
||
var ch: Dictionary = panel.changed_settings()
|
||
_check(ch.keys().size() == 4 and ch["team_size"] == 3 and ch["mode"] == "dm", "nur geänderte Werte werden gesendet")
|
||
await panel.save_settings()
|
||
_check("Sofort aktiv" in panel._settings_result.text and "nächsten Map" in panel._settings_result.text and "Neustart" in panel._settings_result.text,
|
||
"Antwort zeigt sofort/nächste Map/Neustart: " + panel._settings_result.text.replace("\n", " | "))
|
||
_check(panel.changed_settings().is_empty(), "nach Speichern keine offenen Änderungen")
|
||
(panel._settings_editors["team_size"] as SpinBox).value = 9999 if false else 1
|
||
panel._fill_settings_editors()
|
||
_check(int((panel._settings_editors["team_size"] as SpinBox).value) == 3, "Zurücksetzen holt Serverwerte")
|
||
(panel._settings_editors["password"] as LineEdit).text = ""
|
||
|
||
# Push: gültige Map
|
||
panel._push_name.text = "editor_test"
|
||
var r: Dictionary = await panel.push_current_map()
|
||
_check(bool(r["ok"]) and "Hochgeladen" in r["text"], "Push gültige Map: " + str(r["text"]).substr(0, 80))
|
||
r = await panel.push_current_map()
|
||
_check(not bool(r["ok"]) and bool(r["exists"]), "zweiter Push -> 'existiert' (Nachfrage)")
|
||
r = await panel.push_current_map(true)
|
||
_check(bool(r["ok"]) and "ersetzt" in r["text"], "Push mit Ersetzen")
|
||
# Push: lokal ungültige Map (Spawns weg) -> gar nicht erst hochgeladen
|
||
var bad: Dictionary = good_doc.duplicate(true)
|
||
bad["spawn_zones"] = {}
|
||
fake.doc = bad
|
||
r = await panel.push_current_map()
|
||
_check(not bool(r["ok"]) and r["stage"] == "lokal" and "nicht hochgeladen" in r["text"], "lokal ungültig -> nicht hochgeladen: " + str(r["text"]).substr(0, 90))
|
||
# Server-422 (Editor-Prüfung umgangen): rohe Datei mit kaputter Prüfsumme
|
||
fake.doc = good_doc
|
||
var client: AdminClient = panel.client
|
||
var bytes := '{"format_version": 2, "info": {}}'.to_utf8_buffer()
|
||
var raw: Dictionary = await client.call_api("POST", "/maps", null, {"name": "kaputt"}, bytes)
|
||
var txt := AdminTexte.erklaere(raw)
|
||
_check(int(raw["status"]) == 422 and "abgelehnt" in txt and "•" in txt, "Server-422 -> deutsche Fehlerliste: " + txt.replace("\n", " | ").substr(0, 100))
|
||
# Rotation / Maps
|
||
await panel.refresh_maps()
|
||
var up_id := ""
|
||
for k in panel._rotation_checks.keys():
|
||
if str(k).ends_with("editor_test.svmap"):
|
||
up_id = k
|
||
_check(up_id != "", "hochgeladene Map in der Liste")
|
||
(panel._rotation_checks[up_id] as CheckBox).button_pressed = true
|
||
await panel.save_rotation()
|
||
_check("Rotation gespeichert" in panel.last_notice, "Rotation speichern")
|
||
await panel.load_map(up_id)
|
||
await create_timer(4.0).timeout
|
||
await panel.refresh_status()
|
||
_check("Example Valley" in panel._status_label.text or "editor_test" in panel._status_label.text, "Map laden: " + panel._status_label.text.split("\n")[1])
|
||
await panel.load_map("res://maps/testmap.tscn")
|
||
await create_timer(3.0).timeout
|
||
await panel.delete_map("editor_test")
|
||
_check("Map gelöscht" in panel.last_notice, "Map löschen")
|
||
await panel._do_restart()
|
||
_check("neu gestartet" in panel.last_notice, "Match neu starten")
|
||
# Spieler (leer) + Logs
|
||
await panel.refresh_players()
|
||
await process_frame
|
||
_check(panel._players_box.get_child_count() == 1, "Spielerliste leer-Hinweis")
|
||
await panel.kick(4242)
|
||
_check("nicht" in panel.last_notice and "Spieler" in panel.last_notice, "Kick unbekannter Spieler -> Meldung: " + panel.last_notice)
|
||
panel._log_filter.text = "Admin"
|
||
await panel.load_logs()
|
||
_check(panel._log_text.text.contains("Admin") and not panel._log_text.text.contains(token), "Logs geladen, Token nicht enthalten")
|
||
|
||
DirAccess.remove_absolute(ProjectSettings.globalize_path(panel.store_path))
|
||
print("CHECKS: %d FAILURES: %d" % [_checks, _failures.size()])
|
||
quit(0 if _failures.is_empty() else 1)
|