X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=test.py;h=40c64a95d769c2d9e8dc3b6cbbe182309002317e;hb=c7c1e0b26821fdd5622f81fb456f1028d4c9ab09;hp=f61e739d9a3e664cd30bfca1d185d13846c46cee;hpb=dc1ca9a306f09886c6c57f8d426c59a9d084b2b3;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/test.py b/test.py index f61e739..40c64a9 100644 --- a/test.py +++ b/test.py @@ -23,6 +23,9 @@ for test_type in limits: class WebMockTestCase(unittest.TestCase): import time + def market_args(self, debug=False, quiet=False): + return type('Args', (object,), { "debug": debug, "quiet": quiet })() + def setUp(self): super(WebMockTestCase, self).setUp() self.wm = requests_mock.Mocker() @@ -77,6 +80,58 @@ class poloniexETest(unittest.TestCase): time.return_value = 123456.7890123456 self.assertEqual(123456789012345, self.s.nonce()) + def test_request(self): + with mock.patch.object(market.ccxt.poloniex, "request") as request,\ + mock.patch("market.ccxt.retry_call") as retry_call: + with self.subTest(wrapped=True): + with self.subTest(desc="public"): + self.s.request("foo") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["foo"], + fkwargs={'api': 'public', 'method': 'GET', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + + with self.subTest(desc="private GET"): + self.s.request("foo", api="private") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["foo"], + fkwargs={'api': 'private', 'method': 'GET', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + + with self.subTest(desc="private POST regexp"): + self.s.request("returnFoo", api="private", method="POST") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["returnFoo"], + fkwargs={'api': 'private', 'method': 'POST', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + + with self.subTest(desc="private POST non-regexp"): + self.s.request("getMarginPosition", api="private", method="POST") + retry_call.assert_called_with(request, + delay=1, tries=10, fargs=["getMarginPosition"], + fkwargs={'api': 'private', 'method': 'POST', 'params': {}, 'headers': None, 'body': None}, + exceptions=(market.ccxt.RequestTimeout,)) + request.assert_not_called() + retry_call.reset_mock() + request.reset_mock() + with self.subTest(wrapped=False): + with self.subTest(desc="private POST non-matching regexp"): + self.s.request("marginBuy", api="private", method="POST") + request.assert_called_with("marginBuy", + api="private", method="POST", params={}, + headers=None, body=None) + retry_call.assert_not_called() + + with self.subTest(desc="private POST non-matching non-regexp"): + self.s.request("closeMarginPositionOther", api="private", method="POST") + request.assert_called_with("closeMarginPositionOther", + api="private", method="POST", params={}, + headers=None, body=None) + retry_call.assert_not_called() + def test_order_precision(self): self.assertEqual(8, self.s.order_precision("FOO")) @@ -1092,7 +1147,7 @@ class MarketTest(WebMockTestCase): self.ccxt = mock.Mock(spec=market.ccxt.poloniexE) def test_values(self): - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) self.assertEqual(self.ccxt, m.ccxt) self.assertFalse(m.debug) @@ -1104,19 +1159,27 @@ class MarketTest(WebMockTestCase): self.assertEqual(m, m.balances.market) self.assertEqual(m, m.ccxt._market) - m = market.Market(self.ccxt, debug=True) + m = market.Market(self.ccxt, self.market_args(debug=True)) self.assertTrue(m.debug) - m = market.Market(self.ccxt, debug=False) + m = market.Market(self.ccxt, self.market_args(debug=False)) self.assertFalse(m.debug) + with mock.patch("market.ReportStore") as report_store: + with self.subTest(quiet=False): + m = market.Market(self.ccxt, self.market_args(quiet=False)) + report_store.assert_called_with(m, verbose_print=True) + with self.subTest(quiet=True): + m = market.Market(self.ccxt, self.market_args(quiet=True)) + report_store.assert_called_with(m, verbose_print=False) + @mock.patch("market.ccxt") def test_from_config(self, ccxt): with mock.patch("market.ReportStore"): ccxt.poloniexE.return_value = self.ccxt self.ccxt.session.request.return_value = "response" - m = market.Market.from_config({"key": "key", "secred": "secret"}) + m = market.Market.from_config({"key": "key", "secred": "secret"}, self.market_args()) self.assertEqual(self.ccxt, m.ccxt) @@ -1125,7 +1188,7 @@ class MarketTest(WebMockTestCase): m.report.log_http_request.assert_called_with('GET', 'URL', 'data', 'headers', 'response') - m = market.Market.from_config({"key": "key", "secred": "secret"}, debug=True) + m = market.Market.from_config({"key": "key", "secred": "secret"}, self.market_args(debug=True)) self.assertEqual(True, m.debug) def test_get_tickers(self): @@ -1134,7 +1197,7 @@ class MarketTest(WebMockTestCase): market.NotSupported ] - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) self.assertEqual("tickers", m.get_tickers()) self.assertEqual("tickers", m.get_tickers()) self.ccxt.fetch_tickers.assert_called_once() @@ -1147,7 +1210,7 @@ class MarketTest(WebMockTestCase): "ETH/ETC": { "bid": 1, "ask": 3 }, "XVG/ETH": { "bid": 10, "ask": 40 }, } - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) ticker = m.get_ticker("ETH", "ETC") self.assertEqual(1, ticker["bid"]) @@ -1175,7 +1238,7 @@ class MarketTest(WebMockTestCase): market.ExchangeError("foo"), ] - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) ticker = m.get_ticker("ETH", "ETC") self.ccxt.fetch_ticker.assert_called_with("ETH/ETC") @@ -1195,7 +1258,7 @@ class MarketTest(WebMockTestCase): self.assertIsNone(ticker) def test_fetch_fees(self): - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) self.ccxt.fetch_fees.return_value = "Foo" self.assertEqual("Foo", m.fetch_fees()) self.ccxt.fetch_fees.assert_called_once() @@ -1222,7 +1285,7 @@ class MarketTest(WebMockTestCase): get_ticker.side_effect = _get_ticker with mock.patch("market.ReportStore"): - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) self.ccxt.fetch_all_balances.return_value = { "USDT": { "exchange_free": D("10000.0"), @@ -1262,7 +1325,7 @@ class MarketTest(WebMockTestCase): (False, 12), (True, 12)]: with self.subTest(sleep=sleep, debug=debug), \ mock.patch("market.ReportStore"): - m = market.Market(self.ccxt, debug=debug) + m = market.Market(self.ccxt, self.market_args(debug=debug)) order_mock1 = mock.Mock() order_mock2 = mock.Mock() @@ -1339,7 +1402,7 @@ class MarketTest(WebMockTestCase): for debug in [True, False]: with self.subTest(debug=debug),\ mock.patch("market.ReportStore"): - m = market.Market(self.ccxt, debug=debug) + m = market.Market(self.ccxt, self.market_args(debug=debug)) value_from = portfolio.Amount("BTC", "1.0") value_from.linked_to = portfolio.Amount("ETH", "10.0") @@ -1375,51 +1438,135 @@ class MarketTest(WebMockTestCase): self.ccxt.transfer_balance.assert_any_call("USDT", 100, "exchange", "margin") self.ccxt.transfer_balance.assert_any_call("ETC", 5, "margin", "exchange") - def test_store_report(self): - + def test_store_file_report(self): file_open = mock.mock_open() - m = market.Market(self.ccxt, user_id=1) - with self.subTest(file=None),\ + m = market.Market(self.ccxt, self.market_args(), report_path="present", user_id=1) + with self.subTest(file="present"),\ + mock.patch("market.open", file_open),\ + mock.patch.object(m, "report") as report,\ + mock.patch.object(market, "datetime") as time_mock: + + report.print_logs = [[time_mock.now(), "Foo"], [time_mock.now(), "Bar"]] + report.to_json.return_value = "json_content" + + m.store_file_report(datetime.datetime(2018, 2, 25)) + + file_open.assert_any_call("present/2018-02-25T00:00:00_1.json", "w") + file_open.assert_any_call("present/2018-02-25T00:00:00_1.log", "w") + file_open().write.assert_any_call("json_content") + file_open().write.assert_any_call("Foo\nBar") + m.report.to_json.assert_called_once_with() + + m = market.Market(self.ccxt, self.market_args(), report_path="error", user_id=1) + with self.subTest(file="error"),\ + mock.patch("market.open") as file_open,\ + mock.patch.object(m, "report") as report,\ + mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock: + file_open.side_effect = FileNotFoundError + + m.store_file_report(datetime.datetime(2018, 2, 25)) + + self.assertRegex(stdout_mock.getvalue(), "impossible to store report file: FileNotFoundError;") + + @mock.patch.object(market, "psycopg2") + def test_store_database_report(self, psycopg2): + connect_mock = mock.Mock() + cursor_mock = mock.MagicMock() + + connect_mock.cursor.return_value = cursor_mock + psycopg2.connect.return_value = connect_mock + m = market.Market(self.ccxt, self.market_args(), + pg_config={"config": "pg_config"}, user_id=1) + cursor_mock.fetchone.return_value = [42] + + with self.subTest(error=False),\ + mock.patch.object(m, "report") as report: + report.to_json_array.return_value = [ + ("date1", "type1", "payload1"), + ("date2", "type2", "payload2"), + ] + m.store_database_report(datetime.datetime(2018, 3, 24)) + connect_mock.assert_has_calls([ + mock.call.cursor(), + mock.call.cursor().execute('INSERT INTO reports("date", "market_config_id", "debug") VALUES (%s, %s, %s) RETURNING id;', (datetime.datetime(2018, 3, 24), None, False)), + mock.call.cursor().fetchone(), + mock.call.cursor().execute('INSERT INTO report_lines("date", "report_id", "type", "payload") VALUES (%s, %s, %s, %s);', ('date1', 42, 'type1', 'payload1')), + mock.call.cursor().execute('INSERT INTO report_lines("date", "report_id", "type", "payload") VALUES (%s, %s, %s, %s);', ('date2', 42, 'type2', 'payload2')), + mock.call.commit(), + mock.call.cursor().close(), + mock.call.close() + ]) + + connect_mock.reset_mock() + with self.subTest(error=True),\ + mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock: + psycopg2.connect.side_effect = Exception("Bouh") + m.store_database_report(datetime.datetime(2018, 3, 24)) + self.assertEqual(stdout_mock.getvalue(), "impossible to store report to database: Exception; Bouh\n") + + def test_store_report(self): + m = market.Market(self.ccxt, self.market_args(), user_id=1) + with self.subTest(file=None, pg_config=None),\ mock.patch.object(m, "report") as report,\ - mock.patch("market.open", file_open): + mock.patch.object(m, "store_database_report") as db_report,\ + mock.patch.object(m, "store_file_report") as file_report: m.store_report() report.merge.assert_called_with(store.Portfolio.report) - file_open.assert_not_called() + + file_report.assert_not_called() + db_report.assert_not_called() report.reset_mock() - file_open = mock.mock_open() - m = market.Market(self.ccxt, report_path="present", user_id=1) - with self.subTest(file="present"),\ - mock.patch("market.open", file_open),\ + m = market.Market(self.ccxt, self.market_args(), report_path="present", user_id=1) + with self.subTest(file="present", pg_config=None),\ mock.patch.object(m, "report") as report,\ + mock.patch.object(m, "store_file_report") as file_report,\ + mock.patch.object(m, "store_database_report") as db_report,\ mock.patch.object(market, "datetime") as time_mock: time_mock.now.return_value = datetime.datetime(2018, 2, 25) - report.to_json.return_value = "json_content" m.store_report() - file_open.assert_any_call("present/2018-02-25T00:00:00_1.json", "w") - file_open().write.assert_called_once_with("json_content") - m.report.to_json.assert_called_once_with() report.merge.assert_called_with(store.Portfolio.report) + file_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) + db_report.assert_not_called() report.reset_mock() + m = market.Market(self.ccxt, self.market_args(), pg_config="present", user_id=1) + with self.subTest(file=None, pg_config="present"),\ + mock.patch.object(m, "report") as report,\ + mock.patch.object(m, "store_file_report") as file_report,\ + mock.patch.object(m, "store_database_report") as db_report,\ + mock.patch.object(market, "datetime") as time_mock: - m = market.Market(self.ccxt, report_path="error", user_id=1) - with self.subTest(file="error"),\ - mock.patch("market.open") as file_open,\ + time_mock.now.return_value = datetime.datetime(2018, 2, 25) + + m.store_report() + + report.merge.assert_called_with(store.Portfolio.report) + file_report.assert_not_called() + db_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) + + report.reset_mock() + m = market.Market(self.ccxt, self.market_args(), + pg_config="pg_config", report_path="present", user_id=1) + with self.subTest(file="present", pg_config="present"),\ mock.patch.object(m, "report") as report,\ - mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock: - file_open.side_effect = FileNotFoundError + mock.patch.object(m, "store_file_report") as file_report,\ + mock.patch.object(m, "store_database_report") as db_report,\ + mock.patch.object(market, "datetime") as time_mock: + + time_mock.now.return_value = datetime.datetime(2018, 2, 25) m.store_report() report.merge.assert_called_with(store.Portfolio.report) - self.assertRegex(stdout_mock.getvalue(), "impossible to store report file: FileNotFoundError;") + file_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) + db_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) def test_print_orders(self): - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) with mock.patch.object(m.report, "log_stage") as log_stage,\ mock.patch.object(m.balances, "fetch_balances") as fetch_balances,\ mock.patch.object(m, "prepare_trades") as prepare_trades,\ @@ -1433,7 +1580,7 @@ class MarketTest(WebMockTestCase): prepare_orders.assert_called_with(compute_value="average") def test_print_balances(self): - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) with mock.patch.object(m.balances, "in_currency") as in_currency,\ mock.patch.object(m.report, "log_stage") as log_stage,\ @@ -1458,7 +1605,7 @@ class MarketTest(WebMockTestCase): @mock.patch("market.ReportStore.log_error") @mock.patch("market.Market.store_report") def test_process(self, store_report, log_error, process): - m = market.Market(self.ccxt) + m = market.Market(self.ccxt, self.market_args()) with self.subTest(before=False, after=False): m.process(None) @@ -2007,16 +2154,20 @@ class TradeTest(WebMockTestCase): value_to = portfolio.Amount("BTC", "1.0") trade = portfolio.Trade(value_from, value_to, "ETH", self.m) - self.assertEqual("buy", trade.order_action(False)) - self.assertEqual("sell", trade.order_action(True)) + trade.inverted = False + self.assertEqual("buy", trade.order_action()) + trade.inverted = True + self.assertEqual("sell", trade.order_action()) value_from = portfolio.Amount("BTC", "0") value_from.linked_to = portfolio.Amount("ETH", "0") value_to = portfolio.Amount("BTC", "-1.0") trade = portfolio.Trade(value_from, value_to, "ETH", self.m) - self.assertEqual("sell", trade.order_action(False)) - self.assertEqual("buy", trade.order_action(True)) + trade.inverted = False + self.assertEqual("sell", trade.order_action()) + trade.inverted = True + self.assertEqual("buy", trade.order_action()) def test_trade_type(self): value_from = portfolio.Amount("BTC", "0.5") @@ -2034,26 +2185,59 @@ class TradeTest(WebMockTestCase): self.assertEqual("short", trade.trade_type) def test_is_fullfiled(self): - value_from = portfolio.Amount("BTC", "0.5") - value_from.linked_to = portfolio.Amount("ETH", "10.0") - value_to = portfolio.Amount("BTC", "1.0") - trade = portfolio.Trade(value_from, value_to, "ETH", self.m) + with self.subTest(inverted=False): + value_from = portfolio.Amount("BTC", "0.5") + value_from.linked_to = portfolio.Amount("ETH", "10.0") + value_to = portfolio.Amount("BTC", "1.0") + trade = portfolio.Trade(value_from, value_to, "ETH", self.m) - order1 = mock.Mock() - order1.filled_amount.return_value = portfolio.Amount("BTC", "0.3") + order1 = mock.Mock() + order1.filled_amount.return_value = portfolio.Amount("BTC", "0.3") - order2 = mock.Mock() - order2.filled_amount.return_value = portfolio.Amount("BTC", "0.01") - trade.orders.append(order1) - trade.orders.append(order2) + order2 = mock.Mock() + order2.filled_amount.return_value = portfolio.Amount("BTC", "0.01") + trade.orders.append(order1) + trade.orders.append(order2) + + self.assertFalse(trade.is_fullfiled) - self.assertFalse(trade.is_fullfiled) + order3 = mock.Mock() + order3.filled_amount.return_value = portfolio.Amount("BTC", "0.19") + trade.orders.append(order3) - order3 = mock.Mock() - order3.filled_amount.return_value = portfolio.Amount("BTC", "0.19") - trade.orders.append(order3) + self.assertTrue(trade.is_fullfiled) + + order1.filled_amount.assert_called_with(in_base_currency=True) + order2.filled_amount.assert_called_with(in_base_currency=True) + order3.filled_amount.assert_called_with(in_base_currency=True) + + with self.subTest(inverted=True): + value_from = portfolio.Amount("BTC", "0.5") + value_from.linked_to = portfolio.Amount("USDT", "1000.0") + value_to = portfolio.Amount("BTC", "1.0") + trade = portfolio.Trade(value_from, value_to, "USDT", self.m) + trade.inverted = True + + order1 = mock.Mock() + order1.filled_amount.return_value = portfolio.Amount("BTC", "0.3") + + order2 = mock.Mock() + order2.filled_amount.return_value = portfolio.Amount("BTC", "0.01") + trade.orders.append(order1) + trade.orders.append(order2) + + self.assertFalse(trade.is_fullfiled) + + order3 = mock.Mock() + order3.filled_amount.return_value = portfolio.Amount("BTC", "0.19") + trade.orders.append(order3) + + self.assertTrue(trade.is_fullfiled) + + order1.filled_amount.assert_called_with(in_base_currency=False) + order2.filled_amount.assert_called_with(in_base_currency=False) + order3.filled_amount.assert_called_with(in_base_currency=False) - self.assertTrue(trade.is_fullfiled) def test_filled_amount(self): value_from = portfolio.Amount("BTC", "0.5") @@ -2713,7 +2897,8 @@ class OrderTest(WebMockTestCase): self.m.report.log_debug_action.assert_called_once() @mock.patch.object(portfolio.Order, "fetch_mouvements") - def test_fetch(self, fetch_mouvements): + @mock.patch.object(portfolio.Order, "mark_finished_order") + def test_fetch(self, mark_finished_order, fetch_mouvements): order = portfolio.Order("buy", portfolio.Amount("ETH", 10), D("0.1"), "BTC", "long", self.m, "trade") order.id = 45 @@ -2723,6 +2908,7 @@ class OrderTest(WebMockTestCase): self.m.report.log_debug_action.assert_called_once() self.m.report.log_debug_action.reset_mock() self.m.ccxt.fetch_order.assert_not_called() + mark_finished_order.assert_not_called() fetch_mouvements.assert_not_called() with self.subTest(debug=False): @@ -2739,17 +2925,19 @@ class OrderTest(WebMockTestCase): self.assertEqual("timestamp", order.timestamp) self.assertEqual(1, len(order.results)) self.m.report.log_debug_action.assert_not_called() + mark_finished_order.assert_called_once() + mark_finished_order.reset_mock() with self.subTest(missing_order=True): self.m.ccxt.fetch_order.side_effect = [ portfolio.OrderNotCached, ] order.fetch() self.assertEqual("closed_unknown", order.status) + mark_finished_order.assert_called_once() @mock.patch.object(portfolio.Order, "fetch") - @mock.patch.object(portfolio.Order, "mark_finished_order") - def test_get_status(self, mark_finished_order, fetch): + def test_get_status(self, fetch): with self.subTest(debug=True): self.m.debug = True order = portfolio.Order("buy", portfolio.Amount("ETH", 10), @@ -2768,10 +2956,8 @@ class OrderTest(WebMockTestCase): return update_status fetch.side_effect = _fetch(order) self.assertEqual("open", order.get_status()) - mark_finished_order.assert_not_called() fetch.assert_called_once() - mark_finished_order.reset_mock() fetch.reset_mock() with self.subTest(debug=False, finished=True): self.m.debug = False @@ -2783,7 +2969,6 @@ class OrderTest(WebMockTestCase): return update_status fetch.side_effect = _fetch(order) self.assertEqual("closed", order.get_status()) - mark_finished_order.assert_called_once() fetch.assert_called_once() def test_run(self): @@ -2978,15 +3163,18 @@ class ReportStoreTest(WebMockTestCase): self.assertEqual(3, len(report_store1.logs)) self.assertEqual(["1", "2", "3"], list(map(lambda x: x["stage"], report_store1.logs))) + self.assertEqual(6, len(report_store1.print_logs)) def test_print_log(self): report_store = market.ReportStore(self.m) with self.subTest(verbose=True),\ + mock.patch.object(store, "datetime") as time_mock,\ mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock: + time_mock.now.return_value = datetime.datetime(2018, 2, 25, 2, 20, 10) report_store.set_verbose(True) report_store.print_log("Coucou") report_store.print_log(portfolio.Amount("BTC", 1)) - self.assertEqual(stdout_mock.getvalue(), "Coucou\n1.00000000 BTC\n") + self.assertEqual(stdout_mock.getvalue(), "2018-02-25 02:20:10: Coucou\n2018-02-25 02:20:10: 1.00000000 BTC\n") with self.subTest(verbose=False),\ mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock: @@ -2995,6 +3183,14 @@ class ReportStoreTest(WebMockTestCase): report_store.print_log(portfolio.Amount("BTC", 1)) self.assertEqual(stdout_mock.getvalue(), "") + def test_default_json_serial(self): + report_store = market.ReportStore(self.m) + + self.assertEqual("2018-02-24T00:00:00", + report_store.default_json_serial(portfolio.datetime(2018, 2, 24))) + self.assertEqual("1.00000000 BTC", + report_store.default_json_serial(portfolio.Amount("BTC", 1))) + def test_to_json(self): report_store = market.ReportStore(self.m) report_store.logs.append({"foo": "bar"}) @@ -3004,6 +3200,20 @@ class ReportStoreTest(WebMockTestCase): report_store.logs.append({"amount": portfolio.Amount("BTC", 1)}) self.assertEqual('[\n {\n "foo": "bar"\n },\n {\n "date": "2018-02-24T00:00:00"\n },\n {\n "amount": "1.00000000 BTC"\n }\n]', report_store.to_json()) + def test_to_json_array(self): + report_store = market.ReportStore(self.m) + report_store.logs.append({ + "date": "date1", "type": "type1", "foo": "bar", "bla": "bla" + }) + report_store.logs.append({ + "date": "date2", "type": "type2", "foo": "bar", "bla": "bla" + }) + logs = list(report_store.to_json_array()) + + self.assertEqual(2, len(logs)) + 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]) + @mock.patch.object(market.ReportStore, "print_log") @mock.patch.object(market.ReportStore, "add_log") def test_log_stage(self, add_log, print_log): @@ -3497,7 +3707,7 @@ class MainTest(WebMockTestCase): mock.patch("main.parse_config") as main_parse_config: with self.subTest(debug=False): main_parse_config.return_value = ["pg_config", "report_path"] - main_fetch_markets.return_value = [({"key": "market_config"},)] + main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)] m = main.get_user_market("config_path.ini", 1) self.assertIsInstance(m, market.Market) @@ -3505,7 +3715,7 @@ class MainTest(WebMockTestCase): with self.subTest(debug=True): main_parse_config.return_value = ["pg_config", "report_path"] - main_fetch_markets.return_value = [({"key": "market_config"},)] + main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)] m = main.get_user_market("config_path.ini", 1, debug=True) self.assertIsInstance(m, market.Market) @@ -3524,16 +3734,16 @@ class MainTest(WebMockTestCase): args_mock.after = "after" self.assertEqual("", stdout_mock.getvalue()) - main.process("config", 1, "report_path", args_mock) + main.process("config", 3, 1, args_mock, "report_path", "pg_config") market_mock.from_config.assert_has_calls([ - mock.call("config", debug="debug", user_id=1, report_path="report_path"), + mock.call("config", args_mock, pg_config="pg_config", market_id=3, user_id=1, report_path="report_path"), mock.call().process("action", before="before", after="after"), ]) with self.subTest(exception=True): market_mock.from_config.side_effect = Exception("boo") - main.process("config", 1, "report_path", args_mock) + main.process(3, "config", 1, "report_path", args_mock, "pg_config") self.assertEqual("Exception: boo\n", stdout_mock.getvalue()) def test_main(self): @@ -3551,7 +3761,7 @@ class MainTest(WebMockTestCase): parse_config.return_value = ["pg_config", "report_path"] - fetch_markets.return_value = [["config1", 1], ["config2", 2]] + fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] main.main(["Foo", "Bar"]) @@ -3561,8 +3771,8 @@ class MainTest(WebMockTestCase): self.assertEqual(2, process.call_count) process.assert_has_calls([ - mock.call("config1", 1, "report_path", args_mock), - mock.call("config2", 2, "report_path", args_mock), + mock.call("config1", 3, 1, args_mock, "report_path", "pg_config"), + mock.call("config2", 1, 2, args_mock, "report_path", "pg_config"), ]) with self.subTest(parallel=True): with mock.patch("main.parse_args") as parse_args,\ @@ -3579,7 +3789,7 @@ class MainTest(WebMockTestCase): parse_config.return_value = ["pg_config", "report_path"] - fetch_markets.return_value = [["config1", 1], ["config2", 2]] + fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] main.main(["Foo", "Bar"]) @@ -3591,9 +3801,9 @@ class MainTest(WebMockTestCase): self.assertEqual(2, process.call_count) process.assert_has_calls([ mock.call.__bool__(), - mock.call("config1", 1, "report_path", args_mock), + mock.call("config1", 3, 1, args_mock, "report_path", "pg_config"), mock.call.__bool__(), - mock.call("config2", 2, "report_path", args_mock), + mock.call("config2", 1, 2, args_mock, "report_path", "pg_config"), ]) @mock.patch.object(main.sys, "exit") @@ -3679,7 +3889,7 @@ class MainTest(WebMockTestCase): rows = list(main.fetch_markets({"foo": "bar"}, None)) psycopg2.connect.assert_called_once_with(foo="bar") - cursor_mock.execute.assert_called_once_with("SELECT config,user_id FROM market_configs") + cursor_mock.execute.assert_called_once_with("SELECT id,config,user_id FROM market_configs") self.assertEqual(["row_1", "row_2"], rows) @@ -3689,7 +3899,7 @@ class MainTest(WebMockTestCase): rows = list(main.fetch_markets({"foo": "bar"}, 1)) psycopg2.connect.assert_called_once_with(foo="bar") - cursor_mock.execute.assert_called_once_with("SELECT config,user_id FROM market_configs WHERE user_id = %s", 1) + cursor_mock.execute.assert_called_once_with("SELECT id,config,user_id FROM market_configs WHERE user_id = %s", 1) self.assertEqual(["row_1", "row_2"], rows) @@ -3753,7 +3963,7 @@ class ProcessorTest(WebMockTestCase): def test_method_arguments(self): ccxt = mock.Mock(spec=market.ccxt.poloniexE) - m = market.Market(ccxt) + m = market.Market(ccxt, self.market_args()) processor = market.Processor(m)