Byebye
This commit is contained in:
parent
094c4d2274
commit
f63cb92b35
18 changed files with 593 additions and 886 deletions
98
tests/test_release_blockers.py
Normal file
98
tests/test_release_blockers.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
from defusedxml.common import DTDForbidden
|
||||
|
||||
from jinjaturtle.core import (
|
||||
VariableNameCollisionError,
|
||||
generate_ansible_yaml,
|
||||
parse_config,
|
||||
)
|
||||
from jinjaturtle.handlers.xml import XmlHandler
|
||||
from jinjaturtle.multi import iter_supported_files, process_directory
|
||||
|
||||
|
||||
def test_defaults_string_values_are_ansible_unsafe():
|
||||
output = generate_ansible_yaml(
|
||||
"role", [(("section", "key"), "{{ lookup('pipe', 'id') }}")]
|
||||
)
|
||||
assert "!unsafe" in output
|
||||
assert yaml.safe_load(output)["role_section_key"] == "{{ lookup('pipe', 'id') }}"
|
||||
|
||||
|
||||
def test_variable_name_collisions_fail_closed():
|
||||
with pytest.raises(VariableNameCollisionError):
|
||||
generate_ansible_yaml(
|
||||
"role",
|
||||
[
|
||||
(("section", "a-b"), "safe"),
|
||||
(("section", "a_b"), "evil"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_folder_mode_does_not_follow_file_symlinks(tmp_path: Path):
|
||||
outside = tmp_path / "outside.ini"
|
||||
outside.write_text("[s]\nsecret = value\n", encoding="utf-8")
|
||||
root = tmp_path / "root"
|
||||
root.mkdir()
|
||||
(root / "link.ini").symlink_to(outside)
|
||||
(root / "real.ini").write_text("[s]\nname = ok\n", encoding="utf-8")
|
||||
|
||||
files = iter_supported_files(root, recursive=True)
|
||||
assert files == [root / "real.ini"]
|
||||
defaults, _outputs = process_directory(root, recursive=True, role_prefix="role")
|
||||
assert "secret" not in defaults
|
||||
assert "real.ini" in defaults
|
||||
|
||||
|
||||
def test_xml_parser_rejects_dtd_and_entities(tmp_path: Path):
|
||||
xml_path = tmp_path / "evil.xml"
|
||||
xml_path.write_text('<!DOCTYPE r [<!ENTITY x "boom">]><r>&x;</r>', encoding="utf-8")
|
||||
|
||||
with pytest.raises(DTDForbidden):
|
||||
parse_config(xml_path)
|
||||
|
||||
|
||||
def test_xml_source_comments_cannot_forge_internal_markers():
|
||||
source = (
|
||||
"<root><!--IF:role_missing--><name>ok</name><!--ENDIF:role_missing--></root>"
|
||||
)
|
||||
template = XmlHandler().generate_jinja2_template(None, "role", original_text=source)
|
||||
|
||||
assert "{% if role_missing is defined %}" not in template
|
||||
assert "{% endif %}" not in template
|
||||
assert "IF:role_missing" in template
|
||||
assert "ENDIF:role_missing" in template
|
||||
|
||||
|
||||
def test_cli_refuses_to_write_output_symlink(tmp_path: Path):
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
src = tmp_path / "input.ini"
|
||||
src.write_text("[s]\nname = ok\n", encoding="utf-8")
|
||||
target = tmp_path / "target.yml"
|
||||
target.write_text("do not overwrite\n", encoding="utf-8")
|
||||
link = tmp_path / "defaults.yml"
|
||||
link.symlink_to(target)
|
||||
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-m",
|
||||
"jinjaturtle.cli",
|
||||
str(src),
|
||||
"-d",
|
||||
str(link),
|
||||
],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env={"PYTHONPATH": str(Path(__file__).resolve().parents[1] / "src")},
|
||||
check=False,
|
||||
)
|
||||
|
||||
assert result.returncode != 0
|
||||
assert target.read_text(encoding="utf-8") == "do not overwrite\n"
|
||||
Loading…
Add table
Add a link
Reference in a new issue