Files
Cinderwild/tests/test_updates.gd

120 lines
6.0 KiB
GDScript

extends SceneTree
## The update check (scripts/core/updates.gd): comparing versions, a plain
## version.json feed, a Gitea/GitHub release feed (its version.json asset and
## downloads by name), "you're up to date", broken feeds, the setting, the
## title screen's banner, and the advice on a "Different game version"
## refusal. No network: a fake feed answers.
## Run: godot --headless --path . --script res://tests/test_updates.gd
var _fails := 0
var _finished := false
var U: Node
var pages: Dictionary = {}
func check(cond: bool, what: String) -> void:
print((" ok " if cond else " FAIL ") + what)
if not cond:
_fails += 1
func _initialize() -> void:
_run.call_deferred()
func _run() -> void:
U = root.get_node("Updates")
U.prefs_path = "user://test_updates.json"
DirAccess.remove_absolute(U.prefs_path)
U.load_prefs()
await _body()
check(_finished, "test ran to the end (no script errors)")
DirAccess.remove_absolute(U.prefs_path)
print("RESULT: %s (%d failures)" % ["PASS" if _fails == 0 else "FAIL", _fails])
quit(1 if _fails > 0 else 0)
func _fake(url: String) -> String:
return String(pages.get(url, "<html>404</html>"))
func _check_now() -> String:
U.check()
while U.state == "checking":
await process_frame
return U.state
func _body() -> void:
print("versions")
var C: Script = load("res://scripts/core/updates.gd")
check(C.compare_versions("0.2.0", "0.1.0") == 1 and C.compare_versions("0.1.0", "0.2.0") == -1, "0.2.0 is newer than 0.1.0")
check(C.compare_versions("v0.10.0", "0.9.5") == 1, "0.10 beats 0.9 (numbers, not letters), and a v in front is fine")
check(C.compare_versions("1.0", "1.0.0") == 0 and C.compare_versions("1.0.0-beta", "1.0.0") == 0, "1.0 = 1.0.0 = 1.0.0-beta")
check(U.version == ProjectSettings.get_setting("application/config/version") and not U.version.is_empty(),
"this game knows its own version (%s)" % U.version)
check(U.feed.begins_with("https://"), "and where to ask: %s" % U.feed)
print("headless, no fake feed")
U.fetch_override = Callable()
check(await _check_now() == "off", "tests and bots never touch the network")
U.fetch_override = _fake
U.feed = "https://example.test/version.json"
var plat: String = C.platform_key()
print("a version.json feed")
pages[U.feed] = JSON.stringify({"version": "9.1.0", "protocol": 99, "notes": "The Cove.", "page": "https://example.test/r/9.1.0",
"downloads": {plat: {"file": "Cinderwild-9.1.0-%s.zip" % plat, "url": "https://example.test/dl/%s.zip" % plat, "sha256": "ab"}}})
check(await _check_now() == "available", "9.1.0 is out: available")
check(U.latest_version() == "9.1.0" and U.latest_protocol() == 99, "its version and protocol")
check(U.download_url() == "https://example.test/dl/%s.zip" % plat and U.download().sha256 == "ab", "this platform's download (%s), with its checksum" % plat)
print("a release feed (Gitea / Forgejo / GitHub)")
U.feed = "https://example.test/api/releases/latest"
pages[U.feed] = JSON.stringify({"tag_name": "v9.2.0", "html_url": "https://example.test/releases/v9.2.0", "assets": [
{"name": "version.json", "browser_download_url": "https://example.test/a/version.json"},
{"name": "Cinderwild-9.2.0-%s.zip" % plat, "browser_download_url": "https://example.test/a/game-%s.zip" % plat}]})
pages["https://example.test/a/version.json"] = JSON.stringify({"version": "9.2.0", "protocol": 99,
"downloads": {plat: {"file": "Cinderwild-9.2.0-%s.zip" % plat, "sha256": "cd"}}, "windows_only_key": true})
check(await _check_now() == "available" and U.latest_version() == "9.2.0", "the release's version.json is read: 9.2.0")
check(U.download_url() == "https://example.test/a/game-%s.zip" % plat, "the download is the release asset with that file name")
check(U.page == "https://example.test/releases/v9.2.0", "and the release page is kept")
U.latest.downloads.erase(plat)
check(U.download_url() == U.page, "no package for this platform: the release page instead")
print("up to date, and broken feeds")
pages[U.feed] = JSON.stringify({"version": U.version, "protocol": 12})
check(await _check_now() == "current", "the same version: up to date")
pages[U.feed] = JSON.stringify({"version": "0.0.1"})
check(await _check_now() == "current", "an older one: up to date")
pages[U.feed] = "<html>Bad gateway</html>"
check(await _check_now() == "failed" and U.error.contains("JSON"), "a 502 page: failed, and says why (%s)" % U.error)
pages[U.feed] = JSON.stringify({"tag_name": "v1", "assets": []})
check(await _check_now() == "failed" and U.error.contains("version.json"), "a release with no version.json: failed")
print("the setting")
U.set_enabled(false)
pages[U.feed] = JSON.stringify({"version": "9.3.0"})
check(await _check_now() == "off", "off: no check")
U.load_prefs()
check(not U.enabled, "and it's remembered")
U.set_enabled(true)
check(await _check_now() == "available", "on again: 9.3.0")
print("the title screen")
var TS: Script = load("res://scripts/ui/title_screen.gd")
var msg := "Different game version: this server runs Cinderwild 9.3.0 (protocol 99), you have protocol 12. Update the game to join."
check(TS.version_advice(msg).contains("9.3.0 is out"), "refused for an old version: it says the new one is out")
check(TS.version_advice("Server is full").is_empty(), "(other refusals: nothing added)")
pages[U.feed] = JSON.stringify({"version": "9.4.0", "notes": "Sea fishing."})
U.state = "idle"
var title: Node = load("res://scenes/title.tscn").instantiate()
root.add_child(title)
for _i in range(5):
await process_frame
while U.state == "checking":
await process_frame
await process_frame
check(title.version_label != null and title.version_label.text.ends_with(U.version), "the version, bottom left (%s)" % title.version_label.text)
check(title.update_banner.visible and title._update_text.text.contains("9.4.0 is out") and title._update_text.text.contains("Sea fishing."),
"a banner: 9.4.0 is out, with its notes")
check(title._update_text.text.contains("git pull"), "(running from the source: it says git pull)")
title.queue_free()
await process_frame
U.fetch_override = Callable()
_finished = true