|
6 | 6 | import pytest |
7 | 7 |
|
8 | 8 | import ucode.skills_download as sd |
9 | | -from ucode.skills_download import skill_dir_roots, write_skill |
| 9 | +from ucode.skills_download import ( |
| 10 | + existing_skill_on_disk, |
| 11 | + should_download_skill, |
| 12 | + skill_dir_roots, |
| 13 | + write_skill, |
| 14 | +) |
10 | 15 |
|
11 | 16 | WS = "https://example.databricks.com" |
12 | 17 |
|
@@ -237,50 +242,56 @@ def test_missing_directory_rejected(self, tmp_path): |
237 | 242 | skill_dir_roots(str(tmp_path / "nope")) |
238 | 243 |
|
239 | 244 |
|
240 | | -def _write(roots, leaf, files, *, location="main.default"): |
241 | | - return write_skill(roots, leaf, files, location=location) |
242 | | - |
243 | | - |
244 | | -class TestWriteSkill: |
245 | | - def test_writes_bundle_into_every_root(self, tmp_path): |
| 245 | +class TestShouldDownloadSkill: |
| 246 | + def test_new_skill_is_downloaded(self, tmp_path): |
246 | 247 | roots = skill_dir_roots(str(tmp_path)) |
247 | | - files = {"SKILL.md": b"# skill", "scripts/run.py": b"print(1)"} |
248 | | - |
249 | | - _write(roots, "triage", files) |
250 | 248 |
|
251 | | - for root in roots: |
252 | | - assert (root / "triage/SKILL.md").read_bytes() == b"# skill" |
253 | | - assert (root / "triage/scripts/run.py").read_bytes() == b"print(1)" |
| 249 | + assert should_download_skill(roots, "triage", location="main.default") |
254 | 250 |
|
255 | 251 | def test_existing_skill_prompt_keep(self, tmp_path, monkeypatch): |
256 | 252 | roots = skill_dir_roots(str(tmp_path)) |
257 | | - _write(roots, "triage", {"SKILL.md": b"from-main"}, location="main.default") |
| 253 | + write_skill(roots, "triage", {"SKILL.md": b"from-main"}) |
258 | 254 |
|
259 | 255 | monkeypatch.setattr(sd, "prompt_yes_no", lambda _: False) |
260 | | - _write(roots, "triage", {"SKILL.md": b"from-ml"}, location="ml.prod") |
261 | 256 |
|
262 | | - assert (roots[0] / "triage/SKILL.md").read_bytes() == b"from-main" |
| 257 | + assert not should_download_skill(roots, "triage", location="ml.prod") |
263 | 258 |
|
264 | 259 | def test_existing_skill_prompt_overwrite(self, tmp_path, monkeypatch): |
265 | 260 | roots = skill_dir_roots(str(tmp_path)) |
266 | | - _write(roots, "triage", {"SKILL.md": b"from-main"}, location="main.default") |
| 261 | + write_skill(roots, "triage", {"SKILL.md": b"from-main"}) |
267 | 262 |
|
268 | 263 | monkeypatch.setattr(sd, "prompt_yes_no", lambda _: True) |
269 | | - _write(roots, "triage", {"SKILL.md": b"from-ml"}, location="ml.prod") |
270 | 264 |
|
271 | | - assert (roots[0] / "triage/SKILL.md").read_bytes() == b"from-ml" |
| 265 | + assert should_download_skill(roots, "triage", location="ml.prod") |
272 | 266 |
|
273 | 267 | def test_invalid_leaf_is_skipped(self, tmp_path): |
274 | 268 | roots = skill_dir_roots(str(tmp_path)) |
275 | 269 |
|
276 | | - _write(roots, "Bad_Name", {"SKILL.md": b"x"}) |
| 270 | + assert not should_download_skill(roots, "Bad_Name", location="main.default") |
| 271 | + |
| 272 | + def test_existing_skill_on_disk_checks_every_root(self, tmp_path): |
| 273 | + roots = skill_dir_roots(str(tmp_path)) |
| 274 | + assert not existing_skill_on_disk(roots, "triage") |
| 275 | + |
| 276 | + (roots[1] / "triage").mkdir(parents=True) |
| 277 | + assert existing_skill_on_disk(roots, "triage") |
| 278 | + |
| 279 | + |
| 280 | +class TestWriteSkill: |
| 281 | + def test_writes_bundle_into_every_root(self, tmp_path): |
| 282 | + roots = skill_dir_roots(str(tmp_path)) |
| 283 | + files = {"SKILL.md": b"# skill", "scripts/run.py": b"print(1)"} |
| 284 | + |
| 285 | + write_skill(roots, "triage", files) |
277 | 286 |
|
278 | | - assert not (roots[0] / "Bad_Name").exists() |
| 287 | + for root in roots: |
| 288 | + assert (root / "triage/SKILL.md").read_bytes() == b"# skill" |
| 289 | + assert (root / "triage/scripts/run.py").read_bytes() == b"print(1)" |
279 | 290 |
|
280 | 291 | def test_path_traversal_is_rejected(self, tmp_path): |
281 | 292 | roots = skill_dir_roots(str(tmp_path)) |
282 | 293 |
|
283 | | - _write(roots, "triage", {"SKILL.md": b"ok", "../escape.md": b"nope", "/abs.md": b"nope"}) |
| 294 | + write_skill(roots, "triage", {"SKILL.md": b"ok", "../escape.md": b"nope", "/abs.md": b"nope"}) |
284 | 295 |
|
285 | 296 | assert (roots[0] / "triage/SKILL.md").read_bytes() == b"ok" |
286 | 297 | assert not (tmp_path / "escape.md").exists() |
@@ -322,6 +333,23 @@ def test_list_failure_skips_location(self, tmp_path, monkeypatch): |
322 | 333 |
|
323 | 334 | assert called == [] |
324 | 335 |
|
| 336 | + def test_declined_skill_is_not_fetched(self, tmp_path, monkeypatch): |
| 337 | + roots = skill_dir_roots(str(tmp_path)) |
| 338 | + write_skill(roots, "triage", {"SKILL.md": b"kept"}) |
| 339 | + monkeypatch.setattr(sd, "list_schema_skills", lambda *a, **k: (["triage"], None)) |
| 340 | + monkeypatch.setattr(sd, "prompt_yes_no", lambda _: False) |
| 341 | + fetched = [] |
| 342 | + monkeypatch.setattr( |
| 343 | + sd, |
| 344 | + "fetch_skill_bundle", |
| 345 | + lambda ws, tok, c, s, leaf: fetched.append(leaf) or ({"SKILL.md": b"new"}, None), |
| 346 | + ) |
| 347 | + |
| 348 | + sd.download_skills(WS, "token", ["main.default"], str(tmp_path)) |
| 349 | + |
| 350 | + assert fetched == [] |
| 351 | + assert (roots[0] / "triage/SKILL.md").read_bytes() == b"kept" |
| 352 | + |
325 | 353 | def test_bundle_failure_skips_that_skill_only(self, tmp_path, monkeypatch): |
326 | 354 | monkeypatch.setattr(sd, "list_schema_skills", lambda *a, **k: (["good", "bad"], None)) |
327 | 355 | monkeypatch.setattr( |
|
0 commit comments