diff --git a/src/cutecoin/core/txhistory.py b/src/cutecoin/core/txhistory.py index 24d993d083732f5ab41b451d584354360da01d9a..592d90b5faa9df35489be894fd53c6fe970318aa 100644 --- a/src/cutecoin/core/txhistory.py +++ b/src/cutecoin/core/txhistory.py @@ -177,8 +177,11 @@ class TxHistory(): parsed_block = min(set(blocks)) logging.debug("Refresh from : {0} to {1}".format(self.latest_block, current_block['number'])) dividends_data = qtbma.ud.History.null_value - while dividends_data == qtbma.ud.History.null_value: - dividends_data = yield from community.bma_access.future_request(qtbma.ud.History, + for i in range(0, 6): + if dividends_data == qtbma.ud.History.null_value: + if i == 5: + return + dividends_data = yield from community.bma_access.future_request(qtbma.ud.History, req_args={'pubkey': self.wallet.pubkey}) dividends = dividends_data['history']['history'] @@ -193,8 +196,12 @@ class TxHistory(): if t.state == Transfer.AWAITING] while parsed_block < current_block['number']: tx_history = qtbma.tx.history.Blocks.null_value - while tx_history == qtbma.tx.history.Blocks.null_value: - tx_history = yield from community.bma_access.future_request(qtbma.tx.history.Blocks, + for i in range(0, 6): + if tx_history == qtbma.tx.history.Blocks.null_value: + if i == 5: + return + + tx_history = yield from community.bma_access.future_request(qtbma.tx.history.Blocks, req_args={'pubkey': self.wallet.pubkey, 'from_':str(parsed_block), 'to_': str(parsed_block + 99)}) diff --git a/src/cutecoin/tests/core/__init__.py b/src/cutecoin/tests/core/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd --- /dev/null +++ b/src/cutecoin/tests/core/__init__.py @@ -0,0 +1 @@ +__author__ = 'inso' diff --git a/src/cutecoin/tests/core/txhistory/__init__.py b/src/cutecoin/tests/core/txhistory/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd --- /dev/null +++ b/src/cutecoin/tests/core/txhistory/__init__.py @@ -0,0 +1 @@ +__author__ = 'inso' diff --git a/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py b/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py new file mode 100644 index 0000000000000000000000000000000000000000..d7522167d83ca6f83ee8ea98ff473299d5ecaf46 --- /dev/null +++ b/src/cutecoin/tests/core/txhistory/test_txhistory_loading.py @@ -0,0 +1,77 @@ +import sys +import unittest +import asyncio +import quamash +import time +import logging +from ucoinpy.documents.peer import BMAEndpoint as PyBMAEndpoint +from PyQt5.QtCore import QLocale, Qt +from PyQt5.QtTest import QTest +from cutecoin.tests.mocks.bma import nice_blockchain +from cutecoin.tests.mocks.access_manager import MockNetworkAccessManager +from cutecoin.core.registry.identities import IdentitiesRegistry +from cutecoin.core.app import Application +from cutecoin.core import Account, Community, Wallet +from cutecoin.core.net import Network, Node +from cutecoin.core.net.endpoint import BMAEndpoint +from cutecoin.core.net.api.bma.access import BmaAccess +from cutecoin.tests import get_application +from cutecoin.core.net.api import bma as qtbma + + +class TestTxHistory(unittest.TestCase): + def setUp(self): + self.qapplication = get_application() + self.network_manager = MockNetworkAccessManager() + QLocale.setDefault(QLocale("en_GB")) + self.lp = quamash.QEventLoop(self.qapplication) + asyncio.set_event_loop(self.lp) + self.identities_registry = IdentitiesRegistry({}) + + self.application = Application(self.qapplication, self.lp, self.network_manager, self.identities_registry) + self.application.preferences['notifications'] = False + + self.endpoint = BMAEndpoint(PyBMAEndpoint("", "127.0.0.1", "", 50000)) + self.node = Node(self.network_manager, "test_currency", [self.endpoint], + "", "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", + nice_blockchain.bma_blockchain_current, Node.ONLINE, + time.time(), {}, "ucoin", "0.14.0", 0) + self.network = Network.create(self.network_manager, self.node) + self.bma_access = BmaAccess.create(self.network) + self.community = Community("test_currency", self.network, self.bma_access) + + self.wallet = Wallet(0, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "Wallet 1", self.identities_registry) + self.wallet.init_cache(self.application, self.community) + + # Salt/password : "testcutecoin/testcutecoin" + # Pubkey : 7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ + self.account = Account("testcutecoin", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "john", [self.community], [self.wallet], [], self.identities_registry) + + def tearDown(self): + try: + self.lp.close() + finally: + asyncio.set_event_loop(None) + + def test_txhistory_reload(self): + mock = nice_blockchain.get_mock() + time.sleep(2) + logging.debug(mock.pretend_url) + self.network_manager.set_mock_path(mock.pretend_url) + received_list = [] + self.lp.run_until_complete(self.wallet.caches[self.community.currency]. + refresh(self.community, received_list)) + self.assertEquals(len(received_list), 2) + received_value = sum([r.metadata['amount'] for r in received_list]) + self.assertEqual(received_value, 60) + self.assertEqual(len(self.wallet.dividends(self.community)), 2) + dividends_value = sum([ud['amount'] for ud in self.wallet.dividends(self.community)]) + self.assertEqual(dividends_value, 15) + mock.delete_mock() + +if __name__ == '__main__': + logging.basicConfig(stream=sys.stderr) + logging.getLogger().setLevel(logging.DEBUG) + unittest.main() diff --git a/src/cutecoin/tests/gui/__init__.py b/src/cutecoin/tests/gui/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..39ab2a0b56350baad834cb7fb0cfecb8223e1fcd --- /dev/null +++ b/src/cutecoin/tests/gui/__init__.py @@ -0,0 +1 @@ +__author__ = 'inso' diff --git a/src/cutecoin/tests/certification/__init__.py b/src/cutecoin/tests/gui/certification/__init__.py similarity index 100% rename from src/cutecoin/tests/certification/__init__.py rename to src/cutecoin/tests/gui/certification/__init__.py diff --git a/src/cutecoin/tests/certification/test_certification.py b/src/cutecoin/tests/gui/certification/test_certification.py similarity index 100% rename from src/cutecoin/tests/certification/test_certification.py rename to src/cutecoin/tests/gui/certification/test_certification.py diff --git a/src/cutecoin/tests/identities_tab/__init__.py b/src/cutecoin/tests/gui/identities_tab/__init__.py similarity index 100% rename from src/cutecoin/tests/identities_tab/__init__.py rename to src/cutecoin/tests/gui/identities_tab/__init__.py diff --git a/src/cutecoin/tests/identities_tab/test_identities_table.py b/src/cutecoin/tests/gui/identities_tab/test_identities_table.py similarity index 100% rename from src/cutecoin/tests/identities_tab/test_identities_table.py rename to src/cutecoin/tests/gui/identities_tab/test_identities_table.py diff --git a/src/cutecoin/tests/main_window/__init__.py b/src/cutecoin/tests/gui/main_window/__init__.py similarity index 100% rename from src/cutecoin/tests/main_window/__init__.py rename to src/cutecoin/tests/gui/main_window/__init__.py diff --git a/src/cutecoin/tests/main_window/test_main_window_dialogs.py b/src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py similarity index 100% rename from src/cutecoin/tests/main_window/test_main_window_dialogs.py rename to src/cutecoin/tests/gui/main_window/test_main_window_dialogs.py diff --git a/src/cutecoin/tests/main_window/test_main_window_menus.py b/src/cutecoin/tests/gui/main_window/test_main_window_menus.py similarity index 100% rename from src/cutecoin/tests/main_window/test_main_window_menus.py rename to src/cutecoin/tests/gui/main_window/test_main_window_menus.py diff --git a/src/cutecoin/tests/process_cfg_account/__init__.py b/src/cutecoin/tests/gui/process_cfg_account/__init__.py similarity index 100% rename from src/cutecoin/tests/process_cfg_account/__init__.py rename to src/cutecoin/tests/gui/process_cfg_account/__init__.py diff --git a/src/cutecoin/tests/process_cfg_account/test_add_account.py b/src/cutecoin/tests/gui/process_cfg_account/test_add_account.py similarity index 100% rename from src/cutecoin/tests/process_cfg_account/test_add_account.py rename to src/cutecoin/tests/gui/process_cfg_account/test_add_account.py diff --git a/src/cutecoin/tests/process_cfg_community/__init__.py b/src/cutecoin/tests/gui/process_cfg_community/__init__.py similarity index 100% rename from src/cutecoin/tests/process_cfg_community/__init__.py rename to src/cutecoin/tests/gui/process_cfg_community/__init__.py diff --git a/src/cutecoin/tests/process_cfg_community/test_add_community.py b/src/cutecoin/tests/gui/process_cfg_community/test_add_community.py similarity index 100% rename from src/cutecoin/tests/process_cfg_community/test_add_community.py rename to src/cutecoin/tests/gui/process_cfg_community/test_add_community.py diff --git a/src/cutecoin/tests/transfer/__init__.py b/src/cutecoin/tests/gui/transfer/__init__.py similarity index 100% rename from src/cutecoin/tests/transfer/__init__.py rename to src/cutecoin/tests/gui/transfer/__init__.py diff --git a/src/cutecoin/tests/transfer/test_transfer.py b/src/cutecoin/tests/gui/transfer/test_transfer.py similarity index 100% rename from src/cutecoin/tests/transfer/test_transfer.py rename to src/cutecoin/tests/gui/transfer/test_transfer.py diff --git a/src/cutecoin/tests/mocks/bma/nice_blockchain.py b/src/cutecoin/tests/mocks/bma/nice_blockchain.py index c692dec887016d8ee029c06f66d1923afcf65575..76a77edfcc009182df832f6fb04bfc32685b132e 100644 --- a/src/cutecoin/tests/mocks/bma/nice_blockchain.py +++ b/src/cutecoin/tests/mocks/bma/nice_blockchain.py @@ -1,7 +1,8 @@ +import json from pretenders.client.http import HTTPMock from pretenders.common.constants import FOREVER -bma_peering = b"""{ +bma_peering = { "version": 1, "currency": "test_currency", "endpoints": [ @@ -10,12 +11,12 @@ bma_peering = b"""{ "status": "UP", "block": "30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3", "signature": "cXuqZuDfyHvxYAEUkPH1TQ1M+8YNDpj8kiHGYi3LIaMqEdVqwVc4yQYGivjxFMYyngRfxXkyvqBKZA6rKOulCA==", - "raw": "Version: 1\\nType: Peer\\nCurrency: meta_brouzouf\\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\\nEndpoints:\\nBASIC_MERKLED_API localhost 127.0.0.1 50000\\n", + "raw": "Version: 1\nType: Peer\nCurrency: meta_brouzouf\nPublicKey: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nBlock: 30152-00003E7F9234E7542FCF669B69B0F84FF79CCCD3\nEndpoints:\nBASIC_MERKLED_API localhost 127.0.0.1 50000\n", "pubkey": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk" -}""" +} -bma_lookup_john = b"""{ - "partial": false, +bma_lookup_john = { + "partial": False, "results": [ { "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", @@ -32,10 +33,10 @@ bma_lookup_john = b"""{ "signed": [] } ] -}""" +} -bma_lookup_doe = b"""{ - "partial": false, +bma_lookup_doe = { + "partial": False, "results": [ { "pubkey": "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn", @@ -52,25 +53,25 @@ bma_lookup_doe = b"""{ "signed": [] } ] -}""" +} -bma_certifiers_of_john = b"""{ +bma_certifiers_of_john = { "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "uid": "john", - "isMember": true, + "isMember": True, "certifications": [ ] -}""" +} -bma_certified_by_john = b"""{ +bma_certified_by_john = { "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "uid": "john", - "isMember": true, + "isMember": True, "certifications": [ ] -}""" +} -bma_parameters = b"""{ +bma_parameters = { "currency": "test_currency", "c": 0.1, "dt": 86400, @@ -86,12 +87,12 @@ bma_parameters = b"""{ "dtDiffEval": 20, "blocksRot": 144, "percentRot": 0.67 -}""" +} -bma_blockchain_current = b"""{ +bma_blockchain_current = { "version": 1, "nonce": 6909, - "number": 3, + "number": 15, "powMin": 4, "time": 1441618206, "medianTime": 1441614759, @@ -104,7 +105,7 @@ bma_blockchain_current = b"""{ "parameters": "", "previousHash": "00003BDA844D77EEE7CF32A6C3C87F2ACBFCFCBB", "previousIssuer": "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk", - "dividend": null, + "dividend": None, "membersChanges": [ ], "identities": [ ], "joiners": [ ], @@ -114,54 +115,220 @@ bma_blockchain_current = b"""{ "certifications": [ ], "transactions": [ ], "raw": "Version: 1\nType: Block\nCurrency: meta_brouzouf\nNonce: 6909\nNumber: 30898\nPoWMin: 4\nTime: 1441618206\nMedianTime: 1441614759\nIssuer: EPs9qX7HmCDy6ptUoMLpTzbh9toHu4au488pBTU9DN6y\nPreviousHash: 00003BDA844D77EEE7CF32A6C3C87F2ACBFCFCBB\nPreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nMembersCount: 20\nIdentities:\nJoiners:\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n" -}""" +} + +# Sent 6, received 20 + 30 +bma_txhistory_john = { + "currency": "test_currency", + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "history": + { + "sent": + [ + { + "version": 1, + "issuers": + [ + "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ" + ], + "inputs": + [ + "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8" + ], + "outputs": + [ + "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:2", + "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:6" + ], + "comment": "", + "signatures": + [ + "1Mn8q3K7N+R4GZEpAUm+XSyty1Uu+BuOy5t7BIRqgZcKqiaxfhAUfDBOcuk2i4TJy1oA5Rntby8hDN+cUCpvDg==" + ], + "hash": "5FB3CB80A982E2BDFBB3EA94673A74763F58CB2A", + "block_number": 2, + "time": 1421932545 + }, +], +"received": + [ + { + "version": 1, + "issuers": + [ + "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn" + ], + "inputs": + [ + "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8" + ], + "outputs": + [ + "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:2", + "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:20" + ], + "comment": "", + "signatures": + [ + "1Mn8q3K7N+R4GZEpAUm+XSyty1Uu+BuOy5t7BIRqgZcKqiaxfhAUfDBOcuk2i4TJy1oA5Rntby8hDN+cUCpvDg==" + ], + "hash": "5FB3CB80A982E2BDFBB3EA94673A74763F58CB2A", + "block_number": 2, + "time": 1421932545 + }, + { + "version": 1, + "issuers": + [ + "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn" + ], + "inputs": + [ + "0:D:1:000A8362AE0C1B8045569CE07735DE4C18E81586:8" + ], + "outputs": + [ + "FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn:5", + "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ:40" + ], + "comment": "", + "signatures": + [ + "1Mn8q3K7N+R4GZEpAUm+XSyty1Uu+BuOy5t7BIRqgZcKqiaxfhAUfDBOcuk2i4TJy1oA5Rntby8hDN+cUCpvDg==" + ], + "hash": "5FB3CB80A982E2BDFBB3EA94673A74763F58CB2A", + "block_number": 12, + "time": 1421932454 + } + ], + "sending": [ ], + "receiving": [ ] + } +} + +bma_udhistory_john = { + "currency": "test_currency", + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "history": +{ + "history": + [ + { + "block_number": 2, + "consumed": False, + "time": 1435749971, + "amount": 5 + }, + { + + "block_number": 10, + "consumed": False, + "time": 1435836032, + "amount": 10 + + } + ] +}} + +bma_txsources_john = { + "currency": "test_currency", + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "sources": +[ +{ + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "type": "D", + "number": 2, + "fingerprint": "4A317E3D676E9800E1E92AA2A7255BCEEFF31185", + "amount": 7 +}, + { + "pubkey": "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", + "type": "D", + "number": 4, + "fingerprint": "4A317E3D676E9800E1E92AA2A7255BCEEFF31185", + "amount": 9 +} +]} + def get_mock(): mock = HTTPMock('127.0.0.1', 50000) mock.when('GET /network/peering')\ - .reply(body=bma_peering, + .reply(body=bytes(json.dumps(bma_peering), "utf-8"), times=FOREVER, headers={'Content-Type': 'application/json'}) mock.when('GET /blockchain/parameters')\ - .reply(body=bma_parameters, + .reply(body=bytes(json.dumps(bma_parameters), "utf-8"), + status=200, + times=FOREVER, + headers={'Content-Type': 'application/json'}) + + mock.when('GET /blockchain/current')\ + .reply(body=bytes(json.dumps(bma_blockchain_current), "utf-8"), + status=200, + times=FOREVER, + headers={'Content-Type': 'application/json'}) + + mock.when('GET /blockchain/block/15')\ + .reply(body=bytes(json.dumps(bma_blockchain_current), "utf-8"), + status=200, + times=FOREVER, + headers={'Content-Type': 'application/json'}) + + mock.when('GET /tx/history/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ/blocks/0/99')\ + .reply(body=bytes(json.dumps(bma_txhistory_john), "utf-8"), + status=200, + times=FOREVER, + headers={'Content-Type': 'application/json'}) + + mock.when('GET /tx/sources/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\ + .reply(body=bytes(json.dumps(bma_txsources_john), "utf-8"), + status=200, + times=FOREVER, + headers={'Content-Type': 'application/json'}) + + + mock.when('GET /ud/history/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\ + .reply(body=bytes(json.dumps(bma_udhistory_john), "utf-8"), status=200, times=FOREVER, headers={'Content-Type': 'application/json'}) mock.when('GET /wot/certifiers-of/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\ - .reply(body=bma_certifiers_of_john, + .reply(body=bytes(json.dumps(bma_certifiers_of_john), "utf-8"), status=200, times=FOREVER, headers={'Content-Type': 'application/json'}) mock.when('GET /wot/certified-by/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\ - .reply(body=bma_certified_by_john, + .reply(body=bytes(json.dumps(bma_certified_by_john), "utf-8"), status=200, times=FOREVER, headers={'Content-Type': 'application/json'}) mock.when('GET /wot/lookup/john')\ - .reply(body=bma_lookup_john, + .reply(body=bytes(json.dumps(bma_lookup_john), "utf-8"), status=200, times=FOREVER, headers={'Content-Type': 'application/json'}) mock.when('GET /wot/lookup/7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ')\ - .reply(body=bma_lookup_john, + .reply(body=bytes(json.dumps(bma_lookup_john), "utf-8"), status=200, times=FOREVER, headers={'Content-Type': 'application/json'}) mock.when('GET /wot/lookup/doe')\ - .reply(body=bma_lookup_doe, + .reply(body=bytes(json.dumps(bma_lookup_doe), "utf-8"), status=200, times=1, headers={'Content-Type': 'application/json'}) mock.when('GET /wot/lookup/FADxcH5LmXGmGFgdixSes6nWnC4Vb4pRUBYT81zQRhjn')\ - .reply(body=bma_lookup_doe, + .reply(body=bytes(json.dumps(bma_lookup_doe), "utf-8"), status=200, times=FOREVER, headers={'Content-Type': 'application/json'})