"""Jinja2 sandbox + regex_extract tests.""" from __future__ import annotations import pytest from mimic.templating.filters import regex_extract from mimic.templating.sandbox import ( CleanupRenderer, RenderError, StepOutputs, render_cleanup, ) class TestRegexExtract: def test_returns_capture_group(self) -> None: assert regex_extract("hello world", r"hello (\w+)") == "world" def test_default_when_no_match(self) -> None: assert regex_extract("hello", r"foo(\d+)", default="N/A") == "N/A" def test_none_input_returns_default(self) -> None: assert regex_extract(None, r"x", default="empty") == "empty" def test_supports_group_zero(self) -> None: assert regex_extract("abc123", r"\w+\d+", group=0) == "abc123" class TestCleanupRenderer: def setup_method(self) -> None: self.renderer = CleanupRenderer() def test_render_params(self) -> None: out = self.renderer.render( "echo {{ params.target }}", params={"target": "WIN-01"}, ) assert out == "echo WIN-01" def test_render_outputs_text(self) -> None: out = self.renderer.render( 'echo "{{ outputs.text }}"', outputs=StepOutputs(text="captured"), ) assert out == 'echo "captured"' def test_regex_extract_filter(self) -> None: out = self.renderer.render( r"{{ outputs.text | regex_extract('pid=(\\d+)') }}", outputs=StepOutputs(text="status: pid=4242 user=svc"), ) assert out == "4242" def test_strict_undefined_raises(self) -> None: with pytest.raises(RenderError): self.renderer.render("{{ params.does_not_exist }}", params={}) def test_sandbox_forbids_attribute_access(self) -> None: with pytest.raises(RenderError): self.renderer.render( "{{ ().__class__.__bases__[0].__subclasses__() }}", params={}, ) def test_module_singleton_round_trip(self) -> None: out = render_cleanup("hello {{ params.x }}", params={"x": "there"}) assert out == "hello there" class TestStepOutputsBlob: def test_blob_returns_empty_when_no_path(self) -> None: out = StepOutputs(text="x") assert out.blob() == "" def test_blob_caps_size(self, tmp_path) -> None: blob = tmp_path / "evidence.bin" blob.write_bytes(b"A" * 1024) out = StepOutputs(blob_path=blob, blob_max_bytes=10) assert out.blob() == "A" * 10