"""starlark-apps PixletRenderer: what reaches Pixlet, and what counts as a render. Three things a Starlark app can do that the renderer got wrong: * put a "|" in a config value -- a shell metacharacter filter dropped the whole key, though the command is a list and no shell is involved; * render nothing -- Pixlet exits 0 and writes a 0-byte file, which was reported as a successful render; * compute its schema at runtime -- the source parser can only read option lists that are written out literally, so a dropdown fed by a live API call came back empty. """ import importlib.util import json import subprocess import sys from pathlib import Path from unittest.mock import patch import pytest PLUGIN_DIR = Path(__file__).resolve().parent.parent / "plugin-repos" / "starlark-apps" @pytest.fixture(scope="module") def renderer_module(): if not PLUGIN_DIR.exists(): pytest.skip("starlark-apps plugin is not checked out") sys.path.insert(0, str(PLUGIN_DIR)) try: spec = importlib.util.spec_from_file_location( "pixlet_renderer_under_test", PLUGIN_DIR / "pixlet_renderer.py") module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module except Exception as e: # noqa: BLE001 - optional deps may be absent pytest.skip(f"pixlet_renderer is not importable here: {e}") finally: sys.path.remove(str(PLUGIN_DIR)) @pytest.fixture def renderer(renderer_module): """A renderer with a known binary and __init__'s binary search bypassed.""" r = renderer_module.PixletRenderer.__new__(renderer_module.PixletRenderer) r.timeout = 30 r.pixlet_binary = "/usr/local/bin/pixlet" return r def _completed(returncode=0, stdout="", stderr=""): return subprocess.CompletedProcess(args=[], returncode=returncode, stdout=stdout, stderr=stderr) class TestConfigValuesReachPixlet: """cmd is a list and there is no shell=True, so nothing here is ever interpreted by a shell -- the filter is defence in depth, not a boundary.""" def _args_for(self, renderer, tmp_path, config): star = tmp_path / "app.star" star.write_text("# app", encoding="utf-8") out = tmp_path / "out.webp" def fake_run(cmd, **kw): out.write_bytes(b"webp-bytes") fake_run.cmd = cmd return _completed() with patch.object(subprocess, "run", side_effect=fake_run): renderer.render(str(tmp_path / "app.star"), str(out), config=config) return fake_run.cmd def test_a_pipe_in_a_value_is_passed_through(self, renderer, tmp_path): """Real apps use "|" as a separator inside one config value.""" args = self._args_for(renderer, tmp_path, {"sign_id": "I-476 North|175659"}) assert "sign_id=I-476 North|175659" in args def test_a_dropped_value_does_not_take_the_key_with_it(self, renderer, tmp_path): args = self._args_for(renderer, tmp_path, {"sign_id": "I-476 North|175659"}) assert any(a.startswith("sign_id=") for a in args) @pytest.mark.parametrize("value", [ "$(rm -rf /)", "`whoami`", "a;b", "a&b", "a>b", "a