X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=tests%2Ftest_store.py;h=d0f7755c10cd73285861a004acda2f27a3b37c6f;hb=40d0fa279e0745b33676f21cdc8b496ebd301cf8;hp=408c0e88cac7a667b088233af6db26a37205f010;hpb=1d72880c097ea8259ce9cc63cfe55e6cc7516bd2;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/tests/test_store.py b/tests/test_store.py index 408c0e8..d0f7755 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -4,12 +4,14 @@ import datetime import threading import market, portfolio, store +@unittest.skipUnless("unit" in limits, "Unit skipped") class NoopLockTest(unittest.TestCase): def test_with(self): noop_lock = store.NoopLock() with noop_lock: self.assertTrue(True) +@unittest.skipUnless("unit" in limits, "Unit skipped") class LockedVarTest(unittest.TestCase): def test_values(self): @@ -61,6 +63,7 @@ class LockedVarTest(unittest.TestCase): thread3.join() self.assertEqual("Bar", locked_var.get()[0:3]) +@unittest.skipUnless("unit" in limits, "Unit skipped") class TradeStoreTest(WebMockTestCase): def test_compute_trades(self): self.m.balances.currencies.return_value = ["XMR", "DASH", "XVG", "BTC", "ETH"] @@ -285,6 +288,7 @@ class TradeStoreTest(WebMockTestCase): self.assertEqual([trade_mock1, trade_mock2], trade_store.pending) +@unittest.skipUnless("unit" in limits, "Unit skipped") class BalanceStoreTest(WebMockTestCase): def setUp(self): super().setUp() @@ -365,17 +369,27 @@ class BalanceStoreTest(WebMockTestCase): balance_store = market.BalanceStore(self.m) - balance_store.fetch_balances() - self.assertNotIn("ETC", balance_store.currencies()) - self.assertListEqual(["USDT", "XVG", "XMR"], list(balance_store.currencies())) - - balance_store.all["ETC"] = portfolio.Balance("ETC", { - "exchange_total": "1", "exchange_free": "0", - "exchange_used": "1" }) - balance_store.fetch_balances(tag="foo") - self.assertEqual(0, balance_store.all["ETC"].total) - self.assertListEqual(["USDT", "XVG", "XMR", "ETC"], list(balance_store.currencies())) - self.m.report.log_balances.assert_called_with(tag="foo") + with self.subTest(log_tickers=False): + balance_store.fetch_balances() + self.assertNotIn("ETC", balance_store.currencies()) + self.assertListEqual(["USDT", "XVG", "XMR"], list(balance_store.currencies())) + + balance_store.all["ETC"] = portfolio.Balance("ETC", { + "exchange_total": "1", "exchange_free": "0", + "exchange_used": "1" }) + balance_store.fetch_balances(tag="foo") + self.assertEqual(0, balance_store.all["ETC"].total) + self.assertListEqual(["USDT", "XVG", "XMR", "ETC"], list(balance_store.currencies())) + self.m.report.log_balances.assert_called_with(tag="foo") + + with self.subTest(log_tickers=True),\ + mock.patch.object(balance_store, "in_currency") as in_currency: + in_currency.return_value = "tickers" + balance_store.fetch_balances(log_tickers=True, ticker_currency="FOO", + ticker_compute_value="compute", ticker_type="type") + self.m.report.log_balances.assert_called_with(compute_value='compute', + tag=None, ticker_currency='FOO', tickers='tickers', + type='type') @mock.patch.object(market.Portfolio, "repartition") def test_dispatch_assets(self, repartition): @@ -437,6 +451,7 @@ class BalanceStoreTest(WebMockTestCase): self.assertEqual(1, as_json["BTC"]) self.assertEqual(2, as_json["ETH"]) +@unittest.skipUnless("unit" in limits, "Unit skipped") class ReportStoreTest(WebMockTestCase): def test_add_log(self): with self.subTest(market=self.m): @@ -454,6 +469,13 @@ class ReportStoreTest(WebMockTestCase): self.assertEqual({"foo": "bar", "date": mock.ANY, "user_id": None, "market_id": None}, result) + def test_add_redis_status(self): + report_store = market.ReportStore(self.m) + result = report_store.add_redis_status({"foo": "bar"}) + + self.assertEqual({"foo": "bar"}, result) + self.assertEqual(result, report_store.redis_status[0]) + def test_set_verbose(self): report_store = market.ReportStore(self.m) with self.subTest(verbose=True): @@ -529,6 +551,20 @@ class ReportStoreTest(WebMockTestCase): self.assertEqual(("date1", "type1", '{\n "foo": "bar",\n "bla": "bla"\n}'), logs[0]) self.assertEqual(("date2", "type2", '{\n "foo": "bar",\n "bla": "bla"\n}'), logs[1]) + def test_to_json_redis(self): + report_store = market.ReportStore(self.m) + report_store.redis_status.append({ + "type": "type1", "foo": "bar", "bla": "bla" + }) + report_store.redis_status.append({ + "type": "type2", "foo": "bar", "bla": "bla" + }) + logs = list(report_store.to_json_redis()) + + self.assertEqual(2, len(logs)) + self.assertEqual(("type1", '{"foo": "bar", "bla": "bla"}'), logs[0]) + self.assertEqual(("type2", '{"foo": "bar", "bla": "bla"}'), logs[1]) + @mock.patch.object(market.ReportStore, "print_log") @mock.patch.object(market.ReportStore, "add_log") def test_log_stage(self, add_log, print_log): @@ -554,22 +590,79 @@ class ReportStoreTest(WebMockTestCase): @mock.patch.object(market.ReportStore, "print_log") @mock.patch.object(market.ReportStore, "add_log") - def test_log_balances(self, add_log, print_log): + @mock.patch.object(market.ReportStore, "add_redis_status") + def test_log_balances(self, add_redis_status, add_log, print_log): report_store = market.ReportStore(self.m) self.m.balances.as_json.return_value = "json" self.m.balances.all = { "FOO": "bar", "BAR": "baz" } - report_store.log_balances(tag="tag") - print_log.assert_has_calls([ - mock.call("[Balance]"), - mock.call("\tbar"), - mock.call("\tbaz"), - ]) - add_log.assert_called_once_with({ - 'type': 'balance', - 'balances': 'json', - 'tag': 'tag' - }) + with self.subTest(tickers=None): + report_store.log_balances(tag="tag") + print_log.assert_has_calls([ + mock.call("[Balance]"), + mock.call("\tbar"), + mock.call("\tbaz"), + ]) + add_log.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag' + }) + add_redis_status.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag' + }) + add_log.reset_mock() + add_redis_status.reset_mock() + with self.subTest(tickers="present"): + amounts = { + "BTC": portfolio.Amount("BTC", 10), + "ETH": portfolio.Amount("BTC", D("0.3")) + } + amounts["ETH"].rate = D("0.1") + + report_store.log_balances(tag="tag", tickers=amounts, + ticker_currency="BTC", compute_value="default", + type="total") + add_log.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag', + 'tickers': { + 'compute_value': 'default', + 'balance_type': 'total', + 'currency': 'BTC', + 'balances': { + 'BTC': D('10'), + 'ETH': D('0.3') + }, + 'rates': { + 'BTC': None, + 'ETH': D('0.1') + }, + 'total': D('10.3') + }, + }) + add_redis_status.assert_called_once_with({ + 'type': 'balance', + 'balances': 'json', + 'tag': 'tag', + 'tickers': { + 'compute_value': 'default', + 'balance_type': 'total', + 'currency': 'BTC', + 'balances': { + 'BTC': D('10'), + 'ETH': D('0.3') + }, + 'rates': { + 'BTC': None, + 'ETH': D('0.1') + }, + 'total': D('10.3') + }, + }) @mock.patch.object(market.ReportStore, "print_log") @mock.patch.object(market.ReportStore, "add_log") @@ -830,6 +923,7 @@ class ReportStoreTest(WebMockTestCase): response = mock.Mock() response.status_code = 200 response.text = "Hey" + response.elapsed.total_seconds.return_value = 120 report_store.log_http_request("method", "url", "body", "headers", response) @@ -840,6 +934,7 @@ class ReportStoreTest(WebMockTestCase): 'body': 'body', 'headers': 'headers', 'status': 200, + 'duration': 120, 'response': 'Hey', 'response_same_as': None, }) @@ -995,6 +1090,7 @@ class ReportStoreTest(WebMockTestCase): 'action': 'Hey' }) +@unittest.skipUnless("unit" in limits, "Unit skipped") class PortfolioTest(WebMockTestCase): def setUp(self): super().setUp() @@ -1005,7 +1101,8 @@ class PortfolioTest(WebMockTestCase): self.wm.get(market.Portfolio.URL, text=self.json_response) @mock.patch.object(market.Portfolio, "parse_cryptoportfolio") - def test_get_cryptoportfolio(self, parse_cryptoportfolio): + @mock.patch.object(market.Portfolio, "store_cryptoportfolio") + def test_get_cryptoportfolio(self, store_cryptoportfolio, parse_cryptoportfolio): with self.subTest(parallel=False): self.wm.get(market.Portfolio.URL, [ {"text":'{ "foo": "bar" }', "status_code": 200}, @@ -1020,23 +1117,28 @@ class PortfolioTest(WebMockTestCase): market.Portfolio.report.log_error.assert_not_called() market.Portfolio.report.log_http_request.assert_called_once() parse_cryptoportfolio.assert_called_once_with() + store_cryptoportfolio.assert_called_once_with() market.Portfolio.report.log_http_request.reset_mock() parse_cryptoportfolio.reset_mock() + store_cryptoportfolio.reset_mock() market.Portfolio.data = store.LockedVar(None) market.Portfolio.get_cryptoportfolio() self.assertIsNone(market.Portfolio.data.get()) self.assertEqual(2, self.wm.call_count) parse_cryptoportfolio.assert_not_called() + store_cryptoportfolio.assert_not_called() market.Portfolio.report.log_error.assert_not_called() market.Portfolio.report.log_http_request.assert_called_once() market.Portfolio.report.log_http_request.reset_mock() parse_cryptoportfolio.reset_mock() + store_cryptoportfolio.reset_mock() market.Portfolio.data = store.LockedVar("Foo") market.Portfolio.get_cryptoportfolio() self.assertEqual(2, self.wm.call_count) parse_cryptoportfolio.assert_not_called() + store_cryptoportfolio.assert_not_called() market.Portfolio.get_cryptoportfolio(refetch=True) self.assertEqual("Foo", market.Portfolio.data.get()) @@ -1057,6 +1159,7 @@ class PortfolioTest(WebMockTestCase): market.Portfolio.get_cryptoportfolio() self.assertIn("foo", market.Portfolio.data.get()) parse_cryptoportfolio.reset_mock() + store_cryptoportfolio.reset_mock() with self.subTest(worker=False): market.Portfolio.data = store.LockedVar(None) market.Portfolio.worker = mock.Mock() @@ -1064,6 +1167,7 @@ class PortfolioTest(WebMockTestCase): market.Portfolio.get_cryptoportfolio() notify.assert_called_once_with() parse_cryptoportfolio.assert_not_called() + store_cryptoportfolio.assert_not_called() def test_parse_cryptoportfolio(self): with self.subTest(description="Normal case"): @@ -1127,6 +1231,33 @@ class PortfolioTest(WebMockTestCase): self.assertEqual({}, market.Portfolio.liquidities.get("high")) self.assertEqual(datetime.datetime(1,1,1), market.Portfolio.last_date.get()) + @mock.patch.object(store.dbs, "redis_connected") + @mock.patch.object(store.dbs, "redis") + def test_store_cryptoportfolio(self, redis, redis_connected): + store.Portfolio.liquidities = store.LockedVar({ + "medium": { + datetime.datetime(2018,3,1): "medium_2018-03-01", + datetime.datetime(2018,3,8): "medium_2018-03-08", + }, + "high": { + datetime.datetime(2018,3,1): "high_2018-03-01", + datetime.datetime(2018,3,8): "high_2018-03-08", + } + }) + store.Portfolio.last_date = store.LockedVar(datetime.datetime(2018,3,8)) + + with self.subTest(redis_connected=False): + redis_connected.return_value = False + store.Portfolio.store_cryptoportfolio() + redis.set.assert_not_called() + + with self.subTest(redis_connected=True): + redis_connected.return_value = True + store.Portfolio.store_cryptoportfolio() + redis.set.assert_has_calls([ + mock.call("/cryptoportfolio/repartition/latest", '{"medium": "medium_2018-03-08", "high": "high_2018-03-08"}'), + mock.call("/cryptoportfolio/repartition/date", "2018-03-08"), + ]) @mock.patch.object(market.Portfolio, "get_cryptoportfolio") def test_repartition(self, get_cryptoportfolio): @@ -1245,7 +1376,7 @@ class PortfolioTest(WebMockTestCase): store.Portfolio.callback.wait() - report.print_log.assert_called_once_with("Fetching cryptoportfolio") + report.print_log.assert_called_once_with("[Worker] Fetching cryptoportfolio") get.assert_called_once_with(refetch=True) sleep.assert_called_once_with(3) self.assertFalse(store.Portfolio.worker_notify.is_set())