Skip to content

Latest commit

 

History

History
97 lines (82 loc) · 3.87 KB

File metadata and controls

97 lines (82 loc) · 3.87 KB

Atlas Bloom Contract Tests

This document captures executable contract expectations for Atlas -> Bloom workflows.

Endpoint Matrix

Workflow Endpoint Method Auth Required Headers Expected Status
Create container /api/v1/object-creation/create POST Bloom bearer token Authorization 200
Patch container /api/v1/containers/{euid} PATCH Bloom bearer token Authorization 200
Create specimen /api/v1/external/specimens POST Bloom bearer token (blm_...) Authorization, Idempotency-Key 200
Get specimen /api/v1/external/specimens/{specimen_euid} GET Bloom bearer token (blm_...) Authorization 200
Update specimen /api/v1/external/specimens/{specimen_euid} PATCH Bloom bearer token (blm_...) Authorization 200
Delete specimen /api/v1/content/{specimen_euid} DELETE Bloom bearer token Authorization 200
Lookup by reference /api/v1/external/specimens/by-reference GET Bloom bearer token (blm_...) Authorization 200
Atlas webhook receive /api/integrations/bloom/v1/events (Atlas side) POST HMAC signature X-Bloom-Signature, X-Bloom-Event-Id 202

Pytest Patterns

def test_create_container_contract(client):
    payload = {
        "category": "container",
        "type": "tube",
        "subtype": "tube-generic-10ml",
        "version": "1.0",
        "name": "atlas contract tube",
        "properties": {"name": "atlas contract tube"},
    }
    resp = client.post("/api/v1/object-creation/create", json=payload)
    assert resp.status_code == 200
    data = resp.json()
    assert data["euid"]
def test_specimen_crud_contract(client, container_euid):
    create_payload = {
        "specimen_template_code": "content/specimen/blood-whole/1.0",
        "container_euid": container_euid,
        "atlas_refs": {"trf_euid": "TRF-1", "patient_id": "PAT-1", "kit_barcode": "KIT-1"},
        "properties": {"source": "atlas"},
    }
    created = client.post(
        "/api/v1/external/specimens",
        json=create_payload,
        headers={"Idempotency-Key": "idem-1"},
    )
    assert created.status_code == 200
    specimen_euid = created.json()["specimen_euid"]

    got = client.get(f"/api/v1/external/specimens/{specimen_euid}")
    assert got.status_code == 200

    patched = client.patch(
        f"/api/v1/external/specimens/{specimen_euid}",
        json={"status": "inactive", "properties": {"qc_state": "failed"}},
    )
    assert patched.status_code == 200

    deleted = client.delete(f"/api/v1/content/{specimen_euid}")
    assert deleted.status_code == 200
def test_lookup_by_reference_contract(client):
    resp = client.get("/api/v1/external/specimens/by-reference", params={"trf_euid": "TRF-1"})
    assert resp.status_code == 200
    assert "items" in resp.json()
def test_webhook_signature_contract():
    body = b'{"organization_id":"...","event_id":"evt-1","event_type":"specimen.updated","payload":{"euid":"SP-1"}}'
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    assert headers["X-Bloom-Signature"] == f"sha256={expected}"
    assert headers["X-Bloom-Event-Id"] == "evt-1"

Negative-Path Matrix

Scenario Expected Outcome
Missing Authorization on protected endpoint 401
Invalid token 401
Unsupported specimen template code 400 (validation failure)
Missing Atlas refs for external specimen create 400
Atlas dependency unavailable during ref validation 424
Missing Idempotency-Key for Atlas facade create flows rejected by integration facade (400)

Run Commands

source /Users/jmajor/projects/daylily/bloom/activate
pytest --no-cov -q tests/test_atlas_workflow_contract.py
pytest --no-cov -q tests/test_atlas_lookup_resilience.py