You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.8 KiB
140 lines
4.8 KiB
import shutil |
|
import tempfile |
|
import sys |
|
import os |
|
import json |
|
from decimal import Decimal |
|
from unittest import TestCase |
|
import time |
|
|
|
from io import StringIO |
|
from electrum.storage import WalletStorage, FINAL_SEED_VERSION |
|
from electrum.wallet import Abstract_Wallet |
|
from electrum.exchange_rate import ExchangeBase, FxThread |
|
from electrum.util import TxMinedStatus |
|
from electrum.bitcoin import COIN |
|
|
|
from . import SequentialTestCase |
|
|
|
|
|
class FakeSynchronizer(object): |
|
|
|
def __init__(self): |
|
self.store = [] |
|
|
|
def add(self, address): |
|
self.store.append(address) |
|
|
|
|
|
class WalletTestCase(SequentialTestCase): |
|
|
|
def setUp(self): |
|
super(WalletTestCase, self).setUp() |
|
self.user_dir = tempfile.mkdtemp() |
|
|
|
self.wallet_path = os.path.join(self.user_dir, "somewallet") |
|
|
|
self._saved_stdout = sys.stdout |
|
self._stdout_buffer = StringIO() |
|
sys.stdout = self._stdout_buffer |
|
|
|
def tearDown(self): |
|
super(WalletTestCase, self).tearDown() |
|
shutil.rmtree(self.user_dir) |
|
# Restore the "real" stdout |
|
sys.stdout = self._saved_stdout |
|
|
|
|
|
class TestWalletStorage(WalletTestCase): |
|
|
|
def test_read_dictionary_from_file(self): |
|
|
|
some_dict = {"a":"b", "c":"d"} |
|
contents = json.dumps(some_dict) |
|
with open(self.wallet_path, "w") as f: |
|
contents = f.write(contents) |
|
|
|
storage = WalletStorage(self.wallet_path, manual_upgrades=True) |
|
self.assertEqual("b", storage.get("a")) |
|
self.assertEqual("d", storage.get("c")) |
|
|
|
def test_write_dictionary_to_file(self): |
|
|
|
storage = WalletStorage(self.wallet_path) |
|
|
|
some_dict = { |
|
u"a": u"b", |
|
u"c": u"d", |
|
u"seed_version": FINAL_SEED_VERSION} |
|
|
|
for key, value in some_dict.items(): |
|
storage.put(key, value) |
|
storage.write() |
|
|
|
with open(self.wallet_path, "r") as f: |
|
contents = f.read() |
|
self.assertEqual(some_dict, json.loads(contents)) |
|
|
|
class FakeExchange(ExchangeBase): |
|
def __init__(self, rate): |
|
super().__init__(lambda self: None, lambda self: None) |
|
self.quotes = {'TEST': rate} |
|
|
|
class FakeFxThread: |
|
def __init__(self, exchange): |
|
self.exchange = exchange |
|
self.ccy = 'TEST' |
|
|
|
remove_thousands_separator = staticmethod(FxThread.remove_thousands_separator) |
|
timestamp_rate = FxThread.timestamp_rate |
|
ccy_amount_str = FxThread.ccy_amount_str |
|
history_rate = FxThread.history_rate |
|
|
|
class FakeWallet: |
|
def __init__(self, fiat_value): |
|
super().__init__() |
|
self.fiat_value = fiat_value |
|
self.transactions = self.verified_tx = {'abc': 'Tx'} |
|
|
|
def get_tx_height(self, txid): |
|
# because we use a current timestamp, and history is empty, |
|
# FxThread.history_rate will use spot prices |
|
return TxMinedStatus(height=10, conf=10, timestamp=time.time(), header_hash='def') |
|
|
|
default_fiat_value = Abstract_Wallet.default_fiat_value |
|
price_at_timestamp = Abstract_Wallet.price_at_timestamp |
|
class storage: |
|
put = lambda self, x: None |
|
|
|
txid = 'abc' |
|
ccy = 'TEST' |
|
|
|
class TestFiat(TestCase): |
|
def setUp(self): |
|
self.value_sat = COIN |
|
self.fiat_value = {} |
|
self.wallet = FakeWallet(fiat_value=self.fiat_value) |
|
self.fx = FakeFxThread(FakeExchange(Decimal('1000.001'))) |
|
default_fiat = Abstract_Wallet.default_fiat_value(self.wallet, txid, self.fx, self.value_sat) |
|
self.assertEqual(Decimal('1000.001'), default_fiat) |
|
self.assertEqual('1,000.00', self.fx.ccy_amount_str(default_fiat, commas=True)) |
|
|
|
def test_save_fiat_and_reset(self): |
|
self.assertEqual(False, Abstract_Wallet.set_fiat_value(self.wallet, txid, ccy, '1000.01', self.fx, self.value_sat)) |
|
saved = self.fiat_value[ccy][txid] |
|
self.assertEqual('1,000.01', self.fx.ccy_amount_str(Decimal(saved), commas=True)) |
|
self.assertEqual(True, Abstract_Wallet.set_fiat_value(self.wallet, txid, ccy, '', self.fx, self.value_sat)) |
|
self.assertNotIn(txid, self.fiat_value[ccy]) |
|
# even though we are not setting it to the exact fiat value according to the exchange rate, precision is truncated away |
|
self.assertEqual(True, Abstract_Wallet.set_fiat_value(self.wallet, txid, ccy, '1,000.002', self.fx, self.value_sat)) |
|
|
|
def test_too_high_precision_value_resets_with_no_saved_value(self): |
|
self.assertEqual(True, Abstract_Wallet.set_fiat_value(self.wallet, txid, ccy, '1,000.001', self.fx, self.value_sat)) |
|
|
|
def test_empty_resets(self): |
|
self.assertEqual(True, Abstract_Wallet.set_fiat_value(self.wallet, txid, ccy, '', self.fx, self.value_sat)) |
|
self.assertNotIn(ccy, self.fiat_value) |
|
|
|
def test_save_garbage(self): |
|
self.assertEqual(False, Abstract_Wallet.set_fiat_value(self.wallet, txid, ccy, 'garbage', self.fx, self.value_sat)) |
|
self.assertNotIn(ccy, self.fiat_value)
|
|
|