import asyncio from decimal import Decimal from time import time from lbry.schema.claim import Claim from lbry.extras.daemon.exchange_rate_manager import ( ExchangeRate, ExchangeRateManager, CurrencyConversionError, BittrexUSDFeed, BittrexBTCFeed, CoinExBTCFeed ) from lbry.testcase import AsyncioTestCase, FakeExchangeRateManager, get_fake_exchange_rate_manager from lbry.error import InvalidExchangeRateResponseError class ExchangeRateTests(AsyncioTestCase): def test_invalid_rates(self): with self.assertRaises(ValueError): ExchangeRate('USDBTC', 0, time()) with self.assertRaises(ValueError): ExchangeRate('USDBTC', -1, time()) def test_fee_converts_to_lbc(self): fee = Claim().stream.fee fee.usd = Decimal(10.0) fee.address = "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9" manager = get_fake_exchange_rate_manager() result = manager.convert_currency(fee.currency, "LBC", fee.amount) self.assertEqual(20.0, result) def test_missing_feed(self): fee = Claim().stream.fee fee.usd = Decimal(1.0) fee.address = "bRcHraa8bYJZL7vkh5sNmGwPDERFUjGPP9" manager = FakeExchangeRateManager([BittrexBTCFeed()], {'BTCLBC': 1.0}) with self.assertRaises(CurrencyConversionError): manager.convert_currency(fee.currency, "LBC", fee.amount) def test_bittrex_feed_response(self): feed = BittrexBTCFeed() out = feed.get_rate_from_response({ "symbol": "LBC-BTC", "lastTradeRate": "0.00000323", "bidRate": "0.00000322", "askRate": "0.00000327" }) self.assertEqual(1.0 / 0.00000323, out) with self.assertRaises(InvalidExchangeRateResponseError): feed.get_rate_from_response({}) with self.assertRaises(InvalidExchangeRateResponseError): feed.get_rate_from_response({ "success": True, "result": [] }) class BadMarketFeed(BittrexUSDFeed): def get_response(self): raise InvalidExchangeRateResponseError(self.name, 'bad stuff') class ExchangeRateManagerTests(AsyncioTestCase): async def test_get_rate_failure_retrieved(self): manager = ExchangeRateManager([BadMarketFeed]) manager.start() await manager.wait() for feed in manager.market_feeds: # no rate but it tried self.assertFalse(feed.has_rate) self.assertTrue(feed.event.is_set()) self.addCleanup(manager.stop) async def test_median_rate_used(self): manager = ExchangeRateManager([BittrexBTCFeed, CoinExBTCFeed]) for feed in manager.market_feeds: feed.last_check = time() bittrex, coinex = manager.market_feeds bittrex.rate = ExchangeRate(bittrex.market, 1.0, time()) coinex.rate = ExchangeRate(coinex.market, 2.0, time()) coinex.rate = ExchangeRate(coinex.market, 3.0, time()) self.assertEqual(14.0, manager.convert_currency("BTC", "LBC", Decimal(7.0))) coinex.rate.spot = 4.0 self.assertEqual(17.5, manager.convert_currency("BTC", "LBC", Decimal(7.0)))