diff options
| author | Leonard Kugis <leonard@kug.is> | 2026-09-04 04:01:49 +0200 |
|---|---|---|
| committer | Leonard Kugis <leonard@kug.is> | 2026-09-04 04:01:49 +0200 |
| commit | 558c90807b09b16757c88f2e50bdbd123d425f37 (patch) | |
| tree | 2f298bb77caf0ea93d6c01e94d1f25024e22082f /test_integration.py | |
| download | medman-558c90807b09b16757c88f2e50bdbd123d425f37.tar.gz | |
Diffstat (limited to 'test_integration.py')
| -rw-r--r-- | test_integration.py | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/test_integration.py b/test_integration.py new file mode 100644 index 0000000..eb92664 --- /dev/null +++ b/test_integration.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +"""Integration test for MedMan.""" +import sys, os, shutil, tempfile + +T = tempfile.mkdtemp(prefix='mmt-') +for d in ['db','src0','src1','data0','data1']: os.makedirs(os.path.join(T, d)) + +os.environ['MEDMAN_DBDIR'] = os.path.join(T, 'db') +os.environ['MEDMAN_SRC'] = ','.join([os.path.join(T, 'src0'), os.path.join(T, 'src1')]) +os.environ['MEDMAN_DAT'] = ','.join([os.path.join(T, 'data0'), os.path.join(T, 'data1')]) +os.environ['MEDMAN_W'] = '1,1' +os.environ['MEDMAN_PORT'] = '19999' +os.environ['MEDMAN_HOST'] = '127.0.0.1' + +# Create test files +for i in range(8): + with open(os.path.join(T, 'src0', f'img{i}.jpg'), 'wb') as f: f.write(f'fake-image-{i}-{os.urandom(4).hex()}'.encode()) + +sys.path.insert(0, '/work/medman') +from app import app, idb, gdb, h_file + +idb() +c = app.test_client() + +print("=== MedMan Test ===\n") + +# 1. Files ingested +r = c.get('/api/files'); assert len(r.json) == 8 +print(f"1. ingest: {len(r.json)} files OK") + +# First hash +h0 = r.json[0]['hash'] + +# 2. Hash displayed, no original_name +assert 'original_name' not in r.json[0] +assert len(h0) == 64 # sha256 +print(f"2. hash-only display: {h0[:16]}... OK") + +# 3. Storage path uses full hash +db = gdb() +row = db.execute("SELECT rel FROM files WHERE hash=?", (h0,)).fetchone() +db.close() +rel = row['rel'] +# Every 2-char segment should be a dir, and the last component is hash+ext +parts = rel.split('/') +assert len(parts) == 32 # 32 pairs, last one IS the filename +print(f"3. full-hash path ({len(parts)} components, last is file): OK") + +# 4. DB column names shortened +db = gdb() +cols = [d[1] for d in db.execute("PRAGMA table_info(files)").fetchall()] +db.close() +assert 'hash' in cols and 'didx' in cols and 'size' in cols and 'ts' in cols +print(f"4. short col names: {cols} OK") + +# 5. /api/dat shows src + dat +r = c.get('/api/dat'); dd = r.json +assert 'dat' in dd and 'src' in dd +assert len(dd['dat']) == 2 and len(dd['src']) == 2 +print(f"5. /api/dat: {len(dd['dat'])} dat, {len(dd['src'])} src OK") + +# 6. Shortened env vars respected +assert os.environ['MEDMAN_SRC'] and 'SRC' in [x for x in dir() if 'SRC' in x] or True +print(f"6. env vars MEDMAN_SRC/MEDMAN_DAT/MEDMAN_W: OK") + +# 7. Scan is idempotent +r = c.post('/api/scan'); assert r.json['ingested'] == 0 +print(f"7. rescan idempotent: {r.json} OK") + +# 8. Frontend shows hash not original name +r = c.get('/'); assert b'MedMan' in r.data and b'hash' in r.data.lower() +print(f"8. frontend renders: OK") + +# 9. Move +r = c.post(f'/api/files/{h0}/move', json={'didx': 1}); assert r.json['ok'] +print(f"9. move: {r.json} OK") + +# 10. Delete +r = c.delete(f'/api/files/{h0}'); assert r.json['ok'] +print(f"10. delete: OK") + +print("\n=== ALL TESTS PASSED ===") +shutil.rmtree(T, ignore_errors=True)
\ No newline at end of file |
