Skip to content
Snippets Groups Projects
Commit 78060fa5 authored by matograine's avatar matograine
Browse files

[test] #213: modify patched_get_source()

* modify values to facilitate test writing
* rename `amount` variable to `balance`

* create test_constants file to prevent circular dependencies
    * modify relevant files : import mock_ud_value from patched.test_constants instead of patched.money

* patched_get_sources() now has a `counter` attribute, and can return different values if called twice
    * can mock the result of an intermediary transaction.

* mod test_get_list_input_for_transaction()
  * to reset the patched_get_sources counter.
  * to make values match new patch behavior
  * to comment what is tested
parent 5031b5e9
Branches
Tags
1 merge request!130#213: Write unit tests for the transaction command
...@@ -17,13 +17,10 @@ along with Silkaj. If not, see <https://www.gnu.org/licenses/>. ...@@ -17,13 +17,10 @@ along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
# This file contains patched functions for testing purposes. # This file contains patched functions for testing purposes.
from silkaj.constants import G1_SYMBOL from silkaj.constants import G1_SYMBOL, SOURCES_PER_TX
from silkaj.money import amount_in_current_base from silkaj.money import amount_in_current_base
from duniterpy.documents.transaction import InputSource from duniterpy.documents.transaction import InputSource
from patched.test_constants import mock_ud_value
# mock UDValue
mock_ud_value = 314
async def patched_ud_value(self): async def patched_ud_value(self):
...@@ -35,16 +32,26 @@ async def patched_get_sources(pubkey): ...@@ -35,16 +32,26 @@ async def patched_get_sources(pubkey):
""" """
Returns transaction sources. Returns transaction sources.
This function doesn't cover all possibilities : only SIG() unlock condition. This function doesn't cover all possibilities : only SIG() unlock condition.
for pubkey DBM6F5ChMJzpmkUdL5zD9UXKExmZGfQ1AgPDQy4MxSBw : 3 TX, amount = 600
for pubkey 4szFkvQ5tzzhwcfUtZD32hdoG2ZzhvG3ZtfR61yjnxdw : 53 TX, amount = 143100 Can be called many times (depending on pubkey).
for pubkey BFb5yv8z1fowR6Z8mBXTALy5z7gHfMU976WtXhmRsUMh : 10 UD, amount = 3140 If so, it will mock intermediary tx for the first 40 inputs.
for pubkey C1oAV9FX2y9iz2sdp7kZBFu3EBNAa6UkrrRG3EwouPeH : 50 UD and 20 TX, amount = 36700 Tests using this function should reset the counter at the begining of each test case.
else : 0 sources, amount = 0 See source_dict.py for inputs lists.
all UTXO have the same amount : 100
all UD have the same amount : 314
for pubkey CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp : 3 TX, balance = 300
for pubkey HcRgKh4LwbQVYuAc3xAdCynYXpKoiPE6qdxCMa8JeHat : 53 TX, balance = 5300
for pubkey 2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY : 10 UD, balance = 3140
for pubkey 9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp : 50 UD and 20 TX, balance = 17700
else : 0 sources, balance = 0
Same hash for each TX for convenience. This may change for other testing purposes. Same hash for each TX for convenience. This may change for other testing purposes.
""" """
def listinput_UD(listinput, amount, pubkey, max_ud, total): def listinput_UD(listinput, balance, pubkey, max_ud):
while max_ud > 0 and total > 0: a = 0
while a < max_ud:
listinput.append( listinput.append(
InputSource( InputSource(
amount=mock_ud_value, amount=mock_ud_value,
...@@ -54,46 +61,73 @@ async def patched_get_sources(pubkey): ...@@ -54,46 +61,73 @@ async def patched_get_sources(pubkey):
index=max_ud, index=max_ud,
) )
) )
amount += amount_in_current_base(listinput[-1]) balance += amount_in_current_base(listinput[-1])
max_ud -= 1 a += 1
total -= 1
def listinput_TX(listinput, amount, max_tx, total): def listinput_TX(listinput, balance, max_tx):
orig_max = max_tx + 1 a = 0
while max_tx > 0 and total > 0: while a < max_tx:
listinput.append( listinput.append(
InputSource( InputSource(
amount=(orig_max - max_tx) * 100, amount=100,
base=0, base=0,
source="T", source="T",
origin_id="1F3059ABF35D78DFB5AFFB3DEAB4F76878B04DB6A14757BBD6B600B1C19157E7", origin_id="1F3059ABF35D78DFB5AFFB3DEAB4F76878B04DB6A14757BBD6B600B1C19157E7",
index=max_tx, index=max_tx,
) )
) )
amount += amount_in_current_base(listinput[-1]) balance += amount_in_current_base(listinput[-1])
max_tx -= 1 a += 1
total -= 1
listinput, n = list(), 0 listinput, n = list(), 0
amount = 0 balance = 0
if pubkey == "CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp": if pubkey == "CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp":
max_tx = 3
max_ud = 0 max_ud = 0
max_tx = 3
elif pubkey == "HcRgKh4LwbQVYuAc3xAdCynYXpKoiPE6qdxCMa8JeHat": elif pubkey == "HcRgKh4LwbQVYuAc3xAdCynYXpKoiPE6qdxCMa8JeHat":
if patched_get_sources.counter == 0:
max_ud = 0
max_tx = 53 max_tx = 53
elif patched_get_sources.counter == 1:
listinput.append(
InputSource(
amount=100 * SOURCES_PER_TX, # 100 * 40 = 4000
base=0,
source="T",
origin_id="1F3059ABF35D78DFB5AFFB3DEAB4F76878B04DB6A14757BBD6B600B1C19157E7",
index=93,
)
)
max_ud = 0 max_ud = 0
max_tx = 6
elif pubkey == "2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY": elif pubkey == "2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY":
max_tx = 0
max_ud = 10 max_ud = 10
max_tx = 0
elif pubkey == "9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp": elif pubkey == "9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp":
max_tx = 20 if patched_get_sources.counter == 0:
max_ud = 50 max_ud = 50
max_tx = 20
elif patched_get_sources.counter == 1:
listinput.append(
InputSource(
amount=mock_ud_value * SOURCES_PER_TX, # 40 UD = 40*314 = 12560
base=0,
source="T",
origin_id="1F3059ABF35D78DFB5AFFB3DEAB4F76878B04DB6A14757BBD6B600B1C19157E7",
index=93,
)
)
max_ud = 4
max_tx = 20
else: else:
max_tx = 0
max_ud = 0 max_ud = 0
max_tx = 0
listinput_UD(listinput, balance, pubkey, max_ud)
listinput_TX(listinput, balance, max_tx)
patched_get_sources.counter += 1
return listinput, balance
total = max_tx + max_ud
listinput_TX(listinput, amount, max_tx, total)
listinput_UD(listinput, amount, pubkey, max_ud, total)
return listinput, amount patched_get_sources.counter = 0
# this file contains only constant values for testing (no function) to prevent circular dependencies
mock_ud_value = 314
...@@ -20,7 +20,7 @@ from silkaj.tui import display_pubkey, display_amount, display_pubkey_and_checks ...@@ -20,7 +20,7 @@ from silkaj.tui import display_pubkey, display_amount, display_pubkey_and_checks
from silkaj.constants import G1_SYMBOL, SHORT_PUBKEY_SIZE from silkaj.constants import G1_SYMBOL, SHORT_PUBKEY_SIZE
from patched.wot import patched_is_member from patched.wot import patched_is_member
from patched.money import mock_ud_value from patched.test_constants import mock_ud_value
# display_amount() # display_amount()
@pytest.mark.parametrize( @pytest.mark.parametrize(
......
...@@ -23,7 +23,8 @@ from silkaj.money import UDValue ...@@ -23,7 +23,8 @@ from silkaj.money import UDValue
from silkaj.cli import cli from silkaj.cli import cli
from silkaj.constants import MINIMAL_ABSOLUTE_TX_AMOUNT, FAILURE_EXIT_STATUS from silkaj.constants import MINIMAL_ABSOLUTE_TX_AMOUNT, FAILURE_EXIT_STATUS
from patched.money import mock_ud_value, patched_ud_value from patched.money import patched_ud_value
from patched.test_constants import mock_ud_value
@pytest.mark.asyncio @pytest.mark.asyncio
......
...@@ -41,7 +41,8 @@ from duniterpy.documents.transaction import ( ...@@ -41,7 +41,8 @@ from duniterpy.documents.transaction import (
from duniterpy.documents.block_uid import BlockUID from duniterpy.documents.block_uid import BlockUID
from patched.wot import patched_is_member from patched.wot import patched_is_member
from patched.money import patched_get_sources, patched_ud_value, mock_ud_value from patched.money import patched_get_sources, patched_ud_value
from patched.test_constants import mock_ud_value
from patched.tools import patched_currency_symbol from patched.tools import patched_currency_symbol
from patched.blockchain_tools import patched_head_block from patched.blockchain_tools import patched_head_block
...@@ -429,24 +430,45 @@ async def test_generate_transaction_document( ...@@ -429,24 +430,45 @@ async def test_generate_transaction_document(
@pytest.mark.parametrize( @pytest.mark.parametrize(
"pubkey, TXamount, expected", "pubkey, TXamount, expected",
[ [
("CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp", 200, (2, 300, False)), # less than 1 source
("CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp", 600, (3, 600, False)), ("CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp", 99, (1, 100, False)),
# exactly one source
("CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp", 100, (1, 100, False)),
# more than 1 source and no interm tx
("CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp", 150, (2, 200, False)),
# all sources
("CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp", 300, (3, 300, False)),
# too high amount
( (
"CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp", "CtM5RZHopnSRAAoWNgTWrUhDEmspcCAxn6fuCEWDWudp",
800, 301,
"Error: you don't have enough money", "Error: you don't have enough money",
), ),
("HcRgKh4LwbQVYuAc3xAdCynYXpKoiPE6qdxCMa8JeHat", 143100, (40, 82000, True)), # need for an intermediary tx
("HcRgKh4LwbQVYuAc3xAdCynYXpKoiPE6qdxCMa8JeHat", 4100, (40, 4000, True)),
# no need for an intermediary tx, but the function still does it
("HcRgKh4LwbQVYuAc3xAdCynYXpKoiPE6qdxCMa8JeHat", 4000, (40, 4000, True)),
# less than 1 UD source
("2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY", 200, (1, 314, False)), ("2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY", 200, (1, 314, False)),
# exactly 1 UD source
("2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY", 314, (1, 314, False)),
# all sources with UD sources
("2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY", 3140, (10, 3140, False)), ("2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY", 3140, (10, 3140, False)),
# too high amount
( (
"2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY", "2sq4w8yYVDWNxVWZqGWWDriFf5z7dn7iLahDCvEEotuY",
5000, 5000,
"Error: you don't have enough money", "Error: you don't have enough money",
), ),
("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 2900, (8, 3600, False)), # mix UD and TX source
("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 22500, (25, 22570, False)), ("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 2500, (8, 2512, False)),
("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 29000, (40, 27280, True)), ("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 7800, (25, 7850, False)),
# need for interm tx
("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 12561, (40, 12560, True)),
# no need for interm tx but the function still does it
("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 12247, (40, 12560, True)),
# exactly 39 sources
("9cwBBgXcSVMT74xiKYygX6FM5yTdwd3NABj1CfHbbAmp", 12246, (39, 12246, False)),
], ],
) )
@pytest.mark.asyncio @pytest.mark.asyncio
...@@ -455,11 +477,13 @@ async def test_get_list_input_for_transaction( ...@@ -455,11 +477,13 @@ async def test_get_list_input_for_transaction(
): ):
""" """
expected is [len(listinput), amount, IntermediateTransaction] or "Error" expected is [len(listinput), amount, IntermediateTransaction] or "Error"
see patched.get_sources() to compute expected values. see patched_get_sources() to compute expected values.
""" """
# patched functions # patched functions
monkeypatch.setattr("silkaj.money.get_sources", patched_get_sources) monkeypatch.setattr("silkaj.money.get_sources", patched_get_sources)
# reset patched_get_sources counter
patched_get_sources.counter = 0
# testing error exit # testing error exit
if isinstance(expected, str): if isinstance(expected, str):
with pytest.raises(SystemExit) as pytest_exit: with pytest.raises(SystemExit) as pytest_exit:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment