Atlas Bloom Contract Tests
This document captures executable contract expectations for Atlas -> Bloom workflows.
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
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"
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)
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