@@ -220,7 +220,7 @@ def test_assess_raises_on_402():
220220
221221
222222# ---------------------------------------------------------------------------
223- # Authorization header
223+ # API key header
224224# ---------------------------------------------------------------------------
225225
226226REPUTATION_PAYLOAD_SIMPLE = {
@@ -239,7 +239,7 @@ def test_auth_header_is_sent():
239239 )
240240 client = AgentScore (api_key = "my-secret-key" )
241241 client .get_reputation (ADDRESS )
242- assert route .calls .last .request .headers ["authorization " ] == "Bearer my-secret-key"
242+ assert route .calls .last .request .headers ["x-api-key " ] == "my-secret-key"
243243
244244
245245# ---------------------------------------------------------------------------
@@ -485,3 +485,182 @@ def test_error_response_no_error_key_fallback():
485485 client .get_reputation (ADDRESS )
486486 assert exc_info .value .status_code == 422
487487 assert exc_info .value .code == "unknown_error"
488+
489+
490+ # ---------------------------------------------------------------------------
491+ # Verification / Compliance fields
492+ # ---------------------------------------------------------------------------
493+
494+
495+ REPUTATION_WITH_VERIFICATION = {
496+ ** REPUTATION_PAYLOAD ,
497+ "verification_level" : "kyc_verified" ,
498+ }
499+
500+ ASSESS_WITH_COMPLIANCE = {
501+ ** ASSESS_PAYLOAD ,
502+ "decision" : "deny" ,
503+ "decision_reasons" : ["kyc_required" , "sanctions_check_pending" ],
504+ "operator_verification" : {
505+ "level" : "none" ,
506+ "operator_type" : None ,
507+ "claimed_at" : None ,
508+ "verified_at" : None ,
509+ },
510+ "verify_url" : "https://agentscore.sh/verify/abc123" ,
511+ "resolved_operator" : "0xoperator456" ,
512+ }
513+
514+
515+ @respx .mock
516+ def test_get_reputation_returns_verification_level ():
517+ respx .get (f"{ BASE_URL } /v1/reputation/{ ADDRESS } " ).mock (
518+ return_value = httpx .Response (200 , json = REPUTATION_WITH_VERIFICATION )
519+ )
520+ client = AgentScore (api_key = API_KEY )
521+ result = client .get_reputation (ADDRESS )
522+ assert result ["verification_level" ] == "kyc_verified"
523+
524+
525+ @respx .mock
526+ def test_get_reputation_omits_verification_level_when_absent ():
527+ respx .get (f"{ BASE_URL } /v1/reputation/{ ADDRESS } " ).mock (
528+ return_value = httpx .Response (200 , json = REPUTATION_PAYLOAD )
529+ )
530+ client = AgentScore (api_key = API_KEY )
531+ result = client .get_reputation (ADDRESS )
532+ assert "verification_level" not in result
533+
534+
535+ @respx .mock
536+ def test_assess_returns_operator_verification ():
537+ respx .post (f"{ BASE_URL } /v1/assess" ).mock (
538+ return_value = httpx .Response (200 , json = ASSESS_WITH_COMPLIANCE )
539+ )
540+ client = AgentScore (api_key = API_KEY )
541+ result = client .assess (ADDRESS )
542+ assert result ["operator_verification" ]["level" ] == "none"
543+ assert result ["operator_verification" ]["operator_type" ] is None
544+
545+
546+ @respx .mock
547+ def test_assess_returns_verify_url ():
548+ respx .post (f"{ BASE_URL } /v1/assess" ).mock (
549+ return_value = httpx .Response (200 , json = ASSESS_WITH_COMPLIANCE )
550+ )
551+ client = AgentScore (api_key = API_KEY )
552+ result = client .assess (ADDRESS )
553+ assert result ["verify_url" ] == "https://agentscore.sh/verify/abc123"
554+
555+
556+ @respx .mock
557+ def test_assess_returns_resolved_operator ():
558+ respx .post (f"{ BASE_URL } /v1/assess" ).mock (
559+ return_value = httpx .Response (200 , json = ASSESS_WITH_COMPLIANCE )
560+ )
561+ client = AgentScore (api_key = API_KEY )
562+ result = client .assess (ADDRESS )
563+ assert result ["resolved_operator" ] == "0xoperator456"
564+
565+
566+ @respx .mock
567+ def test_assess_omits_verification_fields_when_absent ():
568+ respx .post (f"{ BASE_URL } /v1/assess" ).mock (
569+ return_value = httpx .Response (200 , json = ASSESS_PAYLOAD )
570+ )
571+ client = AgentScore (api_key = API_KEY )
572+ result = client .assess (ADDRESS )
573+ assert "operator_verification" not in result
574+ assert "verify_url" not in result
575+ assert "resolved_operator" not in result
576+
577+
578+ @respx .mock
579+ def test_assess_sends_compliance_policy_fields ():
580+ route = respx .post (f"{ BASE_URL } /v1/assess" ).mock (
581+ return_value = httpx .Response (200 , json = ASSESS_PAYLOAD )
582+ )
583+ client = AgentScore (api_key = API_KEY )
584+ policy = {
585+ "require_kyc" : True ,
586+ "require_sanctions_clear" : True ,
587+ "min_age" : 90 ,
588+ "blocked_jurisdictions" : ["KP" , "IR" ],
589+ "require_entity_type" : "agent" ,
590+ }
591+ client .assess (ADDRESS , policy = policy )
592+ body = json .loads (route .calls .last .request .content )
593+ assert body ["policy" ]["require_kyc" ] is True
594+ assert body ["policy" ]["require_sanctions_clear" ] is True
595+ assert body ["policy" ]["min_age" ] == 90
596+ assert body ["policy" ]["blocked_jurisdictions" ] == ["KP" , "IR" ]
597+ assert body ["policy" ]["require_entity_type" ] == "agent"
598+
599+
600+ @pytest .mark .asyncio
601+ @respx .mock
602+ async def test_aget_reputation_returns_verification_level ():
603+ respx .get (f"{ BASE_URL } /v1/reputation/{ ADDRESS } " ).mock (
604+ return_value = httpx .Response (200 , json = REPUTATION_WITH_VERIFICATION )
605+ )
606+ client = AgentScore (api_key = API_KEY )
607+ result = await client .aget_reputation (ADDRESS )
608+ assert result ["verification_level" ] == "kyc_verified"
609+ await client .aclose ()
610+
611+
612+ @pytest .mark .asyncio
613+ @respx .mock
614+ async def test_aassess_returns_compliance_fields ():
615+ respx .post (f"{ BASE_URL } /v1/assess" ).mock (
616+ return_value = httpx .Response (200 , json = ASSESS_WITH_COMPLIANCE )
617+ )
618+ client = AgentScore (api_key = API_KEY )
619+ result = await client .aassess (ADDRESS )
620+ assert result ["operator_verification" ]["level" ] == "none"
621+ assert result ["verify_url" ] == "https://agentscore.sh/verify/abc123"
622+ assert result ["resolved_operator" ] == "0xoperator456"
623+ await client .aclose ()
624+
625+
626+ # ---------------------------------------------------------------------------
627+ # Integration-style: compliance deny flow
628+ # ---------------------------------------------------------------------------
629+
630+
631+ @respx .mock
632+ def test_full_compliance_deny_flow ():
633+ """Full assess flow with compliance policy returning deny + verify_url."""
634+ compliance_response = {
635+ ** REPUTATION_PAYLOAD ,
636+ "decision" : "deny" ,
637+ "decision_reasons" : ["kyc_required" , "sanctions_check_pending" ],
638+ "on_the_fly" : False ,
639+ "operator_verification" : {
640+ "level" : "none" ,
641+ "operator_type" : None ,
642+ "claimed_at" : None ,
643+ "verified_at" : None ,
644+ },
645+ "verify_url" : "https://agentscore.sh/verify/xyz789" ,
646+ }
647+ route = respx .post (f"{ BASE_URL } /v1/assess" ).mock (
648+ return_value = httpx .Response (200 , json = compliance_response )
649+ )
650+ client = AgentScore (api_key = API_KEY )
651+ result = client .assess (
652+ ADDRESS ,
653+ policy = {
654+ "require_kyc" : True ,
655+ "require_sanctions_clear" : True ,
656+ },
657+ )
658+ assert result ["decision" ] == "deny"
659+ assert "kyc_required" in result ["decision_reasons" ]
660+ assert "sanctions_check_pending" in result ["decision_reasons" ]
661+ assert result ["verify_url" ] == "https://agentscore.sh/verify/xyz789"
662+ assert result ["operator_verification" ]["level" ] == "none"
663+
664+ body = json .loads (route .calls .last .request .content )
665+ assert body ["policy" ]["require_kyc" ] is True
666+ assert body ["policy" ]["require_sanctions_clear" ] is True
0 commit comments