From a971a4f6a8e79ebe7fabe983d9a43e51ef0299b7 Mon Sep 17 00:00:00 2001 From: Jason Sherman Date: Wed, 18 Oct 2023 11:57:54 -0700 Subject: [PATCH] updates to the revocation routes affected by anoncreds-rs Signed-off-by: Jason Sherman --- aries_cloudagent/revocation/routes.py | 6 +- .../revocation/tests/test_routes.py | 705 ++++-------------- 2 files changed, 164 insertions(+), 547 deletions(-) diff --git a/aries_cloudagent/revocation/routes.py b/aries_cloudagent/revocation/routes.py index 7cfbbe7ce9..cc47b73a02 100644 --- a/aries_cloudagent/revocation/routes.py +++ b/aries_cloudagent/revocation/routes.py @@ -15,6 +15,8 @@ from marshmallow import fields, validate, validates_schema from marshmallow.exceptions import ValidationError +from ..anoncreds.models.anoncreds_revocation import RevRegDefState + from ..anoncreds.default.legacy_indy.registry import LegacyIndyRegistry from ..anoncreds.base import ( AnonCredsObjectNotFound, @@ -367,8 +369,8 @@ class SetRevRegStateQueryStringSchema(OpenAPISchema): required=True, validate=validate.OneOf( [ - getattr(IssuerRevRegRecord, m) - for m in vars(IssuerRevRegRecord) + getattr(RevRegDefState, m) + for m in vars(RevRegDefState) if m.startswith("STATE_") ] ), diff --git a/aries_cloudagent/revocation/tests/test_routes.py b/aries_cloudagent/revocation/tests/test_routes.py index f17d7dc735..7c8d113d4f 100644 --- a/aries_cloudagent/revocation/tests/test_routes.py +++ b/aries_cloudagent/revocation/tests/test_routes.py @@ -2,22 +2,25 @@ import shutil import unittest -from aiohttp.web import HTTPBadRequest, HTTPNotFound +from aiohttp.web import HTTPNotFound from asynctest import TestCase as AsyncTestCase from asynctest import mock as async_mock -import pytest -from aries_cloudagent.core.in_memory import InMemoryProfile -from aries_cloudagent.revocation.error import RevocationError -from ...storage.in_memory import InMemoryStorage +from ...anoncreds.models.anoncreds_revocation import ( + RevRegDef, + RevRegDefValue, +) +from ...askar.profile import AskarProfile + +from ...core.in_memory import InMemoryProfile from .. import routes as test_module class TestRevocationRoutes(AsyncTestCase): def setUp(self): - self.profile = InMemoryProfile.test_profile() + self.profile = InMemoryProfile.test_profile(profile_class=AskarProfile) self.context = self.profile.context setattr(self.context, "profile", self.profile) self.request_dict = { @@ -169,125 +172,6 @@ async def test_publish_revocations_x(self): with self.assertRaises(test_module.web.HTTPBadRequest): await test_module.publish_revocations(self.request) - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_clear_pending_revocations(self): - self.request.json = async_mock.CoroutineMock() - - with async_mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, async_mock.patch.object( - test_module.web, "json_response" - ) as mock_response: - clear_pending = async_mock.CoroutineMock() - mock_mgr.return_value.clear_pending_revocations = clear_pending - - await test_module.clear_pending_revocations(self.request) - - mock_response.assert_called_once_with( - {"rrid2crid": clear_pending.return_value} - ) - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_clear_pending_revocations_x(self): - self.request.json = async_mock.CoroutineMock() - - with async_mock.patch.object( - test_module, "RevocationManager", autospec=True - ) as mock_mgr, async_mock.patch.object( - test_module.web, "json_response" - ) as mock_response: - clear_pending = async_mock.CoroutineMock( - side_effect=test_module.StorageError() - ) - mock_mgr.return_value.clear_pending_revocations = clear_pending - - with self.assertRaises(test_module.web.HTTPBadRequest): - await test_module.clear_pending_revocations(self.request) - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_create_rev_reg(self): - CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" - self.request.json = async_mock.CoroutineMock( - return_value={ - "max_cred_num": "1000", - "credential_definition_id": CRED_DEF_ID, - } - ) - - with async_mock.patch.object( - InMemoryStorage, "find_all_records", autospec=True - ) as mock_find, async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_find.return_value = True - mock_indy_revoc.return_value = async_mock.MagicMock( - init_issuer_registry=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - generate_registry=async_mock.CoroutineMock(), - serialize=async_mock.MagicMock(return_value="dummy"), - ) - ) - ) - - result = await test_module.create_rev_reg(self.request) - mock_json_response.assert_called_once_with({"result": "dummy"}) - assert result is mock_json_response.return_value - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_create_rev_reg_no_such_cred_def(self): - CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" - self.request.json = async_mock.CoroutineMock( - return_value={ - "max_cred_num": "1000", - "credential_definition_id": CRED_DEF_ID, - } - ) - - with async_mock.patch.object( - InMemoryStorage, "find_all_records", autospec=True - ) as mock_find, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_find.return_value = False - - with self.assertRaises(HTTPNotFound): - result = await test_module.create_rev_reg(self.request) - mock_json_response.assert_not_called() - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_create_rev_reg_no_revo_support(self): - CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" - self.request.json = async_mock.CoroutineMock( - return_value={ - "max_cred_num": "1000", - "credential_definition_id": CRED_DEF_ID, - } - ) - - with async_mock.patch.object( - InMemoryStorage, "find_all_records", autospec=True - ) as mock_find, async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_find = True - mock_indy_revoc.return_value = async_mock.MagicMock( - init_issuer_registry=async_mock.CoroutineMock( - side_effect=test_module.RevocationNotSupportedError( - error_code="dummy" - ) - ) - ) - - with self.assertRaises(HTTPBadRequest): - result = await test_module.create_rev_reg(self.request) - - mock_json_response.assert_not_called() - - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_rev_regs_created(self): CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" self.request.query = { @@ -296,41 +180,81 @@ async def test_rev_regs_created(self): } with async_mock.patch.object( - test_module.IssuerRevRegRecord, "query", async_mock.CoroutineMock() + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definitions", + async_mock.CoroutineMock(), ) as mock_query, async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ) as mock_json_response: - mock_query.return_value = [async_mock.MagicMock(revoc_reg_id="dummy")] + mock_query.return_value = ["dummy"] result = await test_module.rev_regs_created(self.request) mock_json_response.assert_called_once_with({"rev_reg_ids": ["dummy"]}) assert result is mock_json_response.return_value - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_get_rev_reg(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did ) + RECORD_ID = "4ba81d6e-f341-4e37-83d4-6b1d3e25a7bd" self.request.match_info = {"rev_reg_id": REV_REG_ID} with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, async_mock.patch.object( + test_module.uuid, "uuid4", async_mock.Mock() + ) as mock_uuid, async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - serialize=async_mock.MagicMock(return_value="dummy") + mock_uuid.return_value = RECORD_ID + mock_anon_creds_revoc.return_value = async_mock.MagicMock( + get_created_revocation_registry_definition=async_mock.CoroutineMock( + return_value=RevRegDef( + issuer_id="issuer_id", + type="CL_ACCUM", + cred_def_id="cred_def_id", + tag="tag", + value=RevRegDefValue( + public_keys={}, + max_cred_num=100, + tails_hash="tails_hash", + tails_location="tails_location", + ), ) - ) + ), + get_created_revocation_registry_definition_state=async_mock.CoroutineMock( + return_value=test_module.RevRegDefState.STATE_FINISHED + ), + get_pending_revocations=async_mock.CoroutineMock(return_value=[]), ) result = await test_module.get_rev_reg(self.request) - mock_json_response.assert_called_once_with({"result": "dummy"}) + mock_json_response.assert_called_once_with( + { + "result": { + "tails_local_path": "tails_location", + "tails_hash": "tails_hash", + "state": test_module.RevRegDefState.STATE_FINISHED, + "issuer_did": "issuer_id", + "pending_pub": [], + "revoc_reg_def": { + "ver": "1.0", + "id": REV_REG_ID, + "revocDefType": "CL_ACCUM", + "tag": "tag", + "credDefId": "cred_def_id", + }, + "max_cred_num": 100, + "record_id": RECORD_ID, + "tag": "tag", + "revoc_def_type": "CL_ACCUM", + "revoc_reg_id": REV_REG_ID, + "cred_def_id": "cred_def_id", + } + } + ) assert result is mock_json_response.return_value - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_get_rev_reg_not_found(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did @@ -338,21 +262,20 @@ async def test_get_rev_reg_not_found(self): self.request.match_info = {"rev_reg_id": REV_REG_ID} with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError(error_code="dummy") - ) + mock_anon_creds_revoc.return_value = async_mock.MagicMock( + get_created_revocation_registry_definition=async_mock.CoroutineMock( + return_value=None + ), ) with self.assertRaises(HTTPNotFound): result = await test_module.get_rev_reg(self.request) mock_json_response.assert_not_called() - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_get_rev_reg_issued(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did @@ -360,23 +283,23 @@ async def test_get_rev_reg_issued(self): self.request.match_info = {"rev_reg_id": REV_REG_ID} with async_mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_revoc_reg_id", - async_mock.CoroutineMock(), - ) as mock_retrieve, async_mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + autospec=True, + ) as mock_rev_reg_def, async_mock.patch.object( test_module.IssuerCredRevRecord, "query_by_ids", async_mock.CoroutineMock(), ) as mock_query, async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ) as mock_json_response: - mock_query.return_value = return_value = [{"...": "..."}, {"...": "..."}] + mock_rev_reg_def.return_value = {} + mock_query.return_value = return_value = [{}, {}] result = await test_module.get_rev_reg_issued_count(self.request) mock_json_response.assert_called_once_with({"result": 2}) assert result is mock_json_response.return_value - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_get_rev_reg_issued_x(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did @@ -384,11 +307,11 @@ async def test_get_rev_reg_issued_x(self): self.request.match_info = {"rev_reg_id": REV_REG_ID} with async_mock.patch.object( - test_module.IssuerRevRegRecord, - "retrieve_by_revoc_reg_id", - async_mock.CoroutineMock(), - ) as mock_retrieve: - mock_retrieve.side_effect = test_module.StorageNotFoundError("no such rec") + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + autospec=True, + ) as mock_rev_reg_def: + mock_rev_reg_def.return_value = None with self.assertRaises(test_module.web.HTTPNotFound): await test_module.get_rev_reg_issued(self.request) @@ -461,49 +384,6 @@ async def test_get_cred_rev_record_not_found(self): with self.assertRaises(test_module.web.HTTPNotFound): await test_module.get_cred_rev_record(self.request) - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_get_active_rev_reg(self): - CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" - self.request.match_info = {"cred_def_id": CRED_DEF_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_active_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - serialize=async_mock.MagicMock(return_value="dummy") - ) - ) - ) - - result = await test_module.get_active_rev_reg(self.request) - mock_json_response.assert_called_once_with({"result": "dummy"}) - assert result is mock_json_response.return_value - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_get_active_rev_reg_not_found(self): - CRED_DEF_ID = f"{self.test_did}:3:CL:1234:default" - self.request.match_info = {"cred_def_id": CRED_DEF_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_active_issuer_rev_reg_record=async_mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError(error_code="dummy") - ) - ) - - with self.assertRaises(HTTPNotFound): - result = await test_module.get_active_rev_reg(self.request) - mock_json_response.assert_not_called() - - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_get_tails_file(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did @@ -511,21 +391,31 @@ async def test_get_tails_file(self): self.request.match_info = {"rev_reg_id": REV_REG_ID} with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + async_mock.CoroutineMock(), + ) as mock_get_rev_reg, async_mock.patch.object( test_module.web, "FileResponse", async_mock.Mock() ) as mock_file_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock(tails_local_path="dummy") - ) + mock_get_rev_reg.return_value = RevRegDef( + issuer_id="issuer_id", + type="CL_ACCUM", + cred_def_id="cred_def_id", + tag="tag", + value=RevRegDefValue( + public_keys={}, + max_cred_num=100, + tails_hash="tails_hash", + tails_location="tails_location", + ), ) result = await test_module.get_tails_file(self.request) - mock_file_response.assert_called_once_with(path="dummy", status=200) + mock_file_response.assert_called_once_with( + path="tails_location", status=200 + ) assert result is mock_file_response.return_value - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_get_tails_file_not_found(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did @@ -533,379 +423,104 @@ async def test_get_tails_file_not_found(self): self.request.match_info = {"rev_reg_id": REV_REG_ID} with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + async_mock.CoroutineMock(), + ) as mock_get_rev_reg, async_mock.patch.object( test_module.web, "FileResponse", async_mock.Mock() ) as mock_file_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError(error_code="dummy") - ) - ) + mock_get_rev_reg.return_value = None with self.assertRaises(HTTPNotFound): result = await test_module.get_tails_file(self.request) mock_file_response.assert_not_called() - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_upload_tails_file_basic(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_upload = async_mock.CoroutineMock() - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - tails_local_path=f"/tmp/tails/{REV_REG_ID}", - has_local_tails_file=True, - upload_tails_file=mock_upload, - ) - ) - ) - result = await test_module.upload_tails_file(self.request) - mock_upload.assert_awaited_once() - mock_json_response.assert_called_once_with({}) - assert result is mock_json_response.return_value - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_upload_tails_file_no_local_tails_file(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - tails_local_path=f"/tmp/tails/{REV_REG_ID}", - has_local_tails_file=False, - ) - ) - ) - - with self.assertRaises(test_module.web.HTTPNotFound): - await test_module.upload_tails_file(self.request) - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_upload_tails_file_fail(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc: - mock_upload = async_mock.CoroutineMock(side_effect=RevocationError("test")) - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - tails_local_path=f"/tmp/tails/{REV_REG_ID}", - has_local_tails_file=True, - upload_tails_file=mock_upload, - ) - ) - ) - - with self.assertRaises(test_module.web.HTTPInternalServerError): - await test_module.upload_tails_file(self.request) - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_send_rev_reg_def(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - send_def=async_mock.CoroutineMock(), - send_entry=async_mock.CoroutineMock(), - serialize=async_mock.MagicMock(return_value="dummy"), - ) - ) - ) - - result = await test_module.send_rev_reg_def(self.request) - mock_json_response.assert_called_once_with({"result": "dummy"}) - assert result is mock_json_response.return_value - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_send_rev_reg_def_not_found(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "FileResponse", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError(error_code="dummy") - ) - ) - - with self.assertRaises(HTTPNotFound): - result = await test_module.send_rev_reg_def(self.request) - mock_json_response.assert_not_called() - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_send_rev_reg_def_x(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - send_def=async_mock.CoroutineMock( - side_effect=test_module.RevocationError() - ), - ) - ) - ) - - with self.assertRaises(test_module.web.HTTPBadRequest): - await test_module.send_rev_reg_def(self.request) - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_send_rev_reg_entry(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - send_entry=async_mock.CoroutineMock(), - serialize=async_mock.MagicMock(return_value="dummy"), - ) - ) - ) - - result = await test_module.send_rev_reg_entry(self.request) - mock_json_response.assert_called_once_with({"result": "dummy"}) - assert result is mock_json_response.return_value - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_send_rev_reg_entry_not_found(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "FileResponse", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError(error_code="dummy") - ) - ) - - with self.assertRaises(HTTPNotFound): - result = await test_module.send_rev_reg_entry(self.request) - mock_json_response.assert_not_called() - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_send_rev_reg_entry_x(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - send_entry=async_mock.CoroutineMock( - side_effect=test_module.RevocationError() - ), - ) - ) - ) - - with self.assertRaises(test_module.web.HTTPBadRequest): - await test_module.send_rev_reg_entry(self.request) - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_update_rev_reg(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - self.request.json = async_mock.CoroutineMock( - return_value={ - "tails_public_uri": f"http://sample.ca:8181/tails/{REV_REG_ID}" - } - ) - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "json_response", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - set_tails_file_public_uri=async_mock.CoroutineMock(), - save=async_mock.CoroutineMock(), - serialize=async_mock.MagicMock(return_value="dummy"), - ) - ) - ) - - result = await test_module.update_rev_reg(self.request) - mock_json_response.assert_called_once_with({"result": "dummy"}) - assert result is mock_json_response.return_value - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_update_rev_reg_not_found(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - self.request.json = async_mock.CoroutineMock( - return_value={ - "tails_public_uri": f"http://sample.ca:8181/tails/{REV_REG_ID}" - } - ) - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "FileResponse", async_mock.Mock() - ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError(error_code="dummy") - ) - ) - - with self.assertRaises(HTTPNotFound): - result = await test_module.update_rev_reg(self.request) - mock_json_response.assert_not_called() - - @pytest.mark.skip(reason="anoncreds-rs breaking change") - async def test_update_rev_reg_x(self): - REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( - self.test_did, self.test_did - ) - self.request.match_info = {"rev_reg_id": REV_REG_ID} - self.request.json = async_mock.CoroutineMock( - return_value={ - "tails_public_uri": f"http://sample.ca:8181/tails/{REV_REG_ID}" - } - ) - - with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - set_tails_file_public_uri=async_mock.CoroutineMock( - side_effect=test_module.RevocationError() - ), - ) - ) - ) - - with self.assertRaises(test_module.web.HTTPBadRequest): - await test_module.update_rev_reg(self.request) - - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_set_rev_reg_state(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did ) + RECORD_ID = "4ba81d6e-f341-4e37-83d4-6b1d3e25a7bd" self.request.match_info = {"rev_reg_id": REV_REG_ID} - self.request.json = async_mock.CoroutineMock( - return_value={ - "max_cred_num": "1000", - } - ) + self.request.query = { - "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, + "state": test_module.RevRegDefState.STATE_FINISHED, } with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( + test_module, "AnonCredsRevocation", autospec=True + ) as mock_anon_creds_revoc, async_mock.patch.object( + test_module.uuid, "uuid4", async_mock.Mock() + ) as mock_uuid, async_mock.patch.object( test_module.web, "json_response", async_mock.Mock() ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - return_value=async_mock.MagicMock( - set_state=async_mock.CoroutineMock(), - save=async_mock.CoroutineMock(), - serialize=async_mock.MagicMock(return_value="dummy"), + mock_uuid.return_value = RECORD_ID + mock_anon_creds_revoc.return_value = async_mock.MagicMock( + set_rev_reg_state=async_mock.CoroutineMock(return_value={}), + get_created_revocation_registry_definition=async_mock.CoroutineMock( + return_value=RevRegDef( + issuer_id="issuer_id", + type="CL_ACCUM", + cred_def_id="cred_def_id", + tag="tag", + value=RevRegDefValue( + public_keys={}, + max_cred_num=100, + tails_hash="tails_hash", + tails_location="tails_location", + ), ) - ) + ), + get_created_revocation_registry_definition_state=async_mock.CoroutineMock( + return_value=test_module.RevRegDefState.STATE_FINISHED + ), + get_pending_revocations=async_mock.CoroutineMock(return_value=[]), ) result = await test_module.set_rev_reg_state(self.request) - mock_json_response.assert_called_once_with({"result": "dummy"}) + mock_json_response.assert_called_once_with( + { + "result": { + "tails_local_path": "tails_location", + "tails_hash": "tails_hash", + "state": test_module.RevRegDefState.STATE_FINISHED, + "issuer_did": "issuer_id", + "pending_pub": [], + "revoc_reg_def": { + "ver": "1.0", + "id": REV_REG_ID, + "revocDefType": "CL_ACCUM", + "tag": "tag", + "credDefId": "cred_def_id", + }, + "max_cred_num": 100, + "record_id": RECORD_ID, + "tag": "tag", + "revoc_def_type": "CL_ACCUM", + "revoc_reg_id": REV_REG_ID, + "cred_def_id": "cred_def_id", + } + } + ) assert result is mock_json_response.return_value - @pytest.mark.skip(reason="anoncreds-rs breaking change") async def test_set_rev_reg_state_not_found(self): REV_REG_ID = "{}:4:{}:3:CL:1234:default:CL_ACCUM:default".format( self.test_did, self.test_did ) self.request.match_info = {"rev_reg_id": REV_REG_ID} - self.request.json = async_mock.CoroutineMock( - return_value={ - "max_cred_num": "1000", - } - ) + self.request.query = { - "state": test_module.IssuerRevRegRecord.STATE_ACTIVE, + "state": test_module.RevRegDefState.STATE_FINISHED, } with async_mock.patch.object( - test_module, "IndyRevocation", autospec=True - ) as mock_indy_revoc, async_mock.patch.object( - test_module.web, "FileResponse", async_mock.Mock() + test_module.AnonCredsRevocation, + "get_created_revocation_registry_definition", + async_mock.CoroutineMock(), + ) as mock_rev_reg_def, async_mock.patch.object( + test_module.web, "json_response", async_mock.Mock() ) as mock_json_response: - mock_indy_revoc.return_value = async_mock.MagicMock( - get_issuer_rev_reg_record=async_mock.CoroutineMock( - side_effect=test_module.StorageNotFoundError(error_code="dummy") - ) - ) + mock_rev_reg_def.return_value = None with self.assertRaises(HTTPNotFound): result = await test_module.set_rev_reg_state(self.request)