refactor(evidence): remove legacy Python layout (#31)

This commit is contained in:
2026-08-24 02:36:30 +02:00
parent 44f1efa5ba
commit 840848df94
36 changed files with 246 additions and 321 deletions
+15 -15
View File
@@ -2,7 +2,7 @@ from datetime import UTC, datetime
import pytest
from tht.ports.evidence import EvidenceSourceError
from tht.evidence.contracts import EvidenceSourceError
class Body:
@@ -28,7 +28,7 @@ class Client:
def test_s3_canonical_uri_version_fingerprint_and_closed_body():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
source = S3EvidenceSource(bucket="evidence", prefix="clinical/", client=client)
item = next(iter(source.discover()))
@@ -39,14 +39,14 @@ def test_s3_canonical_uri_version_fingerprint_and_closed_body():
def test_s3_etag_fallback_and_bounds():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
with pytest.raises(ValueError):
S3EvidenceSource(bucket="evidence", client=client, max_objects=0)
def test_s3_rejects_private_or_insecure_endpoint_without_explicit_opt_in():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
with pytest.raises(ValueError, match="trusted"):
S3EvidenceSource(bucket="evidence", endpoint_url="https://127.0.0.1:9000", client=Client())
with pytest.raises(ValueError, match="HTTPS"):
@@ -59,20 +59,20 @@ def test_s3_rejects_private_or_insecure_endpoint_without_explicit_opt_in():
@pytest.mark.parametrize("bucket", ["UPPER", "bad_bucket", "-start", "end-", "a..b"])
def test_s3_rejects_invalid_bucket_names(bucket):
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
with pytest.raises(ValueError, match="bucket"):
S3EvidenceSource(bucket=bucket, client=Client())
@pytest.mark.parametrize("bucket", ["127.0.0.1", "192.168.1.1"])
def test_s3_rejects_ip_shaped_bucket(bucket):
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
with pytest.raises(ValueError, match="bucket"):
S3EvidenceSource(bucket=bucket, client=Client())
def test_s3_rejects_endpoint_query_path_fragment_and_untrusted_custom_host():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
for endpoint in ("https://s3.example.test/path", "https://s3.example.test/?x=1",
"https://s3.example.test/#x"):
with pytest.raises(ValueError, match="root"):
@@ -83,7 +83,7 @@ def test_s3_rejects_endpoint_query_path_fragment_and_untrusted_custom_host():
def test_s3_rejects_out_of_prefix_key_and_missing_validator():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
client.list_objects_v2 = lambda **kwargs: {"Contents": [{"Key": "other/a.md", "ETag": '"x"'}]}
with pytest.raises(EvidenceSourceError):
@@ -94,7 +94,7 @@ def test_s3_rejects_out_of_prefix_key_and_missing_validator():
def test_s3_rejects_leading_slash_prefix_empty_and_control_keys():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
with pytest.raises(ValueError, match="prefix"):
S3EvidenceSource(bucket="evidence", prefix="/clinical", client=Client())
for key in ("", "clinical/a\x00.md", "clinical/a\x7f.md"):
@@ -106,7 +106,7 @@ def test_s3_rejects_leading_slash_prefix_empty_and_control_keys():
@pytest.mark.parametrize("prefix", ["/bad", "x" * 1025, "bad\x00prefix", "bad\x7fprefix"])
def test_s3_rejects_invalid_prefix_before_client_request(prefix):
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
with pytest.raises(ValueError, match="prefix"):
S3EvidenceSource(bucket="evidence", prefix=prefix, client=client)
@@ -114,7 +114,7 @@ def test_s3_rejects_invalid_prefix_before_client_request(prefix):
def test_s3_hard_page_limit_never_requests_page_max_plus_one():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
def listing(**kwargs):
client.list_calls += 1
@@ -128,7 +128,7 @@ def test_s3_hard_page_limit_never_requests_page_max_plus_one():
def test_s3_acquire_rejects_exact_etag_drift_and_closes_body():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
source = S3EvidenceSource(bucket="evidence", client=client)
item = next(iter(source.discover()))
@@ -140,7 +140,7 @@ def test_s3_acquire_rejects_exact_etag_drift_and_closes_body():
def test_s3_acquire_rejects_forged_reconstructed_item_before_get():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
source = S3EvidenceSource(bucket="evidence", client=client)
item = next(iter(source.discover()))
@@ -153,14 +153,14 @@ def test_s3_acquire_rejects_forged_reconstructed_item_before_get():
@pytest.mark.parametrize("host", ["127.0.0.1", "10.0.0.1", "169.254.1.1", "0.0.0.0",
"[::1]", "[fe80::1]", "[::]"])
def test_s3_literal_non_global_endpoint_requires_private_opt_in(host):
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
with pytest.raises(ValueError, match="private"):
S3EvidenceSource(bucket="evidence", endpoint_url=f"https://{host}:9000",
trusted_endpoint=True, client=Client())
def test_s3_size_limit_closes_body():
from tht.adapters.evidence.s3 import S3EvidenceSource
from tht.evidence.adapters.s3 import S3EvidenceSource
client = Client()
source = S3EvidenceSource(bucket="evidence", client=client, max_bytes=4)
item = next(iter(source.discover()))