"""Additional tests for create module.""" import time import pytest from ect import Payload, create, generate_key, CreateOptions, default_create_options, POL_DECISION_APPROVED def test_default_create_options(): opts = default_create_options() assert opts.key_id == "" def test_create_errors(): key = generate_key() p = Payload(iss="i", aud=["a"], iat=1, exp=2, jti="j", exec_act="e", par=[], pol="p", pol_decision=POL_DECISION_APPROVED) with pytest.raises(ValueError, match="KeyID|required"): create(p, key, CreateOptions(key_id="")) with pytest.raises((ValueError, TypeError, AttributeError)): create(None, key, CreateOptions(key_id="k")) def test_create_optional_pol(): key = generate_key() now = int(time.time()) p = Payload( iss="iss", aud=["a"], iat=now, exp=now + 3600, jti="jti-nopol", exec_act="act", par=[], ) compact = create(p, key, CreateOptions(key_id="kid")) assert compact def test_create_validation_errors(): key = generate_key() base = dict(iss="i", aud=["a"], iat=1, exp=2, jti="j", exec_act="e", par=[]) with pytest.raises(ValueError, match="iss"): create(Payload(**{**base, "iss": ""}), key, CreateOptions(key_id="k")) with pytest.raises(ValueError, match="aud"): create(Payload(**{**base, "aud": []}), key, CreateOptions(key_id="k")) with pytest.raises(ValueError, match="jti"): create(Payload(**{**base, "jti": ""}), key, CreateOptions(key_id="k")) with pytest.raises(ValueError, match="exec_act"): create(Payload(**{**base, "exec_act": ""}), key, CreateOptions(key_id="k")) with pytest.raises(ValueError, match="pol and pol_decision"): create(Payload(**{**base, "pol": "p", "pol_decision": ""}), key, CreateOptions(key_id="k")) with pytest.raises(ValueError, match="pol_decision"): create(Payload(**{**base, "pol": "p", "pol_decision": "bad"}), key, CreateOptions(key_id="k")) def test_create_ext_compensation_reason_requires_required(): key = generate_key() p = Payload( iss="i", aud=["a"], iat=1, exp=2, jti="j", exec_act="e", par=[], ext={"compensation_reason": "rollback", "compensation_required": False}, ) with pytest.raises(ValueError, match="compensation_required"): create(p, key, CreateOptions(key_id="k")) def test_create_zero_expiry_uses_default(): key = generate_key() p = Payload(iss="i", aud=["a"], iat=0, exp=0, jti="j", exec_act="e", par=[]) compact = create(p, key, CreateOptions(key_id="k", default_expiry_sec=300)) assert compact # create() works on a copy; decode the token to verify defaults were applied import jwt claims = jwt.decode(compact, options={"verify_signature": False}) assert claims["exp"] > claims["iat"] def test_create_validate_uuids_rejects_non_uuid_jti(): key = generate_key() now = int(time.time()) p = Payload(iss="i", aud=["a"], iat=now, exp=now + 3600, jti="not-a-uuid", exec_act="e", par=[]) with pytest.raises(ValueError, match="jti must be UUID"): create(p, key, CreateOptions(key_id="k", validate_uuids=True)) def test_create_max_par_length(): key = generate_key() now = int(time.time()) p = Payload(iss="i", aud=["a"], iat=now, exp=now + 3600, jti="550e8400-e29b-41d4-a716-446655440000", exec_act="e", par=["p1", "p2"]) with pytest.raises(ValueError, match="par exceeds max length"): create(p, key, CreateOptions(key_id="k", max_par_length=1)) def test_create_ext_size_rejected(): from ect.validate import EXT_MAX_SIZE key = generate_key() now = int(time.time()) p = Payload( iss="i", aud=["a"], iat=now, exp=now + 3600, jti="550e8400-e29b-41d4-a716-446655440000", exec_act="e", par=[], ext={"x": "y" * (EXT_MAX_SIZE - 5)}, ) with pytest.raises(ValueError, match="ext exceeds max size"): create(p, key, CreateOptions(key_id="k"))