feat: add draft data, gap analysis report, and workspace config
This commit is contained in:
103
workspace/act/tests/test_lifecycle.py
Normal file
103
workspace/act/tests/test_lifecycle.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""Tests for act.lifecycle module."""
|
||||
|
||||
import time
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
|
||||
from act.crypto import generate_ed25519_keypair, sign
|
||||
from act.errors import ACTCapabilityError, ACTPhaseError
|
||||
from act.lifecycle import transition_to_record
|
||||
from act.token import (
|
||||
ACTMandate,
|
||||
ACTRecord,
|
||||
Capability,
|
||||
Delegation,
|
||||
ErrorClaim,
|
||||
TaskClaim,
|
||||
decode_jws,
|
||||
encode_jws,
|
||||
)
|
||||
from act.crypto import verify
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def keys():
|
||||
iss_priv, iss_pub = generate_ed25519_keypair()
|
||||
sub_priv, sub_pub = generate_ed25519_keypair()
|
||||
return iss_priv, iss_pub, sub_priv, sub_pub
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mandate(keys):
|
||||
iss_priv, _, _, _ = keys
|
||||
m = ACTMandate(
|
||||
alg="EdDSA", kid="iss-key",
|
||||
iss="agent-a", sub="agent-b", aud="agent-b",
|
||||
iat=1772064000, exp=1772064900,
|
||||
jti=str(uuid.uuid4()),
|
||||
task=TaskClaim(purpose="test"),
|
||||
cap=[Capability(action="read.data"), Capability(action="write.result")],
|
||||
delegation=Delegation(depth=0, max_depth=2, chain=[]),
|
||||
)
|
||||
return m
|
||||
|
||||
|
||||
class TestTransitionToRecord:
|
||||
def test_basic_transition(self, mandate, keys):
|
||||
_, _, sub_priv, sub_pub = keys
|
||||
record, compact = transition_to_record(
|
||||
mandate, sub_kid="sub-key", sub_private_key=sub_priv,
|
||||
exec_act="read.data", par=[], status="completed",
|
||||
)
|
||||
assert isinstance(record, ACTRecord)
|
||||
assert record.exec_act == "read.data"
|
||||
assert record.kid == "sub-key"
|
||||
assert record.iss == mandate.iss # preserved
|
||||
# Verify signature
|
||||
_, _, sig, si = decode_jws(compact)
|
||||
verify(sub_pub, sig, si)
|
||||
|
||||
def test_with_hashes(self, mandate, keys):
|
||||
_, _, sub_priv, _ = keys
|
||||
record, _ = transition_to_record(
|
||||
mandate, sub_kid="k", sub_private_key=sub_priv,
|
||||
exec_act="write.result", par=[], status="completed",
|
||||
inp_hash="abc", out_hash="def",
|
||||
)
|
||||
assert record.inp_hash == "abc"
|
||||
assert record.out_hash == "def"
|
||||
|
||||
def test_with_error(self, mandate, keys):
|
||||
_, _, sub_priv, _ = keys
|
||||
record, _ = transition_to_record(
|
||||
mandate, sub_kid="k", sub_private_key=sub_priv,
|
||||
exec_act="read.data", par=[], status="failed",
|
||||
err=ErrorClaim(code="timeout", detail="request timed out"),
|
||||
)
|
||||
assert record.status == "failed"
|
||||
assert record.err is not None
|
||||
assert record.err.code == "timeout"
|
||||
|
||||
def test_rejects_bad_exec_act(self, mandate, keys):
|
||||
_, _, sub_priv, _ = keys
|
||||
with pytest.raises(ACTCapabilityError):
|
||||
transition_to_record(
|
||||
mandate, sub_kid="k", sub_private_key=sub_priv,
|
||||
exec_act="delete.everything", par=[],
|
||||
)
|
||||
|
||||
def test_preserves_phase1_claims(self, mandate, keys):
|
||||
_, _, sub_priv, _ = keys
|
||||
record, _ = transition_to_record(
|
||||
mandate, sub_kid="k", sub_private_key=sub_priv,
|
||||
exec_act="read.data", par=[], status="completed",
|
||||
)
|
||||
assert record.iss == mandate.iss
|
||||
assert record.sub == mandate.sub
|
||||
assert record.aud == mandate.aud
|
||||
assert record.iat == mandate.iat
|
||||
assert record.exp == mandate.exp
|
||||
assert record.jti == mandate.jti
|
||||
assert record.task == mandate.task
|
||||
assert record.cap == mandate.cap
|
||||
Reference in New Issue
Block a user