✨ save_exchange_record
should be Optional
#3728
865 tests run, 842 passed, 6 skipped, 17 failed.
Annotations
Check failure on line 529 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_accept_proof_request_verifier_has_issuer_role[clean-clean-clean-clean-clean-trust_registry]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72041f4200>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'0_speed_uuid': {'cred_id...ibutes': {}, 'trace': None}, 'proof_id': 'v2-1a9ded88-7396-4f53-a0ad-6f331143c3ef', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
meld_co_issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': 'fb87b3ab-e3f6-461f-a959-6921e817aa9a', 'created_at': '2024-11-22T17:40:39.958981Z', 'credential_definition_id': 'Vb8URxnLAs2WinBmxywSBW:3:CL:216:tag', ...}
meld_co_credential_definition_id = 'Vb8URxnLAs2WinBmxywSBW:3:CL:216:tag'
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72041f4200>
meld_co_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72041afb30>
meld_co_and_alice_connection = MeldCoAliceConnect(alice_connection_id='fb87b3ab-e3f6-461f-a959-6921e817aa9a', meld_co_connection_id='e67aef05-802b-48b5-ad9e-12c47f7b618f')
@pytest.mark.anyio
@pytest.mark.parametrize(
"meld_co_and_alice_connection", ["trust_registry", "default"], indirect=True
)
async def test_accept_proof_request_verifier_has_issuer_role(
meld_co_issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
meld_co_credential_definition_id: str,
alice_member_client: RichAsyncClient,
meld_co_client: RichAsyncClient,
meld_co_and_alice_connection: MeldCoAliceConnect,
):
request_body = {
"connection_id": meld_co_and_alice_connection.meld_co_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": meld_co_credential_definition_id}]
).to_dict(),
}
send_proof_response = await send_proof_request(meld_co_client, request_body)
meld_co_proof_id = send_proof_response["proof_id"]
thread_id = send_proof_response["thread_id"]
alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={"thread_id": thread_id},
)
alice_proof_id = alice_payload["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
assert await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"proof_id": alice_proof_id,
},
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
indy_request_attrs = IndyRequestedCredsRequestedAttr(
cred_id=referent, revealed=True
)
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={"0_speed_uuid": indy_request_attrs},
requested_predicates={},
self_attested_attributes={},
),
)
> response = await alice_member_client.post(
VERIFIER_BASE_PATH + "/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_verifier.py:529:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72041f4200>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 38 in app/tests/e2e/issuer/test_save_exchange_record.py
github-actions / JUnit Test Report
test_save_exchange_record.test_issue_credential_with_save_exchange_record[clean-clean-clean-clean-clean-None]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7fb386b27c50>
method = 'post', url = '/v1/issuer/credentials'
kwargs = {'json': {'connection_id': '2a2eb3bb-1d25-4ea1-aad0-b5b04b40e84f', 'indy_credential_detail': {'attributes': {'age': '4...ce', 'speed': '10'}, 'credential_definition_id': '2AszGVdGiN6A2sa6AQPGD5:3:CL:245:tag'}, 'save_exchange_record': None}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/issuer/credentials'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
faber_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7fb386b27c50>
credential_definition_id = '2AszGVdGiN6A2sa6AQPGD5:3:CL:245:tag'
faber_and_alice_connection = FaberAliceConnect(alice_connection_id='058f4a74-e533-4aca-916d-5bbe40dbca25', faber_connection_id='2a2eb3bb-1d25-4ea1-aad0-b5b04b40e84f')
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7fb385f7d370>
save_exchange_record = None
@pytest.mark.anyio
@pytest.mark.parametrize("save_exchange_record", [None, False, True])
async def test_issue_credential_with_save_exchange_record(
faber_client: RichAsyncClient,
credential_definition_id: str,
faber_and_alice_connection: FaberAliceConnect,
alice_member_client: RichAsyncClient,
save_exchange_record: Optional[bool],
) -> CredentialExchange:
credential = {
"connection_id": faber_and_alice_connection.faber_connection_id,
"indy_credential_detail": {
"credential_definition_id": credential_definition_id,
"attributes": sample_credential_attributes,
},
"save_exchange_record": save_exchange_record,
}
# create and send credential offer- issuer
faber_send_response = (
> await faber_client.post(
CREDENTIALS_BASE_PATH,
json=credential,
)
).json()
app/tests/e2e/issuer/test_save_exchange_record.py:38:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7fb386b27c50>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/issuer/credentials'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/issuer/credentials', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 529 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_accept_proof_request_verifier_has_issuer_role[clean-clean-clean-clean-clean-default]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d94d10>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'0_speed_uuid': {'cred_id...ibutes': {}, 'trace': None}, 'proof_id': 'v2-17cf68cd-5ee7-4a7d-bc71-b4471cdd56ab', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
meld_co_issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': 'd0611fc9-98b0-47c9-9762-a33a89902888', 'created_at': '2024-11-22T17:40:46.384371Z', 'credential_definition_id': 'Vb8URxnLAs2WinBmxywSBW:3:CL:216:tag', ...}
meld_co_credential_definition_id = 'Vb8URxnLAs2WinBmxywSBW:3:CL:216:tag'
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d94d10>
meld_co_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72041afb30>
meld_co_and_alice_connection = MeldCoAliceConnect(alice_connection_id='d0611fc9-98b0-47c9-9762-a33a89902888', meld_co_connection_id='222ed84a-14f3-4c7d-8d98-4d70455382a9')
@pytest.mark.anyio
@pytest.mark.parametrize(
"meld_co_and_alice_connection", ["trust_registry", "default"], indirect=True
)
async def test_accept_proof_request_verifier_has_issuer_role(
meld_co_issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
meld_co_credential_definition_id: str,
alice_member_client: RichAsyncClient,
meld_co_client: RichAsyncClient,
meld_co_and_alice_connection: MeldCoAliceConnect,
):
request_body = {
"connection_id": meld_co_and_alice_connection.meld_co_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": meld_co_credential_definition_id}]
).to_dict(),
}
send_proof_response = await send_proof_request(meld_co_client, request_body)
meld_co_proof_id = send_proof_response["proof_id"]
thread_id = send_proof_response["thread_id"]
alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={"thread_id": thread_id},
)
alice_proof_id = alice_payload["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
assert await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"proof_id": alice_proof_id,
},
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
indy_request_attrs = IndyRequestedCredsRequestedAttr(
cred_id=referent, revealed=True
)
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={"0_speed_uuid": indy_request_attrs},
requested_predicates={},
self_attested_attributes={},
),
)
> response = await alice_member_client.post(
VERIFIER_BASE_PATH + "/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_verifier.py:529:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d94d10>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 98 in app/tests/e2e/verifier/test_predicate_proofs.py
github-actions / JUnit Test Report
test_predicate_proofs.test_predicate_proofs[clean-clean-clean-clean-clean-clean-<]
assert 422 == 400
+ where 422 = HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}').status_code
+ where HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') = <ExceptionInfo HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') tblen=4>.value
Raw output
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7d6840>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='d991b06a-f84f-4832-a9c2-f60ccf752968', acme_connection_id='3ca4d914-67a6-4e4e-b93d-d0f76d3790f8')
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7a1e50>
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '5d3faf77-11e7-4661-a4f6-84507f1f486f', 'created_at': '2024-11-22T17:41:09.563954Z', 'credential_definition_id': '5kZ7Um6dCo4rNzdX8eijAf:3:CL:255:tag', ...}
predicate = '<'
@pytest.mark.anyio
@pytest.mark.parametrize("predicate", ["<", ">", "<=", ">="])
async def test_predicate_proofs(
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
alice_member_client: RichAsyncClient,
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
predicate: str,
):
request_body = {
"type": "indy",
"indy_proof_request": {
"requested_attributes": {},
"requested_predicates": {
"over_18": {
"name": "age",
"p_type": predicate,
"p_value": 18,
}
},
},
"connection_id": acme_and_alice_connection.acme_connection_id,
"save_exchange_record": True,
}
send_proof_response = await send_proof_request(acme_client, request_body)
thread_id = send_proof_response["thread_id"]
alice_event = await check_webhook_state(
client=alice_member_client,
topic="proofs",
filter_map={"thread_id": thread_id},
state="request-received",
)
alice_proof_id = alice_event["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={},
requested_predicates={
"over_18": {
"cred_id": referent,
}
},
self_attested_attributes={},
),
)
if predicate in [">", ">="]:
response = await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request",
json=proof_accept.model_dump(),
)
result = response.json()
pres_exchange_result = PresentationExchange(**result)
assert isinstance(pres_exchange_result, PresentationExchange)
acme_proof_event = await check_webhook_state(
client=acme_client,
topic="proofs",
state="done",
filter_map={"thread_id": thread_id},
)
assert acme_proof_event["verified"] is True
else:
with pytest.raises(HTTPException) as exc:
await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request", json=proof_accept.model_dump()
)
> assert exc.value.status_code == 400
E assert 422 == 400
E + where 422 = HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}').status_code
E + where HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') = <ExceptionInfo HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') tblen=4>.value
app/tests/e2e/verifier/test_predicate_proofs.py:98: AssertionError
Check failure on line 133 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_accept_proof_request[clean-clean-clean-clean-clean-clean-trust_registry]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203938a40>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'0_speed_uuid': {'cred_id...ibutes': {}, 'trace': None}, 'proof_id': 'v2-206e7e91-aded-4089-a6fc-843a9dc77e0e', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': 'd29f3784-1177-425c-b27d-974931bd5cbf', 'created_at': '2024-11-22T17:41:12.836406Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203938a40>
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='19651091-891f-4949-878d-8dd921ea3c75', acme_connection_id='4f1d7509-a5e8-4500-99f7-57aef256ac60')
@pytest.mark.anyio
@pytest.mark.parametrize(
"acme_and_alice_connection", ["trust_registry", "default"], indirect=True
)
async def test_accept_proof_request(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
alice_member_client: RichAsyncClient,
acme_client: RichAsyncClient,
credential_definition_id: str,
acme_and_alice_connection: AcmeAliceConnect,
):
request_body = {
"connection_id": acme_and_alice_connection.acme_connection_id,
"indy_proof_request": {
"name": "Proof Request",
"version": "1.0.0",
"requested_attributes": {
"0_speed_uuid": {
"name": "speed",
"restrictions": [{"cred_def_id": credential_definition_id}],
}
},
"requested_predicates": {},
},
}
send_proof_response = await send_proof_request(acme_client, request_body)
acme_proof_id = send_proof_response["proof_id"]
thread_id = send_proof_response["thread_id"]
alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"thread_id": thread_id,
},
)
alice_proof_id = alice_payload["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
indy_request_attrs = IndyRequestedCredsRequestedAttr(
cred_id=referent, revealed=True
)
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={"0_speed_uuid": indy_request_attrs},
requested_predicates={},
self_attested_attributes={},
),
)
> response = await alice_member_client.post(
VERIFIER_BASE_PATH + "/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_verifier.py:133:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203938a40>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 74 in app/tests/e2e/verifier/test_predicate_proofs.py
github-actions / JUnit Test Report
test_predicate_proofs.test_predicate_proofs[clean-clean-clean-clean-clean-clean->]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7b5340>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {}, 'requested_predicates'...ibutes': {}, 'trace': None}, 'proof_id': 'v2-d111bb31-eb39-4378-b9b1-e30439d5ab61', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7d6840>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='92a50c89-1dc7-40c4-8974-6eea1b0f37b3', acme_connection_id='1a184139-4df9-435a-a289-8833635c0c32')
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7b5340>
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': 'fcc87fc0-32bc-48bf-b2ba-cbedc97905dc', 'created_at': '2024-11-22T17:41:16.206261Z', 'credential_definition_id': '5kZ7Um6dCo4rNzdX8eijAf:3:CL:255:tag', ...}
predicate = '>'
@pytest.mark.anyio
@pytest.mark.parametrize("predicate", ["<", ">", "<=", ">="])
async def test_predicate_proofs(
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
alice_member_client: RichAsyncClient,
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
predicate: str,
):
request_body = {
"type": "indy",
"indy_proof_request": {
"requested_attributes": {},
"requested_predicates": {
"over_18": {
"name": "age",
"p_type": predicate,
"p_value": 18,
}
},
},
"connection_id": acme_and_alice_connection.acme_connection_id,
"save_exchange_record": True,
}
send_proof_response = await send_proof_request(acme_client, request_body)
thread_id = send_proof_response["thread_id"]
alice_event = await check_webhook_state(
client=alice_member_client,
topic="proofs",
filter_map={"thread_id": thread_id},
state="request-received",
)
alice_proof_id = alice_event["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={},
requested_predicates={
"over_18": {
"cred_id": referent,
}
},
self_attested_attributes={},
),
)
if predicate in [">", ">="]:
> response = await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_predicate_proofs.py:74:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7b5340>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 133 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_accept_proof_request[clean-clean-clean-clean-clean-clean-default]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72039387a0>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'0_speed_uuid': {'cred_id...ibutes': {}, 'trace': None}, 'proof_id': 'v2-f4edd59c-a1b4-4151-b13c-0a5bfd9123fc', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '65e0d1fa-b1a0-4bcb-8605-d5106a92b76b', 'created_at': '2024-11-22T17:41:20.248173Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72039387a0>
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='cee08c62-d6f3-4bf4-82db-aee261e0156c', acme_connection_id='818c5eea-5563-44d7-bbaf-737c63a34805')
@pytest.mark.anyio
@pytest.mark.parametrize(
"acme_and_alice_connection", ["trust_registry", "default"], indirect=True
)
async def test_accept_proof_request(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
alice_member_client: RichAsyncClient,
acme_client: RichAsyncClient,
credential_definition_id: str,
acme_and_alice_connection: AcmeAliceConnect,
):
request_body = {
"connection_id": acme_and_alice_connection.acme_connection_id,
"indy_proof_request": {
"name": "Proof Request",
"version": "1.0.0",
"requested_attributes": {
"0_speed_uuid": {
"name": "speed",
"restrictions": [{"cred_def_id": credential_definition_id}],
}
},
"requested_predicates": {},
},
}
send_proof_response = await send_proof_request(acme_client, request_body)
acme_proof_id = send_proof_response["proof_id"]
thread_id = send_proof_response["thread_id"]
alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"thread_id": thread_id,
},
)
alice_proof_id = alice_payload["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
indy_request_attrs = IndyRequestedCredsRequestedAttr(
cred_id=referent, revealed=True
)
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={"0_speed_uuid": indy_request_attrs},
requested_predicates={},
self_attested_attributes={},
),
)
> response = await alice_member_client.post(
VERIFIER_BASE_PATH + "/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_verifier.py:133:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72039387a0>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 98 in app/tests/e2e/verifier/test_predicate_proofs.py
github-actions / JUnit Test Report
test_predicate_proofs.test_predicate_proofs[clean-clean-clean-clean-clean-clean-<=]
assert 422 == 400
+ where 422 = HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}').status_code
+ where HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') = <ExceptionInfo HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') tblen=4>.value
Raw output
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7d6840>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='3013f310-49f7-4169-a9b3-2b75f229181b', acme_connection_id='f493fbd5-817a-43e9-85e2-edf869ed8e9f')
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7962d0>
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '6b3caf8c-fb83-4935-9541-ba7362108c63', 'created_at': '2024-11-22T17:41:24.278155Z', 'credential_definition_id': '5kZ7Um6dCo4rNzdX8eijAf:3:CL:255:tag', ...}
predicate = '<='
@pytest.mark.anyio
@pytest.mark.parametrize("predicate", ["<", ">", "<=", ">="])
async def test_predicate_proofs(
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
alice_member_client: RichAsyncClient,
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
predicate: str,
):
request_body = {
"type": "indy",
"indy_proof_request": {
"requested_attributes": {},
"requested_predicates": {
"over_18": {
"name": "age",
"p_type": predicate,
"p_value": 18,
}
},
},
"connection_id": acme_and_alice_connection.acme_connection_id,
"save_exchange_record": True,
}
send_proof_response = await send_proof_request(acme_client, request_body)
thread_id = send_proof_response["thread_id"]
alice_event = await check_webhook_state(
client=alice_member_client,
topic="proofs",
filter_map={"thread_id": thread_id},
state="request-received",
)
alice_proof_id = alice_event["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={},
requested_predicates={
"over_18": {
"cred_id": referent,
}
},
self_attested_attributes={},
),
)
if predicate in [">", ">="]:
response = await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request",
json=proof_accept.model_dump(),
)
result = response.json()
pres_exchange_result = PresentationExchange(**result)
assert isinstance(pres_exchange_result, PresentationExchange)
acme_proof_event = await check_webhook_state(
client=acme_client,
topic="proofs",
state="done",
filter_map={"thread_id": thread_id},
)
assert acme_proof_event["verified"] is True
else:
with pytest.raises(HTTPException) as exc:
await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request", json=proof_accept.model_dump()
)
> assert exc.value.status_code == 400
E assert 422 == 400
E + where 422 = HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}').status_code
E + where HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') = <ExceptionInfo HTTPException(status_code=422, detail='{"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}') tblen=4>.value
app/tests/e2e/verifier/test_predicate_proofs.py:98: AssertionError
Check failure on line 302 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_get_proof_and_get_proofs[clean-clean-clean-clean-clean-clean]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203938cb0>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'0_speed_uuid': {'cred_id...ibutes': {}, 'trace': None}, 'proof_id': 'v2-744259b2-facb-47ad-af36-89dde35fea17', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='e9ac6a68-7d7e-4965-8a07-21e8bc41721f', acme_connection_id='d5b67050-51b2-4014-afac-90bcb8bfe065')
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '62193549-69db-4f72-b652-39cf15905cd9', 'created_at': '2024-11-22T17:41:28.549191Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203938cb0>
@pytest.mark.anyio
async def test_get_proof_and_get_proofs(
acme_and_alice_connection: AcmeAliceConnect,
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
credential_definition_id: str,
acme_client: RichAsyncClient,
alice_member_client: RichAsyncClient,
):
acme_connection_id = acme_and_alice_connection.acme_connection_id
request_body = {
"save_exchange_record": True,
"connection_id": acme_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": credential_definition_id}]
).to_dict(),
}
send_proof_response = await send_proof_request(acme_client, request_body)
# Assert that getting single proof record works
acme_proof_id = send_proof_response["proof_id"]
thread_id = send_proof_response["thread_id"]
response = await acme_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{acme_proof_id}",
)
result = response.json()
assert "connection_id" in result
assert "created_at" in result
assert "updated_at" in result
assert "presentation" in result
assert "presentation_request" in result
await asyncio.sleep(0.3) # allow moment for alice records to update
# Fetch proofs for alice
alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"thread_id": thread_id,
},
)
alice_proof_id = alice_payload["proof_id"]
# Get credential referent for alice to accept request
referent = (
await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
).json()[0]["cred_info"]["referent"]
indy_request_attrs = IndyRequestedCredsRequestedAttr(
cred_id=referent, revealed=True
)
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={"0_speed_uuid": indy_request_attrs},
requested_predicates={},
self_attested_attributes={},
),
)
# Alice accepts
> await alice_member_client.post(
VERIFIER_BASE_PATH + "/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_verifier.py:302:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203938cb0>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 76 in app/tests/e2e/verifier/test_self_attested.py
github-actions / JUnit Test Report
test_self_attested.test_self_attested_attributes[clean-clean-clean-clean-clean-clean]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f6c5a0bb320>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'name_attribute': {'cred_...234567890'}, 'trace': None}, 'proof_id': 'v2-a2539618-c772-4bca-8dc9-28bf771923ef', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f6c5b59f680>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='cb6eb9cb-6be0-4b9e-a066-8478e018a122', acme_connection_id='21aa9761-fc4a-444b-8cdc-bafc3649020a')
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f6c5a0bb320>
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '3509d5d8-eb98-401c-ab43-cdcbe4d55d4d', 'created_at': '2024-11-22T17:41:29.281518Z', 'credential_definition_id': '38rLP4b9vGx9P2mNbR4cCX:3:CL:268:tag', ...}
@pytest.mark.anyio
async def test_self_attested_attributes(
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
alice_member_client: RichAsyncClient,
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
):
request_body = {
"type": "indy",
"indy_proof_request": {
"requested_attributes": {
"name_attribute": {
"name": "name",
},
"self_attested_cell_nr": {
"name": "my_cell_nr",
},
},
"requested_predicates": {},
},
"connection_id": acme_and_alice_connection.acme_connection_id,
"save_exchange_record": True,
}
send_proof_response = await send_proof_request(acme_client, request_body)
thread_id = send_proof_response["thread_id"]
acme_proof_id = send_proof_response["proof_id"]
alice_event = await check_webhook_state(
client=alice_member_client,
topic="proofs",
filter_map={"thread_id": thread_id},
state="request-received",
)
alice_proof_id = alice_event["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={
"name_attribute": {
"cred_id": referent,
"revealed": True,
}
},
requested_predicates={},
self_attested_attributes={
"self_attested_cell_nr": "1234567890",
},
),
)
> response = await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_self_attested.py:76:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f6c5a0bb320>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 74 in app/tests/e2e/verifier/test_predicate_proofs.py
github-actions / JUnit Test Report
test_predicate_proofs.test_predicate_proofs[clean-clean-clean-clean-clean-clean->=]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7d42f0>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {}, 'requested_predicates'...ibutes': {}, 'trace': None}, 'proof_id': 'v2-84cf64a3-a589-4c76-b7ec-3bec3e11bb00', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7d6840>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='96113c70-cb1e-47e2-a766-cd62b5d2b3e2', acme_connection_id='eaaae3ea-3c9a-43e7-86b9-1e6684da8bdf')
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7d42f0>
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '8aedb974-50c4-4e2d-800c-1d1c7379917b', 'created_at': '2024-11-22T17:41:29.927497Z', 'credential_definition_id': '5kZ7Um6dCo4rNzdX8eijAf:3:CL:255:tag', ...}
predicate = '>='
@pytest.mark.anyio
@pytest.mark.parametrize("predicate", ["<", ">", "<=", ">="])
async def test_predicate_proofs(
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
alice_member_client: RichAsyncClient,
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
predicate: str,
):
request_body = {
"type": "indy",
"indy_proof_request": {
"requested_attributes": {},
"requested_predicates": {
"over_18": {
"name": "age",
"p_type": predicate,
"p_value": 18,
}
},
},
"connection_id": acme_and_alice_connection.acme_connection_id,
"save_exchange_record": True,
}
send_proof_response = await send_proof_request(acme_client, request_body)
thread_id = send_proof_response["thread_id"]
alice_event = await check_webhook_state(
client=alice_member_client,
topic="proofs",
filter_map={"thread_id": thread_id},
state="request-received",
)
alice_proof_id = alice_event["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={},
requested_predicates={
"over_18": {
"cred_id": referent,
}
},
self_attested_attributes={},
),
)
if predicate in [">", ">="]:
> response = await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_predicate_proofs.py:74:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7ff2df7d42f0>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 566 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_saving_of_presentation_exchange_records[clean-clean-clean-clean-clean-clean-None-None]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
method = 'post', url = '/v1/verifier/send-request'
kwargs = {'json': {'connection_id': 'bfc3a0ef-7059-4652-a273-a3ea62c42619', 'indy_proof_request': {'name': 'string', 'non_revok...quested_attributes': {'0_speed_uuid': {'name': 'speed', 'restrictions': [{...}]}}, ...}, 'save_exchange_record': None}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/send-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': 'dbb334c2-632b-44ac-8d26-5b91dd3c2575', 'created_at': '2024-11-22T17:41:39.292442Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f72041f7d10>
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='200ca3b1-cbd1-48c4-b364-8caa3d9ac91e', acme_connection_id='bfc3a0ef-7059-4652-a273-a3ea62c42619')
acme_save_exchange_record = None, alice_save_exchange_record = None
@pytest.mark.anyio
@pytest.mark.parametrize("acme_save_exchange_record", [None, False, True])
@pytest.mark.parametrize("alice_save_exchange_record", [None, False, True])
async def test_saving_of_presentation_exchange_records(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
credential_definition_id: str,
alice_member_client: RichAsyncClient,
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
acme_save_exchange_record: Optional[bool],
alice_save_exchange_record: Optional[bool],
):
request_body = {
"connection_id": acme_and_alice_connection.acme_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": credential_definition_id}]
).to_dict(),
"save_exchange_record": acme_save_exchange_record,
}
> send_proof_response = await send_proof_request(acme_client, request_body)
app/tests/e2e/verifier/test_verifier.py:566:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
app/tests/util/verifier.py:10: in send_proof_request
response = await client.post(
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/send-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/send-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 600 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_saving_of_presentation_exchange_records[clean-clean-clean-clean-clean-clean-None-False]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203da3c20>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'0_speed_uuid': {'cred_id...ibutes': {}, 'trace': None}, 'proof_id': 'v2-16d5bd13-d156-4711-8307-b23effa28fb1', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': 'e768b912-999e-4f69-b5f4-0d83867a4172', 'created_at': '2024-11-22T17:41:44.426432Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203da3c20>
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='2b324149-767b-46ac-9f29-556ae0875d3d', acme_connection_id='79060d3e-423b-43d9-8791-6e928a4de16c')
acme_save_exchange_record = False, alice_save_exchange_record = None
@pytest.mark.anyio
@pytest.mark.parametrize("acme_save_exchange_record", [None, False, True])
@pytest.mark.parametrize("alice_save_exchange_record", [None, False, True])
async def test_saving_of_presentation_exchange_records(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
credential_definition_id: str,
alice_member_client: RichAsyncClient,
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
acme_save_exchange_record: Optional[bool],
alice_save_exchange_record: Optional[bool],
):
request_body = {
"connection_id": acme_and_alice_connection.acme_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": credential_definition_id}]
).to_dict(),
"save_exchange_record": acme_save_exchange_record,
}
send_proof_response = await send_proof_request(acme_client, request_body)
acme_proof_id = send_proof_response["proof_id"]
thread_id = send_proof_response["thread_id"]
alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"thread_id": thread_id,
},
)
alice_proof_id = alice_payload["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
indy_request_attrs = IndyRequestedCredsRequestedAttr(
cred_id=referent, revealed=True
)
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={"0_speed_uuid": indy_request_attrs},
requested_predicates={},
self_attested_attributes={},
),
save_exchange_record=alice_save_exchange_record,
)
> response = await alice_member_client.post(
VERIFIER_BASE_PATH + "/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_verifier.py:600:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203da3c20>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 600 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_saving_of_presentation_exchange_records[clean-clean-clean-clean-clean-clean-None-True]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7202dece60>
method = 'post', url = '/v1/verifier/accept-request'
kwargs = {'json': {'dif_presentation_spec': None, 'indy_presentation_spec': {'requested_attributes': {'0_speed_uuid': {'cred_id...ibutes': {}, 'trace': None}, 'proof_id': 'v2-b192346a-2fd5-473a-afdd-27ec5952b8c6', 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '950e904d-58ef-4bcd-b77f-f8f4a6f9a3ad', 'created_at': '2024-11-22T17:41:50.047851Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7202dece60>
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='8322789e-aa68-4876-8e43-2d41aa40bafe', acme_connection_id='99f28de0-5e45-4592-8791-f3351928b731')
acme_save_exchange_record = True, alice_save_exchange_record = None
@pytest.mark.anyio
@pytest.mark.parametrize("acme_save_exchange_record", [None, False, True])
@pytest.mark.parametrize("alice_save_exchange_record", [None, False, True])
async def test_saving_of_presentation_exchange_records(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
credential_definition_id: str,
alice_member_client: RichAsyncClient,
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
acme_save_exchange_record: Optional[bool],
alice_save_exchange_record: Optional[bool],
):
request_body = {
"connection_id": acme_and_alice_connection.acme_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": credential_definition_id}]
).to_dict(),
"save_exchange_record": acme_save_exchange_record,
}
send_proof_response = await send_proof_request(acme_client, request_body)
acme_proof_id = send_proof_response["proof_id"]
thread_id = send_proof_response["thread_id"]
alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"thread_id": thread_id,
},
)
alice_proof_id = alice_payload["proof_id"]
requested_credentials = await alice_member_client.get(
f"{VERIFIER_BASE_PATH}/proofs/{alice_proof_id}/credentials"
)
referent = requested_credentials.json()[0]["cred_info"]["referent"]
indy_request_attrs = IndyRequestedCredsRequestedAttr(
cred_id=referent, revealed=True
)
proof_accept = AcceptProofRequest(
proof_id=alice_proof_id,
indy_presentation_spec=IndyPresSpec(
requested_attributes={"0_speed_uuid": indy_request_attrs},
requested_predicates={},
self_attested_attributes={},
),
save_exchange_record=alice_save_exchange_record,
)
> response = await alice_member_client.post(
VERIFIER_BASE_PATH + "/accept-request",
json=proof_accept.model_dump(),
)
app/tests/e2e/verifier/test_verifier.py:600:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7202dece60>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/accept-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/accept-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 566 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_saving_of_presentation_exchange_records[clean-clean-clean-clean-clean-clean-False-None]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
method = 'post', url = '/v1/verifier/send-request'
kwargs = {'json': {'connection_id': '654cb07d-16c6-4e0f-8523-2db20de78d93', 'indy_proof_request': {'name': 'string', 'non_revok...quested_attributes': {'0_speed_uuid': {'name': 'speed', 'restrictions': [{...}]}}, ...}, 'save_exchange_record': None}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/send-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': 'b74488f2-c91b-4029-9cde-d5cc6c1fe63f', 'created_at': '2024-11-22T17:41:55.727618Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7202dd0770>
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='3e42c4af-bb95-4e05-942f-d7aadd97a9a4', acme_connection_id='654cb07d-16c6-4e0f-8523-2db20de78d93')
acme_save_exchange_record = None, alice_save_exchange_record = False
@pytest.mark.anyio
@pytest.mark.parametrize("acme_save_exchange_record", [None, False, True])
@pytest.mark.parametrize("alice_save_exchange_record", [None, False, True])
async def test_saving_of_presentation_exchange_records(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
credential_definition_id: str,
alice_member_client: RichAsyncClient,
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
acme_save_exchange_record: Optional[bool],
alice_save_exchange_record: Optional[bool],
):
request_body = {
"connection_id": acme_and_alice_connection.acme_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": credential_definition_id}]
).to_dict(),
"save_exchange_record": acme_save_exchange_record,
}
> send_proof_response = await send_proof_request(acme_client, request_body)
app/tests/e2e/verifier/test_verifier.py:566:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
app/tests/util/verifier.py:10: in send_proof_request
response = await client.post(
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/send-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/send-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 566 in app/tests/e2e/verifier/test_verifier.py
github-actions / JUnit Test Report
test_verifier.test_saving_of_presentation_exchange_records[clean-clean-clean-clean-clean-clean-True-None]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
method = 'post', url = '/v1/verifier/send-request'
kwargs = {'json': {'connection_id': '1ddcdee2-514a-4f65-a565-1839cf8e3954', 'indy_proof_request': {'name': 'string', 'non_revok...quested_attributes': {'0_speed_uuid': {'name': 'speed', 'restrictions': [{...}]}}, ...}, 'save_exchange_record': None}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/send-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '7687bec7-ccf9-4d90-ab13-b4ccddf9d632', 'created_at': '2024-11-22T17:42:15.479790Z', 'credential_definition_id': '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag', ...}
credential_definition_id = '5pAv9UW8haJsdJaDTfuCTN:3:CL:216:tag'
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203916870>
acme_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
acme_and_alice_connection = AcmeAliceConnect(alice_connection_id='87b68e73-28b3-4330-8dec-d3f5d1d44789', acme_connection_id='1ddcdee2-514a-4f65-a565-1839cf8e3954')
acme_save_exchange_record = None, alice_save_exchange_record = True
@pytest.mark.anyio
@pytest.mark.parametrize("acme_save_exchange_record", [None, False, True])
@pytest.mark.parametrize("alice_save_exchange_record", [None, False, True])
async def test_saving_of_presentation_exchange_records(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
credential_definition_id: str,
alice_member_client: RichAsyncClient,
acme_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
acme_save_exchange_record: Optional[bool],
alice_save_exchange_record: Optional[bool],
):
request_body = {
"connection_id": acme_and_alice_connection.acme_connection_id,
"indy_proof_request": sample_indy_proof_request(
restrictions=[{"cred_def_id": credential_definition_id}]
).to_dict(),
"save_exchange_record": acme_save_exchange_record,
}
> send_proof_response = await send_proof_request(acme_client, request_body)
app/tests/e2e/verifier/test_verifier.py:566:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
app/tests/util/verifier.py:10: in send_proof_request
response = await client.post(
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7f7203d5eff0>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/send-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/send-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException
Check failure on line 38 in app/tests/e2e/verifier/test_verifier_oob.py
github-actions / JUnit Test Report
test_verifier_oob.test_accept_proof_request_oob[clean-clean-clean-clean-clean-clean]
fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
Raw output
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7feeaa71f320>
method = 'post', url = '/v1/verifier/create-request'
kwargs = {'json': {'comment': 'some comment', 'dif_proof_request': None, 'indy_proof_request': {'name': 'string', 'non_revoked'...{'name': 'speed', 'names': None, 'non_revoked': None, 'restrictions': None}}, ...}, 'save_exchange_record': None, ...}}
attempt = 0, response = <Response [422 Unprocessable Entity]>, code = 422
async def _request_with_retries(self, method: str, url: str, **kwargs) -> Response:
for attempt in range(self.retries):
try:
response = await getattr(super(), method)(url, **kwargs)
> return await self._handle_response(response)
shared/util/rich_async_client.py:67:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:50: in _handle_response
response.raise_for_status() # Raise exception for 4xx and 5xx status codes
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Response [422 Unprocessable Entity]>
def raise_for_status(self) -> Response:
"""
Raise the `HTTPStatusError` if one occurred.
"""
request = self._request
if request is None:
raise RuntimeError(
"Cannot call `raise_for_status` as the request "
"instance has not been set on this response."
)
if self.is_success:
return self
if self.has_redirect_location:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
> raise HTTPStatusError(message, request=request, response=self)
E httpx.HTTPStatusError: Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/create-request'
E For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
/usr/local/lib/python3.12/site-packages/httpx/_models.py:763: HTTPStatusError
The above exception was the direct cause of the following exception:
issue_credential_to_alice = {'attributes': {'age': '44', 'name': 'Alice', 'speed': '10'}, 'connection_id': '1a0f8ec7-f83f-4902-ba45-cae9f720d265', 'created_at': '2024-11-22T17:42:21.076898Z', 'credential_definition_id': 'FaCpQiPvw8aEQ3FkGvG3D5:3:CL:243:tag', ...}
alice_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7feeaa71d460>
bob_member_client = <shared.util.rich_async_client.RichAsyncClient object at 0x7feeaa71f320>
@pytest.mark.anyio
async def test_accept_proof_request_oob(
issue_credential_to_alice: CredentialExchange, # pylint: disable=unused-argument
alice_member_client: RichAsyncClient,
bob_member_client: RichAsyncClient,
):
# Create the proof request against aca-py
create_proof_request = CreateProofRequest(
indy_proof_request=sample_indy_proof_request(),
comment="some comment",
)
> create_proof_response = await bob_member_client.post(
VERIFIER_BASE_PATH + "/create-request",
json=create_proof_request.model_dump(by_alias=True),
)
app/tests/e2e/verifier/test_verifier_oob.py:38:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
shared/util/rich_async_client.py:81: in post
return await self._request_with_retries("post", url, **kwargs)
shared/util/rich_async_client.py:78: in _request_with_retries
await self._handle_error(e, url, method)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <shared.util.rich_async_client.RichAsyncClient object at 0x7feeaa71f320>
e = HTTPStatusError("Client error '422 Unprocessable Entity' for url 'https://tenant-web.cloudapi.dev.didxtech.com/tenant/v1/verifier/create-request'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422")
url = '/v1/verifier/create-request', method = 'post'
async def _handle_error(self, e: HTTPStatusError, url: str, method: str) -> None:
code = e.response.status_code
message = e.response.text
log_message = (
f"{self.name} {method} `{url}` failed. "
f"Status code: {code}. Response: `{message}`."
)
logger.error(log_message)
> raise HTTPException(status_code=code, detail=message) from e
E fastapi.exceptions.HTTPException: 422: {"detail":[{"type":"bool_type","loc":["body","save_exchange_record"],"msg":"Input should be a valid boolean","input":null}]}
shared/util/rich_async_client.py:61: HTTPException