from __future__ import annotations import base64 import json from v1.payments.apple_verifier import ( AppleJwsVerifier, VerificationError, VerifiedTransaction, ) def _make_jws_parts(header: dict[str, object], payload: dict[str, object]) -> tuple[str, str]: h = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b"=").decode() p = base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b"=").decode() return h, p class TestAppleJwsVerifierInvalidInput: def test_invalid_header_returns_error(self) -> None: verifier = AppleJwsVerifier() result = verifier.verify_signed_transaction( "not-a-jws", expected_bundle_id="com.meeyao.qianwen", expected_product_id="com.meeyao.qianwen.starter_pack", ) assert isinstance(result, VerificationError) assert result.code == "PAYMENT_TRANSACTION_INVALID" assert "decode" in result.detail.lower() or "header" in result.detail.lower() def test_missing_x5c_returns_error(self) -> None: verifier = AppleJwsVerifier() h, p = _make_jws_parts({"alg": "ES256"}, {"bundleId": "test"}) result = verifier.verify_signed_transaction( f"{h}.{p}.fake", expected_bundle_id="com.meeyao.qianwen", expected_product_id="com.meeyao.qianwen.starter_pack", ) assert isinstance(result, VerificationError) assert "x5c" in result.detail def test_short_x5c_returns_error(self) -> None: verifier = AppleJwsVerifier() h, p = _make_jws_parts({"alg": "ES256", "x5c": ["one"]}, {"bundleId": "test"}) result = verifier.verify_signed_transaction( f"{h}.{p}.fake", expected_bundle_id="com.meeyao.qianwen", expected_product_id="com.meeyao.qianwen.starter_pack", ) assert isinstance(result, VerificationError) assert "x5c" in result.detail def test_issuer_subject_mismatch_returns_error(self) -> None: verifier = AppleJwsVerifier() leaf_cert_b64 = base64.b64encode(b"fake_leaf_cert").decode() intermediate_cert_b64 = base64.b64encode(b"fake_intermediate_cert").decode() root_cert_b64 = base64.b64encode(b"fake_root_cert").decode() h, p = _make_jws_parts( {"alg": "ES256", "x5c": [leaf_cert_b64, intermediate_cert_b64, root_cert_b64]}, {"bundleId": "com.meeyao.qianwen"}, ) result = verifier.verify_signed_transaction( f"{h}.{p}.fake", expected_bundle_id="com.meeyao.qianwen", expected_product_id="com.meeyao.qianwen.starter_pack", ) assert isinstance(result, VerificationError) assert "fingerprint" in result.detail or "issuer" in result.detail or "subject" in result.detail