fix: apply code-review findings to import_fruits script and tests

- find_images: verify exact fruit_id prefix (stem-parse before _s0.) to
  prevent cross-fruit image contamination (e.g. mitschurins steals
  mitschurins_fruchtbare images)
- DATA_DIR uses os.path.abspath to handle symlinks / relative invocation
- counts["images"] derived from IMAGE_DIRS constant, not hardcoded keys
- counts["warnings"] incremented on missing-id/name skip (was missing)
- UPSERT preserves existing comment (comment = fruits.comment, not NULL)
- Print summary and rollback moved inside try/except to avoid NameError
- Remove dead XML_PATH constant
- Tests: add tearDown to clean up tmpdir; fix vacuous _tn exclusion test
  to include positive-control _s0 file; add prefix-collision regression test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 13:38:05 +02:00
co-authored by Claude Sonnet 4.6
parent 4d4c5f399f
commit 7fc8204924
3 changed files with 48 additions and 20 deletions
+17 -2
View File
@@ -1,4 +1,5 @@
import os
import shutil
import tempfile
import unittest
from datetime import date
@@ -127,6 +128,9 @@ class TestFindImages(unittest.TestCase):
for d in (self.ef_dir, self.bl_dir, self.bau_dir):
os.makedirs(d)
def tearDown(self):
shutil.rmtree(self.tmpdir, ignore_errors=True)
def _touch(self, path, content=b"img"):
with open(path, "wb") as f:
f.write(content)
@@ -149,10 +153,13 @@ class TestFindImages(unittest.TestCase):
types = [i["image_type"] for i in imgs]
self.assertIn("tree", types)
def test_skips_tn_files(self):
def test_skips_tn_files_but_finds_s0(self):
# _tn file must be excluded; _s0 file must be included (positive control)
self._touch(os.path.join(self.ef_dir, "adams_apfel_ef_tn.jpg"))
self._touch(os.path.join(self.ef_dir, "adams_apfel_ef_s0.jpg"))
imgs = find_images("adams_apfel", self.tmpdir)
self.assertEqual(imgs, [])
self.assertEqual(len(imgs), 1)
self.assertEqual(imgs[0]["filename"], "adams_apfel_ef_s0.jpg")
def test_returns_empty_when_no_match(self):
imgs = find_images("unknown_fruit", self.tmpdir)
@@ -173,6 +180,14 @@ class TestFindImages(unittest.TestCase):
imgs = find_images("abbe_fetel", self.tmpdir)
self.assertEqual(len(imgs), 3)
def test_does_not_steal_images_from_fruit_with_longer_id(self):
# "mitschurins" must not match "mitschurins_fruchtbare_nda_s0.jpg"
self._touch(os.path.join(self.ef_dir, "mitschurins_ef_s0.jpg"))
self._touch(os.path.join(self.ef_dir, "mitschurins_fruchtbare_ef_s0.jpg"))
imgs = find_images("mitschurins", self.tmpdir)
self.assertEqual(len(imgs), 1)
self.assertEqual(imgs[0]["filename"], "mitschurins_ef_s0.jpg")
if __name__ == "__main__":
unittest.main()