"""Sandbox narzędzi plikowych to ostatnia linia obrony - testujemy go jak zabezpieczenie, nie jak feature.""" import pytest from agentic_codemod.tools import WorkspaceTools from agentic_codemod.tools.workspace import WorkspaceError @pytest.fixture() def workspace(acme_app, settings, audit): return WorkspaceTools(acme_app, settings, audit) def test_odczyt_pliku_zwraca_numerowane_linie(workspace): content = workspace.read_file("src/acme_app/notifier.py") assert " 1| " in content def test_wyjscie_poza_repozytorium_jest_zabronione(workspace): with pytest.raises(WorkspaceError, match="poza repozytorium"): workspace.read_file("../../etc/passwd") @pytest.mark.parametrize("path", [".gitlab-ci.yml", ".git/config", "deploy/secret.env", "app.pem"]) def test_sciezki_objete_zakazem_sa_blokowane(workspace, path): with pytest.raises(WorkspaceError, match="zakaz|poza repozytorium"): workspace.write_file(path, "cokolwiek") def test_replace_wymaga_jednoznacznego_fragmentu(workspace): with pytest.raises(WorkspaceError, match="występuje 2 razy"): workspace.replace_in_file( "src/acme_app/notifier.py", " client = Client(api_key=api_key, endpoint=endpoint)\n", " client = AcmeClient()\n", ) def test_replace_bez_dopasowania_daje_wskazowke_nie_wyjatek_techniczny(workspace): with pytest.raises(WorkspaceError, match="Odczytaj plik ponownie"): workspace.replace_in_file("src/acme_app/notifier.py", "czegoś takiego tu nie ma", "x") def test_udana_edycja_jest_rejestrowana(workspace): workspace.replace_in_file("src/acme_app/notifier.py", "from acme import Client", "from acme import AcmeClient") assert "src/acme_app/notifier.py" in workspace.changed_files assert any(entry["tool"] == "replace_in_file" and entry["ok"] for entry in workspace.audit.entries) def test_budzet_zmienionych_plikow_jest_egzekwowany(workspace, settings): settings.max_files_changed = 1 workspace.write_file("a.py", "x = 1\n") with pytest.raises(WorkspaceError, match="budżet"): workspace.write_file("b.py", "y = 2\n") def test_wyszukiwanie_zwraca_dopasowania(workspace): assert "notifier.py" in workspace.search_repo("from acme import", "*.py")