Skip to content

Commit

Permalink
Regression test valid credential (#805)
Browse files Browse the repository at this point in the history
* add new fixture to conftest

* rename to exchange id

* add new fixture get or issue valid alice cred

* formatting

* add new regression test proof request against valid credential

* 🎨 rename credential_id

* 🎨

* 🎨 remove SKIP_CLEAN_TESTS setting

* 🎨 rename fixture labels for clean_run and regression_run

---------

Co-authored-by: ff137 <[email protected]>
Co-authored-by: cl0ete <[email protected]>
  • Loading branch information
cl0ete and ff137 authored May 16, 2024
1 parent 274e8a6 commit da56200
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 15 deletions.
1 change: 1 addition & 0 deletions app/tests/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
)
from app.tests.fixtures.credentials import (
get_or_issue_regression_cred_revoked,
get_or_issue_regression_cred_valid,
issue_alice_creds,
issue_credential_to_alice,
meld_co_issue_credential_to_alice,
Expand Down
90 changes: 90 additions & 0 deletions app/tests/e2e/verifier/test_verifier.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
import json
import time

import pytest
from aries_cloudcontroller import IndyPresSpec, IndyRequestedCredsRequestedAttr
Expand All @@ -11,8 +12,10 @@
from app.routes.oob import router as oob_router
from app.routes.verifier import AcceptProofRequest, RejectProofRequest
from app.routes.verifier import router as verifier_router
from app.tests.fixtures.credentials import ReferentCredDef
from app.tests.services.verifier.utils import indy_proof_request
from app.tests.util.connections import AcmeAliceConnect, MeldCoAliceConnect
from app.tests.util.regression_testing import TestMode
from app.tests.util.verifier import send_proof_request
from app.tests.util.webhooks import check_webhook_state
from shared import RichAsyncClient
Expand Down Expand Up @@ -664,3 +667,90 @@ async def test_saving_of_presentation_exchange_records(
with pytest.raises(HTTPException) as exc:
await acme_client.get(f"{VERIFIER_BASE_PATH}/proofs/{acme_proof_id}")
assert exc.value.status_code == 404


@pytest.mark.anyio
@pytest.mark.skipif(
TestMode.clean_run in TestMode.fixture_params,
reason="Run only in regression mode",
)
async def test_regression_proof_valid_credential(
get_or_issue_regression_cred_valid: ReferentCredDef,
acme_client: RichAsyncClient,
alice_member_client: RichAsyncClient,
acme_and_alice_connection: AcmeAliceConnect,
):
unix_timestamp = int(time.time())
referent = get_or_issue_regression_cred_valid.referent
credential_definition_id_revocable = (
get_or_issue_regression_cred_valid.cred_def_revocable
)

# Do proof request
request_body = {
"protocol_version": "v2",
"comment": "Test cred is not revoked",
"type": "indy",
"indy_proof_request": {
"non_revoked": {"to": unix_timestamp},
"requested_attributes": {
"THE_SPEED": {
"name": "speed",
"restrictions": [
{"cred_def_id": credential_definition_id_revocable}
],
}
},
"requested_predicates": {},
},
"save_exchange_record": True,
"connection_id": acme_and_alice_connection.acme_connection_id,
}
send_proof_response = await send_proof_request(acme_client, request_body)
acme_proof_exchange_id = send_proof_response["proof_id"]

alice_payload = await check_webhook_state(
client=alice_member_client,
topic="proofs",
state="request-received",
filter_map={
"thread_id": send_proof_response["thread_id"],
},
look_back=5,
)

alice_proof_exchange_id = alice_payload["proof_id"]

# Send proof
await alice_member_client.post(
f"{VERIFIER_BASE_PATH}/accept-request",
json={
"proof_id": alice_proof_exchange_id,
"type": "indy",
"indy_presentation_spec": {
"requested_attributes": {
"THE_SPEED": {"cred_id": referent, "revealed": True}
},
"requested_predicates": {},
"self_attested_attributes": {},
},
"dif_presentation_spec": {},
},
)

await check_webhook_state(
client=acme_client,
topic="proofs",
state="done",
filter_map={
"proof_id": acme_proof_exchange_id,
},
look_back=5,
)

# Check proof
proof = (
await acme_client.get(f"{VERIFIER_BASE_PATH}/proofs/{acme_proof_exchange_id}")
).json()

assert proof["verified"] is True
89 changes: 87 additions & 2 deletions app/tests/fixtures/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ async def revoke_alice_creds(
await faber_client.post(
f"{CREDENTIALS_BASE_PATH}/revoke",
json={
"credential_exchange_id": cred.credential_id,
"credential_exchange_id": cred.credential_exchange_id,
},
)

Expand All @@ -239,7 +239,7 @@ async def revoke_alice_creds_and_publish(
await faber_client.post(
f"{CREDENTIALS_BASE_PATH}/revoke",
json={
"credential_exchange_id": cred.credential_id,
"credential_exchange_id": cred.credential_exchange_id,
"auto_publish_on_ledger": auto_publish,
},
)
Expand Down Expand Up @@ -353,3 +353,88 @@ async def get_or_issue_regression_cred_revoked(
referent=revoked_credential["referent"],
cred_def_revocable=revoked_credential["cred_def_id"],
)


@pytest.fixture(scope="function")
async def get_or_issue_regression_cred_valid(
faber_client: RichAsyncClient,
alice_member_client: RichAsyncClient,
credential_definition_id_revocable: str,
faber_and_alice_connection: FaberAliceConnect,
):
valid_credential_attribute_name = "Alice-valid"

# Wallet Query to fetch credential with this attribute name
wql = quote(f'{{"attr::name::value":"{valid_credential_attribute_name}"}}')

results = (await alice_member_client.get(f"{WALLET_BASE_PATH}?wql={wql}")).json()[
"results"
]
assert (
len(results) < 2
), f"Should have 1 or 0 credentials with this attr name, got: {results}"

if results:
valid_credential = results[0]
assert (
valid_credential["attrs"]["name"] == valid_credential_attribute_name
), f"WQL returned unexpected credential: {valid_credential}"

else:
# Cred doesn't yet exist; issue credential for regression testing
assert_fail_on_recreating_fixtures()

credential = {
"protocol_version": "v2",
"connection_id": faber_and_alice_connection.faber_connection_id,
"save_exchange_record": True,
"indy_credential_detail": {
"credential_definition_id": credential_definition_id_revocable,
"attributes": {
"speed": "10",
"name": valid_credential_attribute_name,
"age": "44",
},
},
}

# Faber sends credential
faber_send_response = await faber_client.post(
CREDENTIALS_BASE_PATH,
json=credential,
)

alice_payload = await check_webhook_state(
client=alice_member_client,
topic="credentials",
state="offer-received",
filter_map={
"thread_id": faber_send_response.json()["thread_id"],
},
)
alice_cred_ex_id = alice_payload["credential_exchange_id"]

# Alice accepts credential
await alice_member_client.post(
f"{CREDENTIALS_BASE_PATH}/{alice_cred_ex_id}/request", json={}
)

await check_webhook_state(
client=alice_member_client,
topic="credentials",
state="done",
filter_map={
"credential_exchange_id": alice_cred_ex_id,
},
)

# Alice fetches the valid credential
wallet_credentials = await alice_member_client.get(
f"{WALLET_BASE_PATH}?wql={wql}"
)
valid_credential = wallet_credentials.json()["results"][0]

return ReferentCredDef(
referent=valid_credential["referent"],
cred_def_revocable=valid_credential["cred_def_id"],
)
20 changes: 7 additions & 13 deletions app/tests/util/regression_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,21 @@ class RegressionTestConfig:
reused_connection_alias = "RegressionTestConnection"

run_regression_tests = os.getenv("RUN_REGRESSION_TESTS", "false").upper() == "TRUE"
skip_clean_tests = os.getenv("SKIP_CLEAN_TESTS", "false").upper() == "TRUE"
delete_fixtures_after_run = (
os.getenv("DELETE_REGRESSION_FIXTURES", "false").upper() == "TRUE"
)
fail_on_recreating_fixtures = (
os.getenv("FAIL_ON_RECREATING_FIXTURES", "false").upper() == "TRUE"
)
delete_fixtures_after_run = (
os.getenv("DELETE_REGRESSION_FIXTURES", "false").upper() == "TRUE"
)


class TestMode:
clean_run = "clean_run"
regression_run = "regression_run"
clean_run = "clean"
regression_run = "reuse"

clean_run_param = (
[clean_run] if RegressionTestConfig.skip_clean_tests is False else []
fixture_params = (
[regression_run] if RegressionTestConfig.run_regression_tests else [clean_run]
)
regression_run_param = (
[regression_run] if RegressionTestConfig.run_regression_tests else []
)

fixture_params = clean_run_param + regression_run_param


def assert_fail_on_recreating_fixtures():
Expand Down

0 comments on commit da56200

Please sign in to comment.