From ad9d93ca3c2ccfb55e43e12e07edcfa3639ddead Mon Sep 17 00:00:00 2001 From: Hardik Sharma Date: Wed, 4 Sep 2024 19:55:17 +0530 Subject: [PATCH 1/6] aded failure tests for did creation --- tests/test_did.py | 131 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/tests/test_did.py b/tests/test_did.py index 630e905..5c0e55d 100644 --- a/tests/test_did.py +++ b/tests/test_did.py @@ -153,6 +153,137 @@ def test_create_did(self, mock_config_service_get, mock_get_store_tx, mock_gener self.assertEqual(result["mnemonic"], mnemonic) self.assertEqual(result["document"], "mocked_document") + @patch('packages.sdk.src.Did.generate_mnemonic') + @patch('packages.sdk.src.Did.generate_keypairs') + @patch('packages.sdk.src.Did.get_store_tx') + @patch('packages.sdk.src.ConfigService.get') + def test_create_did_failure(self, mock_config_service_get, mock_get_store_tx, mock_generate_keypairs, mock_generate_mnemonic): + # Mock the return values of the functions and methods + mock_api = MagicMock() + mock_config_service_get.return_value = mock_api + + mnemonic = "use stereo ostrich special broccoli hurdle share subway jewel truck almost noodle loud goat more enhance brisk hope attend girl city catch mistake differ" + mock_generate_mnemonic.return_value = mnemonic + mock_keypairs = { + "authentication": MagicMock(), + "key_agreement": MagicMock(), + "assertion_method": MagicMock(), + "capability_delegation": MagicMock() + } + mock_generate_keypairs.return_value = mock_keypairs + + mock_get_store_tx.return_value = "mocked_tx" + + mock_api.create_signed_extrinsic = MagicMock() + mock_api.submit_extrinsic = MagicMock() + mock_api.runtime_call = MagicMock(return_value="mocked_encoded_did") + + # Simulate failure by returning None or an empty dictionary from linked_info_from_chain + with patch('packages.sdk.src.Did.get_did_uri_from_key', return_value="did:cord:3vRsRQmgpuuyzkfMYwnAMuT9LKwxZMedbBGmAicrXk7EhsEr") as mock_get_did_uri_from_key, \ + patch('packages.sdk.src.Did.linked_info_from_chain', return_value=None) as mock_linked_info_from_chain: + + submitter_account = MagicMock() + submitter_account.ss58_address = "mocked_address" + + # Call the function and expect it to raise an exception + with self.assertRaises(Exception) as context: + asyncio.run(Cord.Did.create_did(submitter_account)) + + # Assertions + mock_generate_mnemonic.assert_called_once_with(24) + mock_generate_keypairs.assert_called_once_with(mnemonic, "sr25519") + mock_get_store_tx.assert_called_once() + mock_api.create_signed_extrinsic.assert_called_once_with("mocked_tx", submitter_account) + mock_api.submit_extrinsic.assert_called_once() + mock_get_did_uri_from_key.assert_called_once() + mock_api.runtime_call.assert_called_once_with("DidApi", "query", ["3vRsRQmgpuuyzkfMYwnAMuT9LKwxZMedbBGmAicrXk7EhsEr"]) + mock_linked_info_from_chain.assert_called_once_with("mocked_encoded_did") + + # Check that the correct exception message is raised + self.assertEqual(str(context.exception), "DID was not successfully created.") + + + @patch('packages.sdk.src.Did.generate_mnemonic') + @patch('packages.sdk.src.Did.generate_keypairs') + @patch('packages.sdk.src.Did.get_store_tx') + @patch('packages.sdk.src.ConfigService.get') + def test_create_did_failure_in_tx_creation(self, mock_config_service_get, mock_get_store_tx, mock_generate_keypairs, mock_generate_mnemonic): + # Mock the return values of the functions and methods + mock_api = MagicMock() + mock_config_service_get.return_value = mock_api + + mnemonic = "use stereo ostrich special broccoli hurdle share subway jewel truck almost noodle loud goat more enhance brisk hope attend girl city catch mistake differ" + mock_generate_mnemonic.return_value = mnemonic + mock_keypairs = { + "authentication": MagicMock(), + "key_agreement": MagicMock(), + "assertion_method": MagicMock(), + "capability_delegation": MagicMock() + } + mock_generate_keypairs.return_value = mock_keypairs + + # Simulate failure in transaction creation + mock_get_store_tx.side_effect = Exception("Failed to create transaction") + + submitter_account = MagicMock() + submitter_account.ss58_address = "mocked_address" + + # Call the function and expect it to raise an exception + with self.assertRaises(Exception) as context: + asyncio.run(Cord.Did.create_did(submitter_account)) + + # Assertions + mock_generate_mnemonic.assert_called_once_with(24) + mock_generate_keypairs.assert_called_once_with(mnemonic, "sr25519") + mock_get_store_tx.assert_called_once() + + # Check that the correct exception message is raised + self.assertEqual(str(context.exception), "Failed to create transaction") + + @patch('packages.sdk.src.Did.generate_mnemonic') + @patch('packages.sdk.src.Did.generate_keypairs') + @patch('packages.sdk.src.Did.get_store_tx') + @patch('packages.sdk.src.ConfigService.get') + def test_create_did_failure_in_submission(self, mock_config_service_get, mock_get_store_tx, mock_generate_keypairs, mock_generate_mnemonic): + # Mock the return values of the functions and methods + mock_api = MagicMock() + mock_config_service_get.return_value = mock_api + + mnemonic = "use stereo ostrich special broccoli hurdle share subway jewel truck almost noodle loud goat more enhance brisk hope attend girl city catch mistake differ" + mock_generate_mnemonic.return_value = mnemonic + mock_keypairs = { + "authentication": MagicMock(), + "key_agreement": MagicMock(), + "assertion_method": MagicMock(), + "capability_delegation": MagicMock() + } + mock_generate_keypairs.return_value = mock_keypairs + + mock_get_store_tx.return_value = "mocked_tx" + + mock_api.create_signed_extrinsic = MagicMock() + + # Simulate failure in submitting the transaction + mock_api.submit_extrinsic.side_effect = Exception("Failed to submit transaction") + + submitter_account = MagicMock() + submitter_account.ss58_address = "mocked_address" + + # Call the function and expect it to raise an exception + with self.assertRaises(Exception) as context: + asyncio.run(Cord.Did.create_did(submitter_account)) + + # Assertions + mock_generate_mnemonic.assert_called_once_with(24) + mock_generate_keypairs.assert_called_once_with(mnemonic, "sr25519") + mock_get_store_tx.assert_called_once() + mock_api.create_signed_extrinsic.assert_called_once_with("mocked_tx", submitter_account) + mock_api.submit_extrinsic.assert_called_once() + + # Check that the correct exception message is raised + self.assertEqual(str(context.exception), "Failed to submit transaction") + + @patch('packages.sdk.src.ConfigService.get') @patch('packages.sdk.src.Did.get_address_by_key') @patch('packages.sdk.src.Did.public_key_to_chain_for_keypair') From 40ed31e03a55529966f0e9b15933163426517589 Mon Sep 17 00:00:00 2001 From: Hardik Sharma Date: Fri, 6 Sep 2024 00:30:54 +0530 Subject: [PATCH 2/6] statement tests --- packages/statement/src/statement_chain.py | 2 +- tests/test_statement.py | 159 ++++++++++++++++++++++ 2 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 tests/test_statement.py diff --git a/packages/statement/src/statement_chain.py b/packages/statement/src/statement_chain.py index e7075ea..1cbde8d 100644 --- a/packages/statement/src/statement_chain.py +++ b/packages/statement/src/statement_chain.py @@ -121,7 +121,7 @@ async def prepare_extrinsic_to_register( if exists: raise Errors.DuplicateStatementError( - f"The statement is already anchored in the chain\nIdentifier: {stmt_entry['elementUri']}" + f"The statement is already anchored in the chain\nIdentifier: {stmt_entry['element_uri']}" ) tx = api.compose_call( diff --git a/tests/test_statement.py b/tests/test_statement.py new file mode 100644 index 0000000..cde55a1 --- /dev/null +++ b/tests/test_statement.py @@ -0,0 +1,159 @@ +import unittest +from unittest.mock import patch, MagicMock, AsyncMock +from packages.utils.src.SDKErrors import Errors +import asyncio +import packages.sdk.src as Cord + +# Global Constants +DIGEST = '0x98b7e7117df3e7b12f31cc9ea97e10f83c807ffa082cb4950c0c3cae5bbb6e3e' +SPACE_URI = 'space:cord:c33wBzcYTn22DPqLbeeJ5U3DEcLSywwNzVvp7iRXP2P6WPu5W' +CREATOR_URI = 'did:cord:3uNfAtHEjabBsKVjmxGcAUF4S5cu7VMogXReho3ncPtrL4NV' +ELEMENT_URI = 'stmt:cord:s3do5hWstnvuwbuPcwuCt9bVecLWVc5foyb1LVAU5Sn97ZMLt:98b7e7117df3e7b12f31cc9ea97e10f83c807ffa082cb4950c0c3cae5bbb6e3e' +AUTHORIZATION_URI = 'auth:cord:a3azw9RwhR9xgURZKJM9xSsDDFRUqgUurvdnQXT1UzCPtZQJ8' + +STMT_ENTRY = { + 'digest': DIGEST, + 'space_uri': SPACE_URI, + 'element_uri': ELEMENT_URI, + 'schema_uri': 'schema:cord:s319FZJkZevpitKNdfvxfs7SeiXzuHyX3ncrTo5LDWxZi7qqP' +} + +AUTHOR_ACCOUNT = MagicMock() # You can configure this further as needed +SIGN_CALLBACK = MagicMock() # Mock sign callback + +class TestStatementFunctions(unittest.TestCase): + + module_path = "packages.sdk.src.Statement.statement_chain" + + @patch('packages.sdk.src.ConfigService.get') + def test_get_uri_for_statement_failure(self, mock_config): + """Test get_uri_for_statement failure scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_api.encode_scale.side_effect = Exception('Encoding error') + + with self.assertRaises(Exception) as context: + Cord.Statement.statement_chain.get_uri_for_statement(DIGEST, SPACE_URI, CREATOR_URI) + + self.assertIn('Encoding error', str(context.exception)) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.uri_to_identifier', return_value='mocked_identifier') + def test_is_statement_stored_success(self, mock_uri, mock_config): + """Test is_statement_stored success scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_api.query.return_value.value = 'mocked_value' + + result = asyncio.run(Cord.Statement.statement_chain.is_statement_stored(DIGEST, SPACE_URI)) + self.assertTrue(result) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.uri_to_identifier', return_value='mocked_identifier') + def test_is_statement_stored_failure(self, mock_uri, mock_config): + """Test is_statement_stored failure scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_api.query.return_value.value = None + + result = asyncio.run(Cord.Statement.statement_chain.is_statement_stored(DIGEST, SPACE_URI)) + self.assertFalse(result) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + @patch(f'{module_path}.is_statement_stored', return_value=False) + def test_prepare_extrinsic_to_register_success(self, mock_strored, mock_authorize_tx, mock_config): + """Test prepare_extrinsic_to_register success scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_api.compose_call.return_value = 'mocked_tx' + mock_authorize_tx.return_value = 'mocked_extrinsic' + + extrinsic = asyncio.run(Cord.Statement.statement_chain.prepare_extrinsic_to_register( + STMT_ENTRY, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + + self.assertEqual(extrinsic, 'mocked_extrinsic') + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + @patch(f'{module_path}.is_statement_stored', return_value=False) + def test_prepare_extrinsic_to_register_failure(self, mock_stored, mock_authorize_tx, mock_config): + """Test prepare_extrinsic_to_register failure scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_api.compose_call.return_value = 'mocked_tx' + mock_authorize_tx.side_effect = Exception('Authorization failed') + + with self.assertRaises(Errors.CordDispatchError) as context: + asyncio.run(Cord.Statement.statement_chain.prepare_extrinsic_to_register( + STMT_ENTRY, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + + self.assertIn('Authorization failed', str(context.exception)) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.prepare_extrinsic_to_register', new_callable=AsyncMock) + def test_dispatch_register_to_chain_success(self, mock_prepare_extrinsic, mock_config): + """Test dispatch_register_to_chain success scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_prepare_extrinsic.return_value = 'mocked_extrinsic' + mock_api.create_signed_extrinsic.return_value = 'signed_extrinsic' + + result = asyncio.run(Cord.Statement.statement_chain.dispatch_register_to_chain( + STMT_ENTRY, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + + self.assertEqual(result, STMT_ENTRY['element_uri']) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.prepare_extrinsic_to_register', new_callable=AsyncMock) + def test_dispatch_register_to_chain_failure(self, mock_prepare_extrinsic, mock_config): + """Test dispatch_register_to_chain failure scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_prepare_extrinsic.side_effect = Exception('Extrinsic preparation failed') + + with self.assertRaises(Exception) as context: + asyncio.run(Cord.Statement.statement_chain.dispatch_register_to_chain( + STMT_ENTRY, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + + self.assertIn('Extrinsic preparation failed', str(context.exception)) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.is_statement_stored', new_callable=AsyncMock) + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + def test_dispatch_update_to_chain_success(self, mock_authorize_tx, mock_is_statement_stored, mock_config): + """Test dispatch_update_to_chain success scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_is_statement_stored.return_value = False + mock_authorize_tx.return_value = 'mocked_extrinsic' + + result = asyncio.run(Cord.Statement.statement_chain.dispatch_update_to_chain( + STMT_ENTRY, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + + self.assertEqual(result, STMT_ENTRY['element_uri']) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.is_statement_stored', new_callable=AsyncMock) + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + def test_dispatch_update_to_chain_failure(self, mock_authorize_tx, mock_is_statement_stored, mock_config): + """Test dispatch_update_to_chain failure scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_is_statement_stored.return_value = False + mock_authorize_tx.side_effect = Exception('Transaction failed') + + with self.assertRaises(Errors.CordDispatchError) as context: + asyncio.run(Cord.Statement.statement_chain.dispatch_update_to_chain( + STMT_ENTRY, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + + self.assertIn('Transaction failed', str(context.exception)) + +if __name__ == '__main__': + unittest.main() From 1d4229133e4fc60488ad22916d2f472b8ee2c3ff Mon Sep 17 00:00:00 2001 From: Hardik Sharma Date: Fri, 6 Sep 2024 11:53:43 +0530 Subject: [PATCH 3/6] added major tests for statement --- tests/test_statement.py | 164 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) diff --git a/tests/test_statement.py b/tests/test_statement.py index cde55a1..f657e7a 100644 --- a/tests/test_statement.py +++ b/tests/test_statement.py @@ -10,13 +10,14 @@ CREATOR_URI = 'did:cord:3uNfAtHEjabBsKVjmxGcAUF4S5cu7VMogXReho3ncPtrL4NV' ELEMENT_URI = 'stmt:cord:s3do5hWstnvuwbuPcwuCt9bVecLWVc5foyb1LVAU5Sn97ZMLt:98b7e7117df3e7b12f31cc9ea97e10f83c807ffa082cb4950c0c3cae5bbb6e3e' AUTHORIZATION_URI = 'auth:cord:a3azw9RwhR9xgURZKJM9xSsDDFRUqgUurvdnQXT1UzCPtZQJ8' - +SCHEMA_URI = 'schema:cord:s319FZJkZevpitKNdfvxfs7SeiXzuHyX3ncrTo5LDWxZi7qqP' STMT_ENTRY = { 'digest': DIGEST, 'space_uri': SPACE_URI, 'element_uri': ELEMENT_URI, - 'schema_uri': 'schema:cord:s319FZJkZevpitKNdfvxfs7SeiXzuHyX3ncrTo5LDWxZi7qqP' + 'schema_uri': SCHEMA_URI, } +STMT_URI = 'stmt:cord:s3do5hWstnvuwbuPcwuCt9bVecLWVc5foyb1LVAU5Sn97ZMLt:98b7e7117df3e7b12f31cc9ea97e10f83c807ffa082cb4950c0c3cae5bbb6e3e' AUTHOR_ACCOUNT = MagicMock() # You can configure this further as needed SIGN_CALLBACK = MagicMock() # Mock sign callback @@ -155,5 +156,164 @@ def test_dispatch_update_to_chain_failure(self, mock_authorize_tx, mock_is_state self.assertIn('Transaction failed', str(context.exception)) + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + @patch(f'{module_path}.uri_to_identifier', new_callable=MagicMock) + @patch(f'{module_path}.uri_to_statement_id_and_digest', new_callable=MagicMock) + def test_prepare_extrinsic_to_revoke_success(self, mock_uri_to_statement_id_and_digest, + mock_uri_to_identifier, mock_authorize_tx, mock_config): + """Test prepare_extrinsic_to_revoke success scenario.""" + # Mocking the return values + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_uri_to_identifier.return_value = 'mock_authorization_id' + mock_uri_to_statement_id_and_digest.return_value = {'identifier': 'mock_statement_id'} + + # Mocking the transaction (tx) composed by `api.compose_call` + mock_api.compose_call.return_value = "mock_composed_tx" + + # Mock the authorized transaction + mock_authorize_tx.return_value = 'authorized_extrinsic' + + # Run the async function using asyncio + result = asyncio.run(Cord.Statement.statement_chain.prepare_extrinsic_to_revoke( + STMT_URI, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + + # Asserting the expected results + self.assertEqual(result, 'authorized_extrinsic') + + # Verifying that the mocks were called with the correct parameters + mock_config.assert_called_once_with('api') + mock_uri_to_identifier.assert_called_once_with(AUTHORIZATION_URI) + mock_uri_to_statement_id_and_digest.assert_called_once_with(ELEMENT_URI) + mock_api.compose_call.assert_called_once_with( + call_module='Statement', + call_function='revoke', + call_params={ + 'statement_id': 'mock_statement_id', + 'authorization': 'mock_authorization_id' + } + ) + mock_authorize_tx.assert_called_once_with( + CREATOR_URI, + 'mock_composed_tx', + SIGN_CALLBACK, + AUTHOR_ACCOUNT.ss58_address + ) + + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.prepare_extrinsic_to_revoke', new_callable=AsyncMock) + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + def test_dispatch_revoke_to_chain_success(self, mock_authorize_tx, mock_prepare_extrinsic, mock_config): + """Test dispatch_revoke_to_chain success scenario.""" + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_prepare_extrinsic.return_value = 'mocked_extrinsic' + mock_api.create_signed_extrinsic.return_value = 'signed_extrinsic' + mock_api.submit_extrinsic.return_value = None # Assuming submit_extrinsic does not return anything + + result = asyncio.run(Cord.Statement.statement_chain.dispatch_revoke_to_chain( + STMT_URI, CREATOR_URI, AUTHOR_ACCOUNT, AUTHORIZATION_URI, SIGN_CALLBACK + )) + self.assertIsNone(result) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + @patch(f'{module_path}.uri_to_identifier', new_callable=MagicMock) + @patch(f'{module_path}.uri_to_statement_id_and_digest', new_callable=MagicMock) + def test_dispatch_restore_to_chain_success(self, mock_uri_to_statement_id_and_digest, + mock_uri_to_identifier, mock_authorize_tx, mock_config): + """Test dispatch_restore_to_chain success scenario.""" + # Mock return values + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_uri_to_identifier.return_value = 'mock_authorization_id' + mock_uri_to_statement_id_and_digest.return_value = {'identifier': 'mock_statement_id'} + mock_api.compose_call.return_value = 'mock_composed_tx' + mock_authorize_tx.return_value = 'authorized_extrinsic' + mock_api.create_signed_extrinsic.return_value = 'signed_extrinsic' + + + # Inputs + statement_uri = STMT_URI + creator_uri = CREATOR_URI + authorization_uri = AUTHORIZATION_URI + + # Call the function + asyncio.run(Cord.Statement.statement_chain.dispatch_restore_to_chain( + statement_uri, creator_uri, AUTHOR_ACCOUNT, authorization_uri, SIGN_CALLBACK + )) + + # Assertions to ensure the expected flow + mock_config.assert_called_once_with('api') + mock_uri_to_identifier.assert_called_once_with(authorization_uri) + mock_uri_to_statement_id_and_digest.assert_called_once_with(statement_uri) + mock_api.compose_call.assert_called_once_with( + call_module='Statement', + call_function='restore', + call_params={ + 'statement_id': 'mock_statement_id', + 'authorization': 'mock_authorization_id' + } + ) + mock_authorize_tx.assert_called_once_with( + creator_uri, 'mock_composed_tx', SIGN_CALLBACK, AUTHOR_ACCOUNT.ss58_address + ) + mock_api.create_signed_extrinsic.assert_called_once_with('authorized_extrinsic', AUTHOR_ACCOUNT) + mock_api.submit_extrinsic.assert_called_once_with('signed_extrinsic', wait_for_inclusion=True) + + @patch('packages.sdk.src.ConfigService.get') + @patch(f'{module_path}.Did.authorize_tx', new_callable=AsyncMock) + @patch(f'{module_path}.uri_to_identifier', new_callable=MagicMock) + @patch(f'{module_path}.uri_to_statement_id_and_digest', new_callable=MagicMock) + def test_dispatch_restore_to_chain_failure(self, mock_uri_to_statement_id_and_digest, + mock_uri_to_identifier, mock_authorize_tx, mock_config): + """Test dispatch_restore_to_chain failure scenario.""" + # Mock return values + mock_api = MagicMock() + mock_config.return_value = mock_api + mock_uri_to_identifier.return_value = 'mock_authorization_id' + mock_uri_to_statement_id_and_digest.return_value = {'identifier': 'mock_statement_id'} + mock_api.compose_call.return_value = 'mock_composed_tx' + mock_authorize_tx.return_value = 'authorized_extrinsic' + mock_api.create_signed_extrinsic.return_value = 'signed_extrinsic' + + # Simulate an error during the extrinsic submission + mock_api.submit_extrinsic.side_effect = Exception('Submit extrinsic failed') + + # Inputs + statement_uri = STMT_URI + creator_uri = CREATOR_URI + authorization_uri = AUTHORIZATION_URI + + # Ensure the function raises CordDispatchError + with self.assertRaises(Errors.CordDispatchError) as context: + asyncio.run(Cord.Statement.statement_chain.dispatch_restore_to_chain( + statement_uri, creator_uri, AUTHOR_ACCOUNT, authorization_uri, SIGN_CALLBACK + )) + + self.assertIn('Error dispatching to chain', str(context.exception)) + + # Ensure the proper flow up to the failure point + mock_config.assert_called_once_with('api') + mock_uri_to_identifier.assert_called_once_with(authorization_uri) + mock_uri_to_statement_id_and_digest.assert_called_once_with(statement_uri) + mock_api.compose_call.assert_called_once_with( + call_module='Statement', + call_function='restore', + call_params={ + 'statement_id': 'mock_statement_id', + 'authorization': 'mock_authorization_id' + } + ) + mock_authorize_tx.assert_called_once_with( + creator_uri, 'mock_composed_tx', SIGN_CALLBACK, AUTHOR_ACCOUNT.ss58_address + ) + mock_api.create_signed_extrinsic.assert_called_once_with('authorized_extrinsic', AUTHOR_ACCOUNT) + mock_api.submit_extrinsic.assert_called_once_with('signed_extrinsic', wait_for_inclusion=True) + + if __name__ == '__main__': unittest.main() From 2f29e2380b3be807ff8697fbf540bf2bc5fe0918 Mon Sep 17 00:00:00 2001 From: Hardik Sharma Date: Fri, 6 Sep 2024 17:19:21 +0530 Subject: [PATCH 4/6] added tests for schema --- tests/test_schema.py | 211 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 tests/test_schema.py diff --git a/tests/test_schema.py b/tests/test_schema.py new file mode 100644 index 0000000..e77dcb9 --- /dev/null +++ b/tests/test_schema.py @@ -0,0 +1,211 @@ +import unittest +from unittest.mock import patch, MagicMock, AsyncMock +import packages.sdk.src as Cord +import asyncio +from packages.identifier.src.identifier import ( + hash_to_uri, + uri_to_identifier, + identifier_to_uri +) + +# Global test constants +TEST_SCHEMA = { + "$id": "schema:cord:s36R1RNXcAytTPd3fsVMVbhCvVQ5B6fi8r722euvBMMdUeXSH", + "$metadata": {"discoverable": True, "slug": "test-demo-schema", "version": "1.0.0"}, + "$schema": "http://cord.network/draft-01/schema#", + "additionalProperties": False, + "description": "Test Demo Schema", + "properties": { + "address": { + "properties": { + "location": { + "properties": { + "country": {"type": "string"}, + "state": {"type": "string"}, + }, + "type": "object", + }, + "pin": {"type": "integer"}, + "street": {"type": "string"}, + }, + "type": "object", + }, + "age": {"type": "integer"}, + "country": {"type": "string"}, + "id": {"type": "string"}, + "name": {"type": "string"}, + }, + "title": "Test Demo Schema v3:d2916ae8-0f07-451a-a378-c1beaa5984c1", + "type": "object", +} + +TEST_CREATOR_URI = "did:cord:3yrn8NahRARGPodzjQQobkhujkYZbzsWttk5QoSEL7qLMfCu" +TEST_SPACE_URI = "space:cord:c37c6MvhrZLXs9AfnsLYxApfjtc1y9s3fACvrD95NYoWD2UE8" +TEST_AUTHOR_ACCOUNT = MagicMock() +TEST_AUTHORIZATION_URI = "auth:cord:a3fraTJoz9yDKpvMyAJJ971F3p7Ts1bfBz2WyMojvYqQNjf6S" +TEST_STATEMENT_URI = "stmt:cord:s3hHaTwx9G4LXprYLSZVanFWikyyiF4w9NVpoQJZw6AYiMLzw:0981d00f89ae59be7a3d97b1c0b35fdbabbe55211400a9a2c029aa00701048eb" +TEST_SCHEMA_URI = "schema:cord:s36R1RNXcAytTPd3fsVMVbhCvVQ5B6fi8r722euvBMMdUeXSH" +TEST_SIGNATURE_CALLBACK = MagicMock() + + +class TestCordSchemaFunctions(unittest.TestCase): + module_path = "packages.sdk.src.Schema.schema_chain" + + @patch(f'{module_path}.encode_cbor_schema') + @patch(f'{module_path}.Utils.crypto_utils.hash_str') + @patch(f'{module_path}.Utils.crypto_utils.blake2_as_hex') + @patch(f'{module_path}.hash_to_uri') + @patch(f"{module_path}.ConfigService.get") + def test_get_uri_for_schema(self, mock_get, mock_hash_to_uri, mock_blake2_as_hex, mock_hash_str, mock_encode_cbor_schema): + # Mock API and other utility functions + mock_api = MagicMock() + mock_get.return_value = mock_api + mock_encode_cbor_schema.return_value = "encoded_cbor_schema" + mock_hash_str.return_value = "test_digest" + mock_blake2_as_hex.return_value = "test_blake2_hash" + mock_hash_to_uri.return_value = TEST_SCHEMA_URI + + # Mock encoding functions + mock_api.encode_scale.side_effect = [ + MagicMock(get_remaining_bytes=MagicMock(return_value=b'serialized_schema_bytes')), + MagicMock(get_remaining_bytes=MagicMock(return_value=b'space_bytes')), + MagicMock(get_remaining_bytes=MagicMock(return_value=b'creator_bytes')) + ] + + # Call the function + result = Cord.Schema.schema_chain.get_uri_for_schema(TEST_SCHEMA, TEST_CREATOR_URI, TEST_SPACE_URI) + + # Assertions + self.assertEqual(result['uri'], TEST_SCHEMA_URI) + self.assertEqual(result['digest'], "test_digest") + + # Ensure encoding and hashing was done correctly + mock_encode_cbor_schema.assert_called_once_with(TEST_SCHEMA) + mock_hash_str.assert_called_once_with(b"encoded_cbor_schema") + mock_api.encode_scale.assert_any_call(type_string="Bytes", value="encoded_cbor_schema") + mock_api.encode_scale.assert_any_call(type_string="Bytes", value=uri_to_identifier(TEST_SPACE_URI)) + mock_api.encode_scale.assert_any_call(type_string="AccountId", value=Cord.Did.to_chain(TEST_CREATOR_URI)) + mock_blake2_as_hex.assert_called_once_with(b'serialized_schema_bytes' + b'space_bytes' + b'creator_bytes') + + + @patch(f"{module_path}.ConfigService.get") + @patch(f"{module_path}.uri_to_identifier") + def test_is_schema_stored(self, mock_uri_to_identifier, mock_get): + mock_api = MagicMock() + mock_get.return_value = mock_api + + mock_api.query.return_value.value = None + schema_exists = asyncio.run( + Cord.Schema.schema_chain.is_schema_stored(TEST_SCHEMA) + ) + self.assertFalse(schema_exists) + + mock_api.query.return_value.value = True + schema_exists = asyncio.run( + Cord.Schema.schema_chain.is_schema_stored(TEST_SCHEMA) + ) + self.assertTrue(schema_exists) + + @patch(f"{module_path}.ConfigService.get") + @patch(f"{module_path}.is_schema_stored", new_callable=AsyncMock) + @patch(f"{module_path}.Did.authorize_tx", new_callable=AsyncMock) + def test_dispatch_to_chain_success( + self, mock_authorize_tx, mock_is_schema_stored, mock_get + ): + # Success test for schema dispatching to chain + mock_api = MagicMock() + mock_get.return_value = mock_api + mock_is_schema_stored.return_value = False # Schema is not already stored + mock_authorize_tx.return_value = "signed_tx" + + # Mock API methods + mock_api.create_signed_extrinsic.return_value = "signed_extrinsic" + mock_api.submit_extrinsic.return_value = None + + # Run the async function + result = asyncio.run( + Cord.Schema.schema_chain.dispatch_to_chain( + TEST_SCHEMA, + TEST_CREATOR_URI, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGNATURE_CALLBACK, + ) + ) + + # Assert that the schema ID is returned + self.assertEqual(result, TEST_SCHEMA["$id"]) + + # Assert the proper call sequence + mock_is_schema_stored.assert_awaited_once_with(TEST_SCHEMA) + mock_authorize_tx.assert_awaited_once_with( + TEST_CREATOR_URI, + mock_api.compose_call.return_value, + TEST_SIGNATURE_CALLBACK, + TEST_AUTHOR_ACCOUNT.ss58_address, + ) + mock_api.create_signed_extrinsic.assert_called_once_with( + call="signed_tx", keypair=TEST_AUTHOR_ACCOUNT + ) + mock_api.submit_extrinsic.assert_called_once_with( + "signed_extrinsic", wait_for_inclusion=True + ) + + @patch(f"{module_path}.ConfigService.get") + @patch(f"{module_path}.is_schema_stored", new_callable=AsyncMock) + @patch(f"{module_path}.Did.authorize_tx", new_callable=AsyncMock) + def test_dispatch_to_chain_schema_already_exists( + self, mock_authorize_tx, mock_is_schema_stored, mock_get + ): + # Test when schema already exists in the chain + mock_api = MagicMock() + mock_get.return_value = mock_api + mock_is_schema_stored.return_value = True # Schema is already stored + + result = asyncio.run( + Cord.Schema.schema_chain.dispatch_to_chain( + TEST_SCHEMA, + TEST_CREATOR_URI, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGNATURE_CALLBACK, + ) + ) + + # Assert that the schema ID is returned and no transaction was submitted + self.assertEqual(result, TEST_SCHEMA["$id"]) + mock_is_schema_stored.assert_awaited_once_with(TEST_SCHEMA) + mock_authorize_tx.assert_not_called() + mock_api.create_signed_extrinsic.assert_not_called() + mock_api.submit_extrinsic.assert_not_called() + + @patch(f"{module_path}.ConfigService.get") + @patch(f"{module_path}.from_chain") + def test_fetch_from_chain(self, mock_from_chain, mock_get): + mock_api = MagicMock() + mock_get.return_value = mock_api + + mock_from_chain.return_value = {"schema": TEST_SCHEMA} + mock_api.query.return_value = MagicMock(value="some_value") + + result = asyncio.run( + Cord.Schema.schema_chain.fetch_from_chain(TEST_SCHEMA_URI) + ) + + self.assertIn("schema", result) + self.assertEqual(result["schema"], TEST_SCHEMA) + + @patch(f"{module_path}.cbor2.loads") + def test_schema_input_from_chain(self, mock_loads): + mock_loads.return_value = TEST_SCHEMA + input_data = "base64_encoded_input==" + + result = Cord.Schema.schema_chain.schema_input_from_chain( + input_data, TEST_SCHEMA_URI + ) + self.assertIn("$id", result) + self.assertEqual(result["$id"], TEST_SCHEMA_URI) + + +if __name__ == "__main__": + unittest.main() From 0b46e0198ce13c77461b16e9dff55cc140e5fe28 Mon Sep 17 00:00:00 2001 From: Hardik Sharma Date: Fri, 6 Sep 2024 23:47:00 +0530 Subject: [PATCH 5/6] tests for asset module --- tests/test_asset.py | 134 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 tests/test_asset.py diff --git a/tests/test_asset.py b/tests/test_asset.py new file mode 100644 index 0000000..e86fac2 --- /dev/null +++ b/tests/test_asset.py @@ -0,0 +1,134 @@ +import unittest +from unittest.mock import MagicMock, patch +import asyncio +from packages.utils.src.SDKErrors import Errors +from packages.utils.src.prefix import ASSET_PREFIX +import packages.sdk.src as Cord + +# Global test constants +TEST_ASSET_ENTRY = { + "creator": "did:cord:creator", + "issuer": "did:cord:issuer", + "owner": "did:cord:owner", + "entry": {"asset_id": "123", "asset_instance_id": "456"}, + "digest": "dummy_digest", + "uri": "asset:cord:123:456" +} +TEST_AUTHOR_ACCOUNT = MagicMock() +TEST_AUTHORIZATION_URI = "auth:cord:a3fraTJoz9yDKpvMyAJJ971F3p7Ts1bfBz2WyMojvYqQNjf6S" +TEST_SIGNATURE_CALLBACK = MagicMock() + +class TestCordAssetFunctions(unittest.TestCase): + + @patch('packages.sdk.src.ConfigService.get') + @patch('packages.sdk.src.Did.authorize_tx') + def test_dispatch_create_to_chain_success(self, mock_authorize_tx, mock_get): + mock_api = MagicMock() + mock_get.return_value = mock_api + mock_authorize_tx.return_value = "signed_tx" + + mock_api.compose_call.return_value = "tx_call" + mock_api.create_signed_extrinsic.return_value = "signed_extrinsic" + mock_api.submit_extrinsic.return_value = None + + result = asyncio.run( + Cord.Asset.asset_chain.dispatch_create_to_chain( + TEST_ASSET_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGNATURE_CALLBACK + ) + ) + + self.assertEqual(result, TEST_ASSET_ENTRY["uri"]) + + @patch('packages.sdk.src.ConfigService.get') + @patch('packages.sdk.src.Did.authorize_tx') + def test_dispatch_create_to_chain_failure(self, mock_authorize_tx, mock_get): + mock_get.return_value = MagicMock() + mock_authorize_tx.side_effect = Exception("Authorization failed") + + with self.assertRaises(Errors.CordDispatchError): + asyncio.run( + Cord.Asset.asset_chain.dispatch_create_to_chain( + TEST_ASSET_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGNATURE_CALLBACK + ) + ) + + @patch('packages.sdk.src.ConfigService.get') + @patch('packages.sdk.src.Did.authorize_tx') + def test_dispatch_issue_to_chain_success(self, mock_authorize_tx, mock_get): + mock_api = MagicMock() + mock_get.return_value = mock_api + mock_authorize_tx.return_value = "signed_tx" + + mock_api.create_signed_extrinsic.return_value = "signed_extrinsic" + mock_api.submit_extrinsic.return_value = None + + result = asyncio.run( + Cord.Asset.asset_chain.dispatch_issue_to_chain( + TEST_ASSET_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGNATURE_CALLBACK + ) + ) + + self.assertEqual(result, TEST_ASSET_ENTRY["uri"]) + + @patch('packages.sdk.src.ConfigService.get') + @patch('packages.sdk.src.Did.authorize_tx') + def test_dispatch_issue_to_chain_failure(self, mock_authorize_tx, mock_get): + mock_get.return_value = MagicMock() + mock_authorize_tx.side_effect = Exception("Authorization failed") + + with self.assertRaises(Errors.CordDispatchError): + asyncio.run( + Cord.Asset.asset_chain.dispatch_issue_to_chain( + TEST_ASSET_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGNATURE_CALLBACK + ) + ) + + @patch('packages.sdk.src.ConfigService.get') + @patch('packages.sdk.src.Did.authorize_tx') + def test_dispatch_transfer_to_chain_success(self, mock_authorize_tx, mock_get): + mock_api = MagicMock() + mock_get.return_value = mock_api + mock_authorize_tx.return_value = "signed_tx" + + mock_api.create_signed_extrinsic.return_value = "signed_extrinsic" + mock_api.submit_extrinsic.return_value = None + + result = asyncio.run( + Cord.Asset.asset_chain.dispatch_transfer_to_chain( + TEST_ASSET_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_SIGNATURE_CALLBACK + ) + ) + + self.assertEqual(result, f"{ASSET_PREFIX}{TEST_ASSET_ENTRY['entry']['asset_id']}:{TEST_ASSET_ENTRY['entry']['asset_instance_id']}") + + @patch('packages.sdk.src.ConfigService.get') + @patch('packages.sdk.src.Did.authorize_tx') + def test_dispatch_transfer_to_chain_failure(self, mock_authorize_tx, mock_get): + mock_get.return_value = MagicMock() + mock_authorize_tx.side_effect = Exception("Authorization failed") + + with self.assertRaises(Errors.CordDispatchError): + asyncio.run( + Cord.Asset.asset_chain.dispatch_transfer_to_chain( + TEST_ASSET_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_SIGNATURE_CALLBACK + ) + ) + +if __name__ == '__main__': + unittest.main() From 07cc2eb9da9b44a83946a0ea66a411e0dcabbf86 Mon Sep 17 00:00:00 2001 From: Hardik Sharma Date: Tue, 10 Sep 2024 16:26:28 +0530 Subject: [PATCH 6/6] added tests for score module --- tests/tests_network_score.py | 213 +++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 tests/tests_network_score.py diff --git a/tests/tests_network_score.py b/tests/tests_network_score.py new file mode 100644 index 0000000..2be514d --- /dev/null +++ b/tests/tests_network_score.py @@ -0,0 +1,213 @@ +import unittest +from unittest.mock import AsyncMock, patch, MagicMock +from packages.utils.src.SDKErrors import Errors +import packages.sdk.src as Cord +import asyncio + +# Mock test constants +TEST_RATING_URI = "rating:cord:r35hzaE3KFVDuZB24bEkeWu38rXK5SavZNe8xomJjp7ZCsvFf" +TEST_AUTHORIZATION_URI = "auth:cord:a3fraTJoz9yDKpvMyAJJ971F3p7Ts1bfBz2WyMojvYqQNjf6S" +TEST_AUTHOR_ACCOUNT = MagicMock(ss58_address="5F3sa2TJ...") +TEST_SIGN_CALLBACK = MagicMock() +TEST_RATING_ENTRY = { + "entry": { + "reference_id": "rating:cord:r37i2uLYsxfj7vkAFaFzhMkT16ns11EELkWY7zJ6ErF8z5Ewf", + "entry_digest": "some_digest", + }, + "entry_digest": "0x5015dd7c7baea48731b083baabd799f9d479c96ab0aa65a199cf92e2cca5eeb3", + "message_id": "msg123", + "entry_uri": TEST_RATING_URI, + "author_uri": "did:cord:author:0001", +} +ENCODED_RATING = { + "entry": { + "entity_id": "entity123", + "provider_id": "provider123", + "rating_type": "overall", + "count_of_txn": 10, + "total_encoded_rating": 850, + + }, + "digest": "digest123", + "message_id": "msg123", + "space": "space123", + "reference_id": "rating:cord:r37i2uLYsxfj7vkAFaFzhMkT16ns11EELkWY7zJ6ErF8z5Ewf", + "creator_id": "creator123", + "entry_type": "type123", + "created_at": 1694074734000, +} + + +class TestRatingModule(unittest.TestCase): + + @patch("packages.sdk.src.ConfigService.get") + @patch("packages.identifier.src.identifier.uri_to_identifier") + def test_is_rating_stored_true(self, mock_uri_to_identifier, mock_config_service): + """ + Test is_rating_stored function when rating is stored. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = ENCODED_RATING + mock_config_service.return_value = mock_api + mock_uri_to_identifier.return_value = "rating_identifier" + + result = asyncio.run(Cord.Score.scoring_chain.is_rating_stored(TEST_RATING_URI)) + self.assertTrue(result) + mock_api.query.assert_called_with( + "NetworkScore", "RatingEntries", ["r35hzaE3KFVDuZB24bEkeWu38rXK5SavZNe8xomJjp7ZCsvFf"] + ) + + @patch("packages.sdk.src.ConfigService.get") + @patch("packages.identifier.src.identifier.uri_to_identifier") + def test_is_rating_stored_false(self, mock_uri_to_identifier, mock_config_service): + """ + Test is_rating_stored function when rating is not stored. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = None + mock_config_service.return_value = mock_api + mock_uri_to_identifier.return_value = "rating_identifier" + + result = asyncio.run(Cord.Score.scoring_chain.is_rating_stored(TEST_RATING_URI)) + self.assertFalse(result) + + @patch("packages.sdk.src.ConfigService.get") + def test_dispatch_rating_to_chain_success(self, mock_config_service): + """ + Test dispatch_rating_to_chain function for successful dispatch. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = None # Rating does not exist + mock_api.compose_call.return_value = "mock_call" + mock_api.create_signed_extrinsic.return_value = "mock_extrinsic" + mock_config_service.return_value = mock_api + + with patch( + "packages.sdk.src.Did.authorize_tx", + new=AsyncMock(return_value="authorized_tx"), + ): + result = asyncio.run( + Cord.Score.scoring_chain.dispatch_rating_to_chain( + TEST_RATING_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGN_CALLBACK, + ) + ) + self.assertEqual(result, TEST_RATING_ENTRY["entry_uri"]) + mock_api.compose_call.assert_called_once() + mock_api.submit_extrinsic.assert_called_once_with( + "mock_extrinsic", wait_for_inclusion=True + ) + + @patch("packages.sdk.src.ConfigService.get") + def test_dispatch_rating_to_chain_already_exists(self, mock_config_service): + """ + Test dispatch_rating_to_chain function when rating already exists. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = ENCODED_RATING # Rating exists + mock_config_service.return_value = mock_api + + result = asyncio.run( + Cord.Score.scoring_chain.dispatch_rating_to_chain( + TEST_RATING_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGN_CALLBACK, + ) + ) + self.assertEqual(result, TEST_RATING_ENTRY["entry_uri"]) + mock_api.compose_call.assert_not_called() # Should not attempt to create a transaction + + @patch("packages.sdk.src.ConfigService.get") + def test_dispatch_revoke_rating_to_chain_success(self, mock_config_service): + """ + Test dispatch_revoke_rating_to_chain for successful revocation. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = ENCODED_RATING # Rating exists + mock_api.compose_call.return_value = "mock_call" + mock_api.create_signed_extrinsic.return_value = "mock_extrinsic" + mock_config_service.return_value = mock_api + + with patch( + "packages.sdk.src.Did.authorize_tx", + new=AsyncMock(return_value="authorized_tx"), + ): + result = asyncio.run(Cord.Score.scoring_chain.dispatch_revoke_rating_to_chain( + TEST_RATING_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGN_CALLBACK, + )) + self.assertEqual(result, TEST_RATING_ENTRY["entry_uri"]) + mock_api.submit_extrinsic.assert_called_once_with( + "mock_extrinsic", wait_for_inclusion=True + ) + + @patch("packages.sdk.src.ConfigService.get") + def test_dispatch_revoke_rating_to_chain_not_found(self, mock_config_service): + """ + Test dispatch_revoke_rating_to_chain when rating entry is not found. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = None # Rating does not exist + mock_config_service.return_value = mock_api + + with self.assertRaises(Errors.CordDispatchError): + asyncio.run(Cord.Score.scoring_chain.dispatch_revoke_rating_to_chain( + TEST_RATING_ENTRY, + TEST_AUTHOR_ACCOUNT, + TEST_AUTHORIZATION_URI, + TEST_SIGN_CALLBACK, + )) + + @patch("packages.sdk.src.ConfigService.get") + def test_fetch_rating_details_from_chain_not_found(self, mock_config_service): + """ + Test fetch_rating_details_from_chain when the rating entry is not found. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = None + mock_config_service.return_value = mock_api + + result = asyncio.run(Cord.Score.scoring_chain.fetch_rating_details_from_chain(TEST_RATING_URI, "GMT")) + self.assertIsNone(result) + + @patch("packages.sdk.src.ConfigService.get") + def test_fetch_entity_aggregate_score_from_chain_found( + self, mock_config_service + ): + """ + Test fetch_entity_aggregate_score_from_chain when data is found. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = { + "count_of_txn": 100, + "total_encoded_rating": 950, + } + mock_config_service.return_value = mock_api + + result = asyncio.run(Cord.Score.scoring_chain.fetch_entity_aggregate_score_from_chain("entity123", "overall")) + self.assertIsNotNone(result) + self.assertEqual(result[0]["count_of_txn"], 100) + self.assertEqual(result[0]["total_rating"], 95.0) + + @patch("packages.sdk.src.ConfigService.get") + def test_fetch_entity_aggregate_score_from_chain_not_found( + self, mock_config_service + ): + """ + Test fetch_entity_aggregate_score_from_chain when no data is found. + """ + mock_api = MagicMock() + mock_api.query.return_value.value = None + mock_config_service.return_value = mock_api + + result = asyncio.run(Cord.Score.scoring_chain.fetch_entity_aggregate_score_from_chain("entity123", "overall")) + self.assertIsNone(result) + + +if __name__ == "__main__": + unittest.main()