@@ -163,3 +163,91 @@ def test_llm_env_overrides(monkeypatch, tmp_path: Path) -> None:
163163 assert llm ["base_url" ] == "http://localhost:11434/v1"
164164 assert llm ["api_key" ] == "sk-test"
165165 assert llm ["model" ] == "llama3"
166+
167+
168+
169+ # ---------------------------------------------------------------------------
170+ # allow-dir / remove-dir / list-allowed-dirs subcommand tests
171+ # ---------------------------------------------------------------------------
172+
173+
174+ def test_allow_dir_adds_current_directory (monkeypatch , tmp_path : Path ) -> None :
175+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
176+ monkeypatch .chdir (tmp_path )
177+
178+ result = runner .invoke (app , ["config" , "allow-dir" ])
179+ assert result .exit_code == 0 , result .stdout
180+ assert str (tmp_path ) in result .stdout
181+
182+
183+ def test_allow_dir_accepts_explicit_path (monkeypatch , tmp_path : Path ) -> None :
184+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
185+ target = tmp_path / "myproject"
186+ target .mkdir ()
187+
188+ result = runner .invoke (app , ["config" , "allow-dir" , str (target )])
189+ assert result .exit_code == 0 , result .stdout
190+ assert str (target ) in result .stdout
191+
192+
193+ def test_allow_dir_rejects_nonexistent_path (monkeypatch , tmp_path : Path ) -> None :
194+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
195+
196+ result = runner .invoke (app , ["config" , "allow-dir" , str (tmp_path / "nonexistent" )])
197+ assert result .exit_code == 1
198+
199+
200+ def test_allow_dir_rejects_home_directory (monkeypatch , tmp_path : Path ) -> None :
201+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
202+ home = str (Path .home ())
203+
204+ result = runner .invoke (app , ["config" , "allow-dir" , home ])
205+ assert result .exit_code == 1
206+ assert "protected" in result .stdout
207+
208+
209+ def test_allow_dir_rejects_root_directory (monkeypatch , tmp_path : Path ) -> None :
210+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
211+
212+ result = runner .invoke (app , ["config" , "allow-dir" , "/" ])
213+ assert result .exit_code == 1
214+ assert "protected" in result .stdout
215+
216+
217+ def test_remove_dir_removes_allowed_directory (monkeypatch , tmp_path : Path ) -> None :
218+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
219+ target = tmp_path / "myproject"
220+ target .mkdir ()
221+
222+ runner .invoke (app , ["config" , "allow-dir" , str (target )])
223+ result = runner .invoke (app , ["config" , "remove-dir" , str (target )])
224+ assert result .exit_code == 0 , result .stdout
225+ assert str (target ) in result .stdout
226+
227+
228+ def test_remove_dir_fails_when_not_in_list (monkeypatch , tmp_path : Path ) -> None :
229+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
230+ target = tmp_path / "myproject"
231+ target .mkdir ()
232+
233+ result = runner .invoke (app , ["config" , "remove-dir" , str (target )])
234+ assert result .exit_code == 1
235+
236+
237+ def test_list_allowed_dirs_shows_added_directories (monkeypatch , tmp_path : Path ) -> None :
238+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
239+ target = tmp_path / "myproject"
240+ target .mkdir ()
241+
242+ runner .invoke (app , ["config" , "allow-dir" , str (target )])
243+ result = runner .invoke (app , ["config" , "list-allowed-dirs" ])
244+ assert result .exit_code == 0 , result .stdout
245+ assert str (target ) in result .stdout
246+
247+
248+ def test_list_allowed_dirs_empty (monkeypatch , tmp_path : Path ) -> None :
249+ monkeypatch .setenv ("VP_CONFIG_DIR" , str (tmp_path / "cfg" ))
250+
251+ result = runner .invoke (app , ["config" , "list-allowed-dirs" ])
252+ assert result .exit_code == 0
253+ assert "No directories" in result .stdout
0 commit comments