From 227d8107aa06404ad13c98db21079006292c7e89 Mon Sep 17 00:00:00 2001 From: Piotr Dec Date: Tue, 25 Nov 2025 01:22:08 +0100 Subject: [PATCH] test: cleanup --- app/services/mo.py | 19 ++++++------------- app/services/passwords.py | 33 +++++++++++++++++++++++++++------ tests/files/test1/test.mo.yaml | 1 + tests/test_mo.py | 26 ++++++++++++++------------ 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/app/services/mo.py b/app/services/mo.py index 33fa240..84792f7 100644 --- a/app/services/mo.py +++ b/app/services/mo.py @@ -7,13 +7,9 @@ from injectable import injectable, autowired, Autowired from app.services import Passwords -class ComplexValueTemplate(Template): - # Pozwala na kropki w nazwach placeholderów, np. ${user.name.first} - idpattern = r'[_a-zA-Z][_a-zA-Z0-9.]*' - - -class SimpleValueTemplate(ComplexValueTemplate): - delimiter = '%' +class ValueTemplate(Template): + # Pozwala na kropki i ukośniki w nazwach placeholderów, np. ${user.name/first} + idpattern = r'[_a-zA-Z][_a-zA-Z0-9.\/]*' @injectable @@ -26,12 +22,9 @@ class Mo: raw = '' with open(mo_file, "r") as mo: raw = mo.read() - cmp = ComplexValueTemplate(raw) - rendered = cmp.substitute(self._passwords.get_values(cmp.get_identifiers())) - smp = SimpleValueTemplate(rendered) - ids = [_id + '.password' for _id in smp.get_identifiers()] - mappings = {k.replace('.password', ''): v for k, v in self._passwords.get_values(ids).items()} - rendered = smp.substitute(mappings) + parsed = ValueTemplate(raw) + mappings = self._passwords.get_values(parsed.get_identifiers()) + rendered = parsed.safe_substitute(mappings) de_mo_ified = str(mo_file).replace(".mo", "") with open(de_mo_ified, "w") as mo: mo.write(rendered) diff --git a/app/services/passwords.py b/app/services/passwords.py index 39ff368..054e234 100644 --- a/app/services/passwords.py +++ b/app/services/passwords.py @@ -6,6 +6,30 @@ import keyring from injectable import injectable from pykeepass import PyKeePass, create_database +class KeyRequest: + def __init__(self, prompt: str): + self.field_name = None + self.entry_name = None + self.path = None + self._parse_prompt(prompt) + + def _parse_prompt(self, prompt: str): + + pass + # k_parts = k.split("/") + # field_name = None + # match len(k_parts): + # case 1: + # field_name = 'password' + # case 2: + # field_name = k_parts[1] + # k = k_parts[0] + # case _: + # output[k] = None + # continue + # key_parts = k.split(".") + # path = key_parts[:-1] if len(key_parts) > 2 else None + # entry_name = key_parts[-1] @injectable(singleton=True) class Passwords: @@ -28,13 +52,10 @@ class Passwords: def get_values(self, keys: list[str]) -> dict[str, str]: output = {} for k in keys: - key_parts = k.split(".") - path = key_parts[:-1] if len(key_parts) > 2 else None - entry_name = key_parts[-2] - field_name = key_parts[-1] + request = KeyRequest(k) with self.open() as kp: - kp_entry = kp.find_entries(path=path, first=True, title=entry_name) - output[k] = self._get_field_value(kp_entry, field_name) + kp_entry = kp.find_entries(path=request.path, first=True, title=request.entry_name) + output[k] = self._get_field_value(kp_entry, request.field_name) return output @staticmethod diff --git a/tests/files/test1/test.mo.yaml b/tests/files/test1/test.mo.yaml index f2aaac7..11bd6b5 100644 --- a/tests/files/test1/test.mo.yaml +++ b/tests/files/test1/test.mo.yaml @@ -2,3 +2,4 @@ value: ${sample} nested: ${some.nested.value} custom: ${custom/field} uname: ${sample/username} +invalid: ${double/slash/example} diff --git a/tests/test_mo.py b/tests/test_mo.py index 8237e8d..01e63c0 100644 --- a/tests/test_mo.py +++ b/tests/test_mo.py @@ -7,7 +7,7 @@ from app.services import Passwords from app.services.mo import Mo -@pytest.fixture +@pytest.fixture(scope='class') def target_path(): p = Path('tests/files/test1/test.yaml') # posprzątaj przed testem, gdyby plik istniał z poprzednich uruchomień @@ -19,7 +19,7 @@ def target_path(): p.unlink() -@pytest.fixture +@pytest.fixture(scope='class') def test1_content(target_path: Path): mo = Mo(Passwords()) mo.process(Path('tests/files/test1/test.mo.yaml').absolute()) @@ -29,20 +29,22 @@ def test1_content(target_path: Path): content = target_path.read_text() assert '${' not in content - return yaml.load(content, Loader=yaml.FullLoader) + yield yaml.load(content, Loader=yaml.FullLoader) -def test_simple(test1_content: dict): - assert test1_content['value'] == 'some_pass' +class TestParsing: + def test_simple(self, test1_content: dict): + assert test1_content['value'] == 'some_pass' -def test_nested(test1_content: dict): - assert test1_content['nested'] == 'nested_pass' + def test_nested(self, test1_content: dict): + assert test1_content['nested'] == 'nested_pass' + def test_custom_field(self, test1_content: dict): + assert test1_content['custom'] == 'custom_content' -def test_custom_field(test1_content: dict): - assert test1_content['custom'] == 'custom_content' + def test_username_field(self, test1_content: dict): + assert test1_content['uname'] == 'sample_username' - -def test_username_field(test1_content: dict): - assert test1_content['uname'] == 'sample_username' + def test_invalid_key(self, test1_content: dict): + assert test1_content.get('invalid') == 'None'