async def test_ticker_traded(mocker): """Для торгуемого тикера должны обновляться котировки и дивиденды.""" dispatcher = handlers.EventHandlersDispatcher() event = events.TickerTraded( "ticker", "ISIN", "M1", date(2020, 12, 22), pd.DataFrame([1]), ) fake_repo = mocker.Mock() fake_load_by_id_and_handle_event = mocker.patch.object( handlers, "_load_by_id_and_handle_event", side_effect=[["aa"], ["bb", "cc"]], ) assert await dispatcher.handle_event(event, fake_repo) == ["aa", "bb", "cc"] fake_load_by_id_and_handle_event.assert_has_calls([ mocker.call(fake_repo, base.create_id(ports.QUOTES, "ticker"), event), mocker.call(fake_repo, base.create_id(ports.DIVIDENDS, "ticker"), event), ], )
def test_update_cond(df, event_date, update): """Индекс обновляется при отсутствии и по окончании месяца.""" event = events.TradingDayEnded(event_date) id_ = base.create_id(ports.CPI) table = cpi.CPI(id_, df=df) assert table._update_cond(event) == update
async def test_prepare_df(mocker): """Вызов по подготовке DataFrame переадресуется шлюзу.""" id_ = base.create_id(ports.CPI) table = cpi.CPI(id_) fake_gateway = mocker.AsyncMock() table._gateway = fake_gateway assert await table._prepare_df("") == fake_gateway.return_value
async def index_calculated( self, event: events.IndexCalculated, repo: AnyTableRepo, ) -> list[domain.AbstractEvent]: """Обновляет таблицу с котировками индексов.""" table_id = base.create_id(ports.INDEX, event.ticker) return await _load_by_id_and_handle_event(repo, table_id, event)
async def app_started( self, event: events.DateCheckRequired, repo: AnyTableRepo, ) -> list[domain.AbstractEvent]: """Обновляет таблицу с торговыми днями.""" table_id = base.create_id(ports.TRADING_DATES) return await _load_by_id_and_handle_event(repo, table_id, event)
async def usd_traded( self, event: events.USDUpdated, repo: AnyTableRepo, ) -> list[domain.AbstractEvent]: """Запускает обновления перечня торгуемых бумаг.""" table_id = base.create_id(ports.SECURITIES) return await _load_by_id_and_handle_event(repo, table_id, event)
def test_new_events(): """Не возвращает новых событий.""" id_ = base.create_id(ports.CPI) table = cpi.CPI(id_) new_events = table._new_events("") assert isinstance(new_events, list) assert not new_events
def test_table_creation(table_factory, mocker): """Создание таблицы.""" fake_df = mocker.Mock() fake_timestamp = mocker.Mock() mongo_dict = {"df": fake_df, "timestamp": fake_timestamp} id_ = base.create_id("group1") table_factory(id_, mongo_dict) table_factory._types_mapping["group1"].assert_called_once_with(id_, fake_df, fake_timestamp)
async def _query( self, group: str, name: str, ) -> pd.DataFrame: """Выполняет асинхронный запрос.""" id_ = base.create_id(group, name) doc = await self._mapper.get_doc(id_) if (df_data := doc.get("data")) is None: raise NoDFError(group, name)
def test_validate_new_df(mocker): """Осуществляется проверка на уникальность и согласованность данных.""" mocker.patch.object(base, "check_unique_increasing_index") mocker.patch.object(base, "check_dfs_mismatch") id_ = base.create_id(ports.CPI) table = cpi.CPI(id_) table._validate_new_df(mocker.sentinel) base.check_unique_increasing_index.assert_called_once_with(mocker.sentinel) base.check_dfs_mismatch.assert_called_once_with(id_, None, mocker.sentinel)
async def ticker_traded( self, event: events.TickerTraded, repo: AnyTableRepo, ) -> list[domain.AbstractEvent]: """Обновляет таблицы с котировками и дивидендами.""" table_groups = [ports.QUOTES, ports.DIVIDENDS] table_ids = [ base.create_id(group, event.ticker) for group in table_groups ] aws = [ _load_by_id_and_handle_event(repo, id_, event) for id_ in table_ids ] return list(itertools.chain.from_iterable(await asyncio.gather(*aws)))
async def update_div( self, event: events.UpdateDivCommand, repo: AnyTableRepo, ) -> list[domain.AbstractEvent]: """Обновляет таблицы с дивидендами.""" usd = await repo(base.create_id(ports.USD)) securities = await repo(base.create_id(ports.SECURITIES)) enriched_event = dataclasses.replace( event, type_=securities.df.loc[event.ticker, col.TICKER_TYPE], usd=usd.df, ) div_id = base.create_id(ports.DIVIDENDS, event.ticker) div_ext_id = base.create_id(ports.DIV_EXT, event.ticker) return [ *await _load_by_id_and_handle_event(repo, div_id, enriched_event), *await _load_by_id_and_handle_event(repo, div_ext_id, enriched_event), ]
async def test_usd_traded(mocker): """После загрузки курса началось обновление данных о торгуемых бумагах.""" dispatcher = handlers.EventHandlersDispatcher() event = events.USDUpdated(date=date(2021, 2, 5), usd=pd.DataFrame) fake_repo = mocker.Mock() fake_loader_and_handler = mocker.patch.object( handlers, "_load_by_id_and_handle_event") assert await dispatcher.handle_event( event, fake_repo) is fake_loader_and_handler.return_value fake_loader_and_handler.assert_called_once_with( fake_repo, base.create_id(ports.SECURITIES), event, )
async def test_handle_app_started(mocker): """Обработка события начала приложения обновляет таблицу с торговыми датами.""" dispatcher = handlers.EventHandlersDispatcher() event = events.DateCheckRequired() fake_repo = mocker.Mock() fake_loader_and_handler = mocker.patch.object( handlers, "_load_by_id_and_handle_event") assert await dispatcher.handle_event( event, fake_repo) is fake_loader_and_handler.return_value fake_loader_and_handler.assert_called_once_with( fake_repo, base.create_id(ports.TRADING_DATES), event, )
async def test_index_calculated(mocker): """Требуется обновить таблицу с индексом.""" dispatcher = handlers.EventHandlersDispatcher() event = events.IndexCalculated("IND1", date(2020, 12, 22)) fake_repo = mocker.Mock() fake_loader_and_handler = mocker.patch.object( handlers, "_load_by_id_and_handle_event") assert await dispatcher.handle_event( event, fake_repo) is fake_loader_and_handler.return_value fake_loader_and_handler.assert_called_once_with( fake_repo, base.create_id(ports.INDEX, "IND1"), event, )
async def trading_day_ended( self, event: events.TradingDayEnded, repo: AnyTableRepo, ) -> list[domain.AbstractEvent]: """Запускает обновление необходимых таблиц в конце торгового дня и создает дочерние события.""" table_groups = [ports.CPI, ports.DIV_NEW, ports.USD] table_ids = [base.create_id(group) for group in table_groups] aws = [ _load_by_id_and_handle_event(repo, id_, event) for id_ in table_ids ] return [ events.IndexCalculated("MCFTRR", event.date), events.IndexCalculated("IMOEX", event.date), events.IndexCalculated("RVI", event.date), *itertools.chain.from_iterable(await asyncio.gather(*aws)), ]
def create_smart_lab_table(): """Создает пустую таблицу дивидендов со SmartLab для тестов.""" id_ = base.create_id(ports.DIV_NEW) return dividends.DivNew(id_)
def create_div_ext_table(): """Создает пустую таблицу дивидендов внешних дивидендов для тестов.""" id_ = base.create_id(ports.DIV_EXT) return dividends.DivExt(id_)
def test_create_id(): """Проверка создание ID.""" assert base.create_id("f", "g") == domain.ID(base.PACKAGE, "f", "g")
def test_create_id_no_name(): """Проверка создание ID без указания названия.""" assert base.create_id("ff") == domain.ID(base.PACKAGE, "ff", "ff")
def test_wrong_id(table_factory): """Исключение при неправильной группе в ID.""" id_ = base.create_id("group2") with pytest.raises(base.TableWrongIDError): table_factory(id_, {})
def create_table(): """Создает пустую таблицу для тестов.""" id_ = base.create_id(ports.QUOTES, "TICKER") return quotes.Quotes(id_)
def create_table(): """Создает пустую таблицу для тестов.""" id_ = base.create_id(ports.USD, ports.USD) return usd.USD(id_)
def create_table(): """Создает пустую таблицу для тестов.""" id_ = base.create_id(ports.INDEX, "SOME_INDEX") return indexes.Indexes(id_)
def create_div_table(): """Создает пустую таблицу дивидендов для тестов.""" id_ = base.create_id(ports.DIVIDENDS) return dividends.Dividends(id_)
def create_table(): """Создает пустую таблицу для тестов.""" id_ = base.create_id(ports.SECURITIES) return securities.Securities(id_)
def make_table(): """Создает пустую таблицу.""" id_ = base.create_id(ports.TRADING_DATES) return trading_dates.TradingDates(id_)