def test_single_layout(self, app, mocker: MockerFixture): app._layout_mode = LayoutMode.single assert app._layout_mode == LayoutMode.single spy = mocker.spy(VSplit, "__init__") layout = app.layout assert spy.call_count == 0 assert len(layout.container.content.children) == 3
def test_border(self, app, mocker: MockerFixture): spy = mocker.spy(Frame, "__init__") app.layout spy.assert_not_called() app._border = True app.layout spy.assert_called_once()
def test_vertical_layout(self, app, mocker: MockerFixture): assert app._layout_mode == LayoutMode.vertical spy = mocker.spy(VSplit, "__init__") layout = app.layout assert isinstance(layout.container, FloatContainer) == True assert spy.call_count == 1 assert len(layout.container.content.children) == 2
async def test_load_pane_date(app, mocker: MockerFixture): class Stub: async def load_data(self): pass spy = mocker.spy(App, "redraw") await app._load_pane_data(Stub()) spy.assert_called_once()
def noninteractive(mocker: MockerFixture) -> MagicMock: loop = asyncio.get_event_loop() # The Click.testing.CliRunner replaces `sys.stdin` with something that is # notcompatible with `add_reader` so we just mock the call. mocker.patch.object(loop, 'add_reader', lambda *_: None) mocker.patch.object(loop, 'remove_reader', lambda *_: None) mock: MagicMock = mocker.MagicMock(name='Foremon._run') mocker.patch('foremon.app.Foremon._run', new=mock) spy = mocker.spy(Foremon, 'run_forever') return spy
async def test_render_task(app, mocker: MockerFixture): assert app._kb.activated == False spy = mocker.spy(History, "read") mocker.patch.object(App, "pane_focus") mocker.patch.object(App, "layout_switch") mocker.patch.object(App, "_load_pane_data") app._no_history = True await app._render_task() assert app._kb.activated == True spy.assert_not_called() app._no_history = False await app._render_task() spy.assert_called_once()
def test_get_integration( fake_controller: Controller, mocker: MockerFixture, integration_input: Union[str, Dict[str, Any]], integration_name_expected: str, args_expected: Dict[str, Any], error_expected: bool, ): get_integrations_spy = mocker.spy(integration_module, "get_integrations") with wrap_exetuction(error_expected=error_expected, exception=ValueError): integration = fake_controller.get_integration(integration_input) if not error_expected: get_integrations_spy.assert_called_once_with(fake_controller, args_expected) assert integration.name == integration_name_expected
async def test_initialize( sut_before_init: Controller, mocker: MockerFixture, controller_input: Union[str, List[str]], actions_input: List[str], included_actions: Optional[List[str]], excluded_actions: Optional[List[str]], actions_output: List[str], error_expected: bool, ): actions = {action: action for action in actions_input} predefined_actions = {action: lambda: None for action in actions_input} sut_before_init.args["controller"] = controller_input integration_mock = IntegrationMock(INTEGRATION_TEST_NAME, sut_before_init, mocker) mocker.patch.object(sut_before_init, "get_integration", return_value=integration_mock) if included_actions: sut_before_init.args["actions"] = included_actions if excluded_actions: sut_before_init.args["excluded_actions"] = excluded_actions mocker.patch.object(sut_before_init, "get_default_actions_mapping", return_value=actions) mocker.patch.object( sut_before_init, "get_predefined_actions_mapping", return_value=predefined_actions, ) get_default_actions_mapping = mocker.spy(sut_before_init, "get_default_actions_mapping") # SUT with wrap_exetuction(error_expected=error_expected, exception=ValueError): await sut_before_init.initialize() # Checks if not error_expected: get_default_actions_mapping.assert_called_once() for controller_id in controller_input: integration_mock.listen_changes.assert_any_call(controller_id) assert integration_mock.listen_changes.call_count == len( controller_input) assert list(sut_before_init.actions_mapping.keys()) == actions_output
def test_redraw(app, mocker: MockerFixture): spy = mocker.spy(Application, "invalidate") app.redraw() spy.assert_called_once()
def test_run_web_scraper_pavilon_animals(betamax_session: requests.Session, mocker: MockerFixture): """ Test the whole workflow of Zoo Prague lexicon web scraper. Tests animals that are in zoo houses, not in animal pens. It uses a test DBHandler which uses local filesystem. Function :func:`scrapers.zoo_scraper.get_animal_urls` is mocked since it returns too many animals. Args: betamax_session (requests.Session): [description] mocker (MockerFixture): A fixture of pytest_mock. """ sleep_time: float = 5 get_animal_id_spy = mocker.spy(zoo_scraper, 'get_animal_id') # Patch the get_animal_urls function urls: list[str] = [ "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=27-agama-stepni&start=27", # Pavilon šelem a plazů "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=795-agama-zapadoafricka&start=795", # Afrika zblizka "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=140-chameleon-obrovsky&start=140", # Pavilon velkých želv "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=702-kakadu-palmovy&start=702", # Rákosův pavilon ] urls: list[ParseResult] = [urlparse(url) for url in urls] mocker.patch('scrapers.zoo_scraper.get_animal_urls', return_value=urls) # Patch time.sleep function ## Can't patch time.sleep by just always returning True because time.sleep is used in calls a lot by the system with times around 0.005. Mocking it that way caused CPU overheating ## The way this works is that the sleep_lambda is called and if argument is lower than sleep_time then original time.sleep function is executed unmocked_sleep = time.sleep sleep_lambda = lambda secs: True if (sleep_time - 2 <= secs <= sleep_time ) else unmocked_sleep(secs) mocker.patch('time.sleep', new=sleep_lambda) # Act # List of animal_pens results the method needs find_res: dict[str, list] = { 'zoo_parts': [{ "_id": 0, "name": "Pavilon šelem a plazů", 'is_building': True }, { "_id": 1, "name": "Afrika zblízka", 'is_building': True }, { "_id": 2, "name": "Pavilon velkých želv", 'is_building': True }, { "_id": 3, "name": "Rákosův pavilon", 'is_building': True }] } output: list[dict] = list() zoo_scraper.run_web_scraper(betamax_session, db_handler=BaseTestHandler(output, find_res), min_delay=sleep_time, collection_name="tmp") output: list[AnimalData] = [AnimalData(**d) for d in output] # Assert assert get_animal_id_spy.call_count == len(urls) assert len(output) == len(urls) assert all([len(animal.map_locations) == 1 for animal in output]) # Each animal has a map_location which is the same as its index in the output assert all([ animal.map_locations[0]['_id'] == index for index, animal in enumerate(output) ])
def test_run_web_scraper_basic(betamax_session: requests.Session, mocker: MockerFixture): """ Test the whole workflow of Zoo Prague lexicon web scraper. It uses a test DBHandler which uses local filesystem. Function :func:`scrapers.zoo_scraper.get_animal_urls` is mocked since it returns too many animals. Args: betamax_session (requests.Session): [description] mocker (MockerFixture): A fixture of pytest_mock. """ sleep_time: float = 5 get_animal_id_spy = mocker.spy(zoo_scraper, 'get_animal_id') # Patch the get_animal_urls function urls: list[str] = [ "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=320-zelva-obrovska&start=320", "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=39-zelva-ostnita&start=39", "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=321-zelva-pardali&start=321", "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=496-sova-palena&start=496", "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=643-tygr-ussurijsky&start=643", "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=306-tucnak-humboldtuv&start=306", "https://www.zoopraha.cz/zvirata-a-expozice/lexikon-zvirat?d=100-bezhrbi-velbloudi&start=100" ] urls: list[ParseResult] = [urlparse(url) for url in urls] mocker.patch('scrapers.zoo_scraper.get_animal_urls', return_value=urls) # Patch time.sleep function ## Can't patch time.sleep by just always returning True because time.sleep is used in calls a lot by the system with times around 0.005. Mocking it that way caused CPU overheating ## The way this works is that the sleep_lambda is called and if argument is lower than sleep_time then original time.sleep function is executed unmocked_sleep = time.sleep sleep_lambda = lambda secs: True if (sleep_time - 2 <= secs <= sleep_time ) else unmocked_sleep(secs) mocker.patch('time.sleep', new=sleep_lambda) # Act # List of animal_pens results the method needs find_res: dict[str, list] = { 'animal_pens': [{ "_id": 0, "name": "želvy", "singular_names": ["želva"] }, { "_id": 1, "name": "želvy obrovské", "singular_names": ["želva obrovská"] }, { "_id": 2, "name": "sovy", "singular_names": ["sova"] }, { "_id": 3, "name": "sovy", "singular_names": ["sova"] }, { "_id": 4, "name": "tygři, tučňáci", "singular_names": ["tygr", "tučňák"] }] } output: list[dict] = list() zoo_scraper.run_web_scraper(betamax_session, db_handler=BaseTestHandler(output, find_res), min_delay=sleep_time, collection_name="tmp") output: list[AnimalData] = [AnimalData(**d) for d in output] # Assert assert get_animal_id_spy.call_count == len(urls) assert len(output) == len(urls) zelva_obrovska: AnimalData = next( filter(lambda animal: 'želva obrovská' in animal.name.lower(), output), None) assert compare_lists([loc['_id'] for loc in zelva_obrovska.map_locations], [1]) zelva_ostni: AnimalData = next( filter(lambda animal: 'želva ostnitá' in animal.name.lower(), output), None) assert compare_lists([loc['_id'] for loc in zelva_ostni.map_locations], [0]) zelva_pardali: AnimalData = next( filter(lambda animal: 'želva pardálí' in animal.name.lower(), output), None) assert compare_lists([loc['_id'] for loc in zelva_pardali.map_locations], [0]) sova: AnimalData = next( filter(lambda animal: 'sova' in animal.name.lower(), output), None) assert compare_lists([loc['_id'] for loc in sova.map_locations], [2, 3]) tygr: AnimalData = next( filter(lambda animal: 'tygr' in animal.name.lower(), output), None) assert tygr.is_currently_available assert tygr.sizes == '' assert tygr.reproduction == '' assert tygr.about_placement_in_zoo_prague is None assert tygr.location_in_zoo is None assert tygr.food_detail is None assert compare_lists([loc['_id'] for loc in tygr.map_locations], [4]) alpaka: AnimalData = next( filter(lambda animal: 'alpaka' in animal.name.lower(), output), None) assert not alpaka.is_currently_available assert len(alpaka.map_locations) == 0 pass