From 1b932fd69c3dba925e0cbf027e05508b2daf5e8c Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Wed, 9 Sep 2026 01:01:42 -0400 Subject: add back launcher script and correct pathing --- tests/test_wrapper_service.py | 170 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 tests/test_wrapper_service.py (limited to 'tests/test_wrapper_service.py') diff --git a/tests/test_wrapper_service.py b/tests/test_wrapper_service.py new file mode 100644 index 0000000..f17a944 --- /dev/null +++ b/tests/test_wrapper_service.py @@ -0,0 +1,170 @@ +import os +import subprocess +import sys +import tempfile +import types +import unittest +from pathlib import Path +from unittest.mock import Mock + + +sys.modules.setdefault( + "decky", + types.SimpleNamespace(DECKY_USER_HOME="/home/deck", logger=Mock()), +) +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "py_modules")) + +from lsfg_vk.wrapper_service import WrapperService + + +class WrapperServiceTests(unittest.TestCase): + def setUp(self): + self.tempdir = tempfile.TemporaryDirectory() + self.home = Path(self.tempdir.name) / "home" / "deck" + self.home.mkdir(parents=True) + self.service = WrapperService() + self.service.user_home = self.home + self.service.local_bin_dir = self.home / ".local/bin" + self.service.config_dir = self.home / ".config/lsfg-vk" + self.service.sidecar_path = self.service.config_dir / "workarounds.json" + self.service.wrapper_path = self.service.local_bin_dir / "lsfg" + + def tearDown(self): + self.tempdir.cleanup() + + def _state(self, **changes): + state = self.service.default_state() + state.update(changes) + return state + + def _run(self, appid, *args, env=None): + process_env = {"PATH": "/usr/bin:/bin", "SteamAppId": str(appid)} + if env: + process_env.update(env) + return subprocess.run( + [str(self.service.wrapper_path), *args], + env=process_env, + capture_output=True, + text=True, + check=True, + ) + + def test_writes_owned_dispatcher_and_validates_shell(self): + response = self.service.set("123", self._state(dxvkFrameRate=60, enableZink=True)) + self.assertTrue(response["success"]) + self.assertEqual(response["wrapper_path"], "~/.lsfg") + self.assertTrue(response["wrapper_owned"]) + self.assertEqual(response["state"]["dxvkFrameRate"], 60) + self.assertEqual(subprocess.run(["/bin/sh", "-n", str(self.service.wrapper_path)]).returncode, 0) + self.assertIn(self.service.MARKER, self.service.wrapper_path.read_text(encoding="utf-8")) + self.assertEqual(self.service.get("123")["state"], self._state(dxvkFrameRate=60, enableZink=True)) + + def test_dispatch_clears_managed_values_preserves_other_environment_and_appends_config(self): + self.service.set( + "123", + self._state(dxvkFrameRate=30, disableSteamdeckMode=True, disableVkbasalt=True, enableZink=True), + ) + result = self._run( + 123, + "/usr/bin/env", + env={ + "DXVK_CONFIG": "dxgi.syncInterval = 0", + "DXVK_FRAME_RATE": "5", + "ENABLE_GAMESCOPE_WSI": "1", + "DISABLE_VKBASALT": "0", + "MESA_LOADER_DRIVER_OVERRIDE": "llvmpipe", + "MANGOHUD": "1", + }, + ) + values = dict(line.split("=", 1) for line in result.stdout.splitlines() if "=" in line) + self.assertEqual(values["ENABLE_GAMESCOPE_WSI"], "0") + self.assertEqual(values["DXVK_HDR"], "0") + self.assertEqual(values["SteamDeck"], "0") + self.assertEqual(values["DISABLE_VKBASALT"], "1") + self.assertEqual(values["__GLX_VENDOR_LIBRARY_NAME"], "mesa") + self.assertEqual(values["MESA_LOADER_DRIVER_OVERRIDE"], "zink") + self.assertEqual(values["GALLIUM_DRIVER"], "zink") + self.assertEqual(values["DXVK_CONFIG"], "dxgi.syncInterval = 0; dxvk.maxFrameRate = 30") + self.assertEqual(values["MANGOHUD"], "1") + self.assertNotIn("DXVK_FRAME_RATE", values) + self.assertNotIn("ENABLE_VKBASALT", values) + + def test_appid_fallback_and_unmatched_passthrough(self): + self.service.set("123", self._state(disableGamescopeWsi=False, disableHdr=False)) + self.service.set("456", self._state(disableSteamdeckMode=True)) + fallback = subprocess.run( + [str(self.service.wrapper_path), "/usr/bin/env"], + env={"PATH": "/usr/bin:/bin", "SteamAppId": "bad", "SteamGameId": "456"}, + capture_output=True, + text=True, + check=True, + ) + fallback_values = dict(line.split("=", 1) for line in fallback.stdout.splitlines() if "=" in line) + self.assertEqual(fallback_values["SteamDeck"], "0") + self.assertEqual(fallback_values["SteamGameId"], "456") + + passthrough = subprocess.run( + [str(self.service.wrapper_path), "/usr/bin/env"], + env={"PATH": "/usr/bin:/bin", "SteamAppId": "999", "KEEP": "yes", "DXVK_HDR": "1"}, + capture_output=True, + text=True, + check=True, + ) + passthrough_values = dict(line.split("=", 1) for line in passthrough.stdout.splitlines() if "=" in line) + self.assertEqual(passthrough_values["KEEP"], "yes") + self.assertEqual(passthrough_values["DXVK_HDR"], "1") + + def test_flatpak_shortcut_receives_env_arguments_and_original_target(self): + fake_flatpak = self.home / ".local/bin/flatpak" + fake_flatpak.parent.mkdir(parents=True, exist_ok=True) + fake_flatpak.write_text( + "#!/bin/sh\n" + "printf 'ARG:%s\\n' \"$@\"\n", + encoding="utf-8", + ) + fake_flatpak.chmod(0o755) + self.service.set("123", self._state(dxvkFrameRate=20, enableZink=True), str(fake_flatpak)) + result = self._run(123, "run", "com.example.Game", "--windowed", env={"DXVK_CONFIG": "foo=1"}) + args = result.stdout.splitlines() + self.assertEqual(args[0], "ARG:run") + self.assertIn("ARG:--env=SteamAppId=123", args) + self.assertIn("ARG:--env=ENABLE_GAMESCOPE_WSI=0", args) + self.assertIn("ARG:--env=DXVK_HDR=0", args) + self.assertIn("ARG:--env=__GLX_VENDOR_LIBRARY_NAME=mesa", args) + self.assertIn("ARG:--env=MESA_LOADER_DRIVER_OVERRIDE=zink", args) + self.assertIn("ARG:--env=GALLIUM_DRIVER=zink", args) + self.assertIn("ARG:--env=DXVK_CONFIG=foo=1; dxvk.maxFrameRate = 20", args) + self.assertIn("ARG:com.example.Game", args) + self.assertIn("ARG:--windowed", args) + + def test_invalid_state_and_foreign_wrapper_fail_closed(self): + invalid = self.service.set("0", self.service.default_state()) + self.assertFalse(invalid["success"]) + invalid = self.service.set("123", {**self.service.default_state(), "dxvkFrameRate": 61}) + self.assertFalse(invalid["success"]) + + self.service.local_bin_dir.mkdir(parents=True, exist_ok=True) + self.service.wrapper_path.write_text("#!/bin/sh\necho foreign\n", encoding="utf-8") + response = self.service.set("123", self.service.default_state()) + self.assertFalse(response["success"]) + self.assertIn("unowned", response["error"]) + self.assertEqual(self.service.wrapper_path.read_text(encoding="utf-8"), "#!/bin/sh\necho foreign\n") + + def test_remove_keeps_a_safe_owned_passthrough_wrapper(self): + self.service.set("123", self.service.default_state()) + response = self.service.remove("123") + self.assertTrue(response["success"]) + self.assertIsNone(self.service.get("123")["state"]) + self.assertTrue(self.service.wrapper_path.exists()) + result = subprocess.run( + [str(self.service.wrapper_path), "/usr/bin/printf", "ok"], + env={"PATH": "/usr/bin:/bin", "SteamAppId": "123"}, + capture_output=True, + text=True, + check=True, + ) + self.assertEqual(result.stdout, "ok") + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3 From cc1e6f47dd9838b066822162a607d2859c043aff Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Wed, 9 Sep 2026 19:16:30 -0400 Subject: refactor: unify flatpak targets with steam profiles --- tests/test_wrapper_service.py | 79 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'tests/test_wrapper_service.py') diff --git a/tests/test_wrapper_service.py b/tests/test_wrapper_service.py index f17a944..5010d23 100644 --- a/tests/test_wrapper_service.py +++ b/tests/test_wrapper_service.py @@ -123,10 +123,20 @@ class WrapperServiceTests(unittest.TestCase): encoding="utf-8", ) fake_flatpak.chmod(0o755) - self.service.set("123", self._state(dxvkFrameRate=20, enableZink=True), str(fake_flatpak)) + self.service.set( + "123", + self._state(dxvkFrameRate=20, enableZink=True), + str(fake_flatpak), + False, + {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, + ) result = self._run(123, "run", "com.example.Game", "--windowed", env={"DXVK_CONFIG": "foo=1"}) args = result.stdout.splitlines() self.assertEqual(args[0], "ARG:run") + self.assertIn("ARG:--filesystem=" + str(self.service.config_dir) + ":rw", args) + self.assertIn("ARG:--filesystem=" + str(self.home / ".local/share/Steam/steamapps/common/Lossless Scaling") + ":ro", args) + self.assertIn("ARG:--env=LSFGVK_CONFIG=" + str(self.service.config_file_path), args) + self.assertIn("ARG:--env=LSFGVK_FLATPAK=1", args) self.assertIn("ARG:--env=SteamAppId=123", args) self.assertIn("ARG:--env=ENABLE_GAMESCOPE_WSI=0", args) self.assertIn("ARG:--env=DXVK_HDR=0", args) @@ -137,6 +147,73 @@ class WrapperServiceTests(unittest.TestCase): self.assertIn("ARG:com.example.Game", args) self.assertIn("ARG:--windowed", args) + def test_flatpak_full_executable_form_is_preserved(self): + fake_flatpak = self.home / ".local/bin/flatpak" + fake_flatpak.parent.mkdir(parents=True, exist_ok=True) + fake_flatpak.write_text( + "#!/bin/sh\n" + "printf 'ARG:%s\\n' \"$@\"\n", + encoding="utf-8", + ) + fake_flatpak.chmod(0o755) + response = self.service.set( + "123", + self._state(), + f"{fake_flatpak} run com.example.Game", + False, + {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, + ) + self.assertTrue(response["success"]) + result = self._run(123, "--windowed") + args = result.stdout.splitlines() + self.assertEqual(args[0], "ARG:run") + self.assertIn("ARG:com.example.Game", args) + self.assertIn("ARG:--windowed", args) + + def test_flatpak_transport_rejects_non_run_invocation(self): + fake_flatpak = self.home / ".local/bin/flatpak" + fake_flatpak.parent.mkdir(parents=True, exist_ok=True) + fake_flatpak.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8") + fake_flatpak.chmod(0o755) + response = self.service.set( + "123", + self._state(), + str(fake_flatpak), + False, + {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, + ) + self.assertTrue(response["success"]) + result = subprocess.run( + [str(self.service.wrapper_path), "bash", "launch-game.sh"], + env={"PATH": "/usr/bin:/bin", "SteamAppId": "123"}, + capture_output=True, + text=True, + ) + self.assertEqual(result.returncode, 64) + self.assertIn("direct flatpak run", result.stderr) + + def test_flatpak_transport_rejects_external_app_id_change(self): + fake_flatpak = self.home / ".local/bin/flatpak" + fake_flatpak.parent.mkdir(parents=True, exist_ok=True) + fake_flatpak.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8") + fake_flatpak.chmod(0o755) + response = self.service.set( + "123", + self._state(), + str(fake_flatpak), + False, + {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, + ) + self.assertTrue(response["success"]) + result = subprocess.run( + [str(self.service.wrapper_path), "run", "com.other.Game"], + env={"PATH": "/usr/bin:/bin", "SteamAppId": "123"}, + capture_output=True, + text=True, + ) + self.assertEqual(result.returncode, 64) + self.assertIn("application ID changed externally", result.stderr) + def test_invalid_state_and_foreign_wrapper_fail_closed(self): invalid = self.service.set("0", self.service.default_state()) self.assertFalse(invalid["success"]) -- cgit v1.2.3 From 670f36e8cc75da9c8b1b174c24e722657bbf2a56 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Thu, 10 Sep 2026 12:15:05 -0400 Subject: cleanup flatpak handles --- tests/test_wrapper_service.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'tests/test_wrapper_service.py') diff --git a/tests/test_wrapper_service.py b/tests/test_wrapper_service.py index 5010d23..0632d93 100644 --- a/tests/test_wrapper_service.py +++ b/tests/test_wrapper_service.py @@ -170,6 +170,25 @@ class WrapperServiceTests(unittest.TestCase): self.assertIn("ARG:com.example.Game", args) self.assertIn("ARG:--windowed", args) + def test_host_transport_does_not_store_shortcut_target(self): + self.service.set( + "123", + self._state(), + "/usr/bin/flatpak", + False, + {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, + ) + response = self.service.set( + "123", + self._state(), + "/usr/bin/ignored", + False, + {"kind": "host"}, + ) + self.assertTrue(response["success"]) + self.assertIsNone(response["shortcut_exe"]) + self.assertIsNone(self.service.get("123")["shortcut_exe"]) + def test_flatpak_transport_rejects_non_run_invocation(self): fake_flatpak = self.home / ".local/bin/flatpak" fake_flatpak.parent.mkdir(parents=True, exist_ok=True) -- cgit v1.2.3 From c6a2abf2f0cab99a8a41709a4bbf6e391a112b4f Mon Sep 17 00:00:00 2001 From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> Date: Thu, 10 Sep 2026 15:48:00 -0400 Subject: test: simplify workaround wrapper coverage --- tests/test_wrapper_service.py | 149 +++++++----------------------------------- 1 file changed, 23 insertions(+), 126 deletions(-) (limited to 'tests/test_wrapper_service.py') diff --git a/tests/test_wrapper_service.py b/tests/test_wrapper_service.py index 0632d93..5c291c7 100644 --- a/tests/test_wrapper_service.py +++ b/tests/test_wrapper_service.py @@ -1,4 +1,3 @@ -import os import subprocess import sys import tempfile @@ -24,10 +23,10 @@ class WrapperServiceTests(unittest.TestCase): self.home.mkdir(parents=True) self.service = WrapperService() self.service.user_home = self.home - self.service.local_bin_dir = self.home / ".local/bin" self.service.config_dir = self.home / ".config/lsfg-vk" + self.service.config_file_path = self.service.config_dir / "conf.toml" self.service.sidecar_path = self.service.config_dir / "workarounds.json" - self.service.wrapper_path = self.service.local_bin_dir / "lsfg" + self.service.wrapper_path = self.home / ".lsfg" def tearDown(self): self.tempdir.cleanup() @@ -59,7 +58,7 @@ class WrapperServiceTests(unittest.TestCase): self.assertIn(self.service.MARKER, self.service.wrapper_path.read_text(encoding="utf-8")) self.assertEqual(self.service.get("123")["state"], self._state(dxvkFrameRate=60, enableZink=True)) - def test_dispatch_clears_managed_values_preserves_other_environment_and_appends_config(self): + def test_dispatch_exports_appid_config_and_workarounds(self): self.service.set( "123", self._state(dxvkFrameRate=30, disableSteamdeckMode=True, disableVkbasalt=True, enableZink=True), @@ -71,12 +70,16 @@ class WrapperServiceTests(unittest.TestCase): "DXVK_CONFIG": "dxgi.syncInterval = 0", "DXVK_FRAME_RATE": "5", "ENABLE_GAMESCOPE_WSI": "1", + "DISABLE_LSFGVK": "1", + "DISABLE_LSFG": "1", "DISABLE_VKBASALT": "0", "MESA_LOADER_DRIVER_OVERRIDE": "llvmpipe", "MANGOHUD": "1", }, ) values = dict(line.split("=", 1) for line in result.stdout.splitlines() if "=" in line) + self.assertEqual(values["SteamAppId"], "123") + self.assertEqual(values["LSFGVK_CONFIG"], str(self.service.config_file_path)) self.assertEqual(values["ENABLE_GAMESCOPE_WSI"], "0") self.assertEqual(values["DXVK_HDR"], "0") self.assertEqual(values["SteamDeck"], "0") @@ -88,6 +91,20 @@ class WrapperServiceTests(unittest.TestCase): self.assertEqual(values["MANGOHUD"], "1") self.assertNotIn("DXVK_FRAME_RATE", values) self.assertNotIn("ENABLE_VKBASALT", values) + self.assertNotIn("DISABLE_LSFGVK", values) + self.assertNotIn("DISABLE_LSFG", values) + + def test_wrapper_is_transport_agnostic(self): + self.service.set("123", self._state()) + fake = self.home / "target" + fake.write_text("#!/bin/sh\nprintf '%s\\n' \"$@\"\n", encoding="utf-8") + fake.chmod(0o755) + result = self._run(123, str(fake), "run", "org.example.Game") + self.assertEqual(result.stdout.splitlines(), ["run", "org.example.Game"]) + content = self.service.wrapper_path.read_text(encoding="utf-8") + self.assertNotIn("flatpakAppId", content) + self.assertNotIn("shortcut_exe", content) + self.assertNotIn("--filesystem", content) def test_appid_fallback_and_unmatched_passthrough(self): self.service.set("123", self._state(disableGamescopeWsi=False, disableHdr=False)) @@ -101,7 +118,7 @@ class WrapperServiceTests(unittest.TestCase): ) fallback_values = dict(line.split("=", 1) for line in fallback.stdout.splitlines() if "=" in line) self.assertEqual(fallback_values["SteamDeck"], "0") - self.assertEqual(fallback_values["SteamGameId"], "456") + self.assertEqual(fallback_values["SteamAppId"], "456") passthrough = subprocess.run( [str(self.service.wrapper_path), "/usr/bin/env"], @@ -114,139 +131,19 @@ class WrapperServiceTests(unittest.TestCase): self.assertEqual(passthrough_values["KEEP"], "yes") self.assertEqual(passthrough_values["DXVK_HDR"], "1") - def test_flatpak_shortcut_receives_env_arguments_and_original_target(self): - fake_flatpak = self.home / ".local/bin/flatpak" - fake_flatpak.parent.mkdir(parents=True, exist_ok=True) - fake_flatpak.write_text( - "#!/bin/sh\n" - "printf 'ARG:%s\\n' \"$@\"\n", - encoding="utf-8", - ) - fake_flatpak.chmod(0o755) - self.service.set( - "123", - self._state(dxvkFrameRate=20, enableZink=True), - str(fake_flatpak), - False, - {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, - ) - result = self._run(123, "run", "com.example.Game", "--windowed", env={"DXVK_CONFIG": "foo=1"}) - args = result.stdout.splitlines() - self.assertEqual(args[0], "ARG:run") - self.assertIn("ARG:--filesystem=" + str(self.service.config_dir) + ":rw", args) - self.assertIn("ARG:--filesystem=" + str(self.home / ".local/share/Steam/steamapps/common/Lossless Scaling") + ":ro", args) - self.assertIn("ARG:--env=LSFGVK_CONFIG=" + str(self.service.config_file_path), args) - self.assertIn("ARG:--env=LSFGVK_FLATPAK=1", args) - self.assertIn("ARG:--env=SteamAppId=123", args) - self.assertIn("ARG:--env=ENABLE_GAMESCOPE_WSI=0", args) - self.assertIn("ARG:--env=DXVK_HDR=0", args) - self.assertIn("ARG:--env=__GLX_VENDOR_LIBRARY_NAME=mesa", args) - self.assertIn("ARG:--env=MESA_LOADER_DRIVER_OVERRIDE=zink", args) - self.assertIn("ARG:--env=GALLIUM_DRIVER=zink", args) - self.assertIn("ARG:--env=DXVK_CONFIG=foo=1; dxvk.maxFrameRate = 20", args) - self.assertIn("ARG:com.example.Game", args) - self.assertIn("ARG:--windowed", args) - - def test_flatpak_full_executable_form_is_preserved(self): - fake_flatpak = self.home / ".local/bin/flatpak" - fake_flatpak.parent.mkdir(parents=True, exist_ok=True) - fake_flatpak.write_text( - "#!/bin/sh\n" - "printf 'ARG:%s\\n' \"$@\"\n", - encoding="utf-8", - ) - fake_flatpak.chmod(0o755) - response = self.service.set( - "123", - self._state(), - f"{fake_flatpak} run com.example.Game", - False, - {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, - ) - self.assertTrue(response["success"]) - result = self._run(123, "--windowed") - args = result.stdout.splitlines() - self.assertEqual(args[0], "ARG:run") - self.assertIn("ARG:com.example.Game", args) - self.assertIn("ARG:--windowed", args) - - def test_host_transport_does_not_store_shortcut_target(self): - self.service.set( - "123", - self._state(), - "/usr/bin/flatpak", - False, - {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, - ) - response = self.service.set( - "123", - self._state(), - "/usr/bin/ignored", - False, - {"kind": "host"}, - ) - self.assertTrue(response["success"]) - self.assertIsNone(response["shortcut_exe"]) - self.assertIsNone(self.service.get("123")["shortcut_exe"]) - - def test_flatpak_transport_rejects_non_run_invocation(self): - fake_flatpak = self.home / ".local/bin/flatpak" - fake_flatpak.parent.mkdir(parents=True, exist_ok=True) - fake_flatpak.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8") - fake_flatpak.chmod(0o755) - response = self.service.set( - "123", - self._state(), - str(fake_flatpak), - False, - {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, - ) - self.assertTrue(response["success"]) - result = subprocess.run( - [str(self.service.wrapper_path), "bash", "launch-game.sh"], - env={"PATH": "/usr/bin:/bin", "SteamAppId": "123"}, - capture_output=True, - text=True, - ) - self.assertEqual(result.returncode, 64) - self.assertIn("direct flatpak run", result.stderr) - - def test_flatpak_transport_rejects_external_app_id_change(self): - fake_flatpak = self.home / ".local/bin/flatpak" - fake_flatpak.parent.mkdir(parents=True, exist_ok=True) - fake_flatpak.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8") - fake_flatpak.chmod(0o755) - response = self.service.set( - "123", - self._state(), - str(fake_flatpak), - False, - {"kind": "flatpak", "flatpakAppId": "com.example.Game"}, - ) - self.assertTrue(response["success"]) - result = subprocess.run( - [str(self.service.wrapper_path), "run", "com.other.Game"], - env={"PATH": "/usr/bin:/bin", "SteamAppId": "123"}, - capture_output=True, - text=True, - ) - self.assertEqual(result.returncode, 64) - self.assertIn("application ID changed externally", result.stderr) - def test_invalid_state_and_foreign_wrapper_fail_closed(self): invalid = self.service.set("0", self.service.default_state()) self.assertFalse(invalid["success"]) invalid = self.service.set("123", {**self.service.default_state(), "dxvkFrameRate": 61}) self.assertFalse(invalid["success"]) - self.service.local_bin_dir.mkdir(parents=True, exist_ok=True) self.service.wrapper_path.write_text("#!/bin/sh\necho foreign\n", encoding="utf-8") response = self.service.set("123", self.service.default_state()) self.assertFalse(response["success"]) self.assertIn("unowned", response["error"]) self.assertEqual(self.service.wrapper_path.read_text(encoding="utf-8"), "#!/bin/sh\necho foreign\n") - def test_remove_keeps_a_safe_owned_passthrough_wrapper(self): + def test_remove_keeps_safe_passthrough_wrapper(self): self.service.set("123", self.service.default_state()) response = self.service.remove("123") self.assertTrue(response["success"]) -- cgit v1.2.3 From 954b2abc47d8772211cb8ecee523900f823184e8 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Fri, 11 Sep 2026 11:08:12 -0400 Subject: better uninstall cleanup --- tests/test_wrapper_service.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'tests/test_wrapper_service.py') diff --git a/tests/test_wrapper_service.py b/tests/test_wrapper_service.py index 5c291c7..20a08ff 100644 --- a/tests/test_wrapper_service.py +++ b/tests/test_wrapper_service.py @@ -158,6 +158,35 @@ class WrapperServiceTests(unittest.TestCase): ) self.assertEqual(result.stdout, "ok") + def test_purge_removes_owned_wrapper_and_state(self): + self.service.set("123", self._state(), non_steam=True) + self.assertTrue(self.service.get("123")["non_steam"]) + self.assertEqual(self.service.list_apps()["apps"][0]["non_steam"], True) + response = self.service.purge() + self.assertTrue(response["success"]) + self.assertEqual(response["removed_files"], [str(self.service.wrapper_path), str(self.service.sidecar_path)]) + self.assertFalse(self.service.wrapper_path.exists()) + self.assertFalse(self.service.sidecar_path.exists()) + + def test_purge_refuses_foreign_wrapper(self): + self.service.wrapper_path.write_text("#!/bin/sh\necho foreign\n", encoding="utf-8") + response = self.service.purge() + self.assertFalse(response["success"]) + self.assertIn("unowned", response["error"]) + self.assertTrue(self.service.wrapper_path.exists()) + + def test_purge_refuses_invalid_state(self): + self.service.config_dir.mkdir(parents=True, exist_ok=True) + self.service.sidecar_path.write_text("not json", encoding="utf-8") + self.service.wrapper_path.write_text( + f"#!/bin/sh\n{self.service.MARKER}\nexec \"$@\"\n", + encoding="utf-8", + ) + response = self.service.purge() + self.assertFalse(response["success"]) + self.assertTrue(self.service.wrapper_path.exists()) + self.assertTrue(self.service.sidecar_path.exists()) + if __name__ == "__main__": unittest.main() -- cgit v1.2.3 From c7ca9c7ec2660d279f5e6957ef882390a8783667 Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Fri, 11 Sep 2026 11:47:16 -0400 Subject: handle decky uninstall to avoid unlaunchable game wrappers --- tests/test_wrapper_service.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests/test_wrapper_service.py') diff --git a/tests/test_wrapper_service.py b/tests/test_wrapper_service.py index 20a08ff..46e029b 100644 --- a/tests/test_wrapper_service.py +++ b/tests/test_wrapper_service.py @@ -187,6 +187,24 @@ class WrapperServiceTests(unittest.TestCase): self.assertTrue(self.service.wrapper_path.exists()) self.assertTrue(self.service.sidecar_path.exists()) + def test_neutralize_leaves_dependency_free_passthrough_wrapper(self): + self.service.set("123", self._state()) + response = self.service.neutralize() + self.assertTrue(response["success"]) + self.assertFalse(self.service.sidecar_path.exists()) + self.assertTrue(self.service.wrapper_path.exists()) + content = self.service.wrapper_path.read_text(encoding="utf-8") + self.assertIn(self.service.MARKER, content) + self.assertNotIn("LSFGVK_CONFIG", content) + self.assertEqual(self._run(123, "/usr/bin/printf", "ok").stdout, "ok") + + def test_neutralize_refuses_foreign_wrapper(self): + self.service.wrapper_path.write_text("#!/bin/sh\necho foreign\n", encoding="utf-8") + response = self.service.neutralize() + self.assertFalse(response["success"]) + self.assertIn("unowned", response["error"]) + self.assertEqual(self.service.wrapper_path.read_text(encoding="utf-8"), "#!/bin/sh\necho foreign\n") + if __name__ == "__main__": unittest.main() -- cgit v1.2.3