Implemented tests for CapturingTask. A few mock classes where needed.

This commit is contained in:
pablo 2021-01-03 20:06:28 +01:00
parent 007f458cd5
commit cf4ce06b57
3 changed files with 267 additions and 236 deletions

170
tests/capturer_test.py Normal file
View file

@ -0,0 +1,170 @@
from tests.mock_classes import (
MockCapturingInterface,
MockParsingFlow,
MockUrlAttackReturnsSuccess,
MockUrlAttackReturnsFailure,
)
from capturer.capturer import CapturingTask
def test_capturing_task_successful_task_flow():
the_task_parameters = dict()
the_task_parameters["uuid"] = "test_uuid"
the_task_parameters["ad_url"] = "test_url"
the_task_parameters["fk_uuid_exploring"] = "test_exploring_uuid"
the_task_parameters["status"] = "Pending"
fake_resulting_field_values = {
"a_field": {"a_value": 1},
"another_field": {"another_value": 2},
}
mock_parsing_flow = MockParsingFlow(
mock_all_found_fields_are_valid=True,
mock_all_non_optional_fields_were_found=True,
mock_field_values_to_return=fake_resulting_field_values,
)
mock_capturing_interface = MockCapturingInterface()
task = CapturingTask(
task_parameters=the_task_parameters,
capturing_interface=mock_capturing_interface,
new_parsing_flow=mock_parsing_flow,
url_acquisition_object=MockUrlAttackReturnsSuccess,
dead_ad_checker=lambda: False,
)
task.capture()
final_data = task.get_ad_data()
assert (
len(mock_capturing_interface.tasks) == 1
and mock_capturing_interface.tasks[the_task_parameters["uuid"]][-1].status
== "Data ready"
and fake_resulting_field_values == final_data
)
def test_capturing_task_dead_ad_task_flow():
the_task_parameters = dict()
the_task_parameters["uuid"] = "test_uuid"
the_task_parameters["ad_url"] = "test_url"
the_task_parameters["fk_uuid_exploring"] = "test_exploring_uuid"
the_task_parameters["status"] = "Pending"
mock_parsing_flow = MockParsingFlow(
mock_all_found_fields_are_valid=False,
issues_to_return={"some_field": {"valid": False}},
)
mock_capturing_interface = MockCapturingInterface()
task = CapturingTask(
task_parameters=the_task_parameters,
capturing_interface=mock_capturing_interface,
new_parsing_flow=mock_parsing_flow,
url_acquisition_object=MockUrlAttackReturnsFailure,
dead_ad_checker=lambda x: True,
)
task.capture()
assert (
len(mock_capturing_interface.tasks) == 1
and mock_capturing_interface.tasks[the_task_parameters["uuid"]][-1].status
== "Dead ad"
)
def test_capturing_task_invalid_fields_surrender_flow():
the_task_parameters = dict()
the_task_parameters["uuid"] = "test_uuid"
the_task_parameters["ad_url"] = "test_url"
the_task_parameters["fk_uuid_exploring"] = "test_exploring_uuid"
the_task_parameters["status"] = "Pending"
mock_parsing_flow = MockParsingFlow(
mock_all_found_fields_are_valid=False,
issues_to_return={"some_field": {"valid": False}},
)
mock_capturing_interface = MockCapturingInterface()
task = CapturingTask(
task_parameters=the_task_parameters,
capturing_interface=mock_capturing_interface,
new_parsing_flow=mock_parsing_flow,
url_acquisition_object=MockUrlAttackReturnsSuccess,
dead_ad_checker=lambda: False,
)
task.capture()
assert (
len(mock_capturing_interface.tasks) == 1
and mock_capturing_interface.tasks[the_task_parameters["uuid"]][-1].status
== "Invalid value fields"
)
def test_capturing_task_missing_fields_surrender_flow():
the_task_parameters = dict()
the_task_parameters["uuid"] = "test_uuid"
the_task_parameters["ad_url"] = "test_url"
the_task_parameters["fk_uuid_exploring"] = "test_exploring_uuid"
the_task_parameters["status"] = "Pending"
mock_parsing_flow = MockParsingFlow(
mock_all_non_optional_fields_were_found=False,
issues_to_return={"some_field": {"found": False}},
)
mock_capturing_interface = MockCapturingInterface()
task = CapturingTask(
task_parameters=the_task_parameters,
capturing_interface=mock_capturing_interface,
new_parsing_flow=mock_parsing_flow,
url_acquisition_object=MockUrlAttackReturnsSuccess,
dead_ad_checker=lambda: False,
)
task.capture()
assert (
len(mock_capturing_interface.tasks) == 1
and mock_capturing_interface.tasks[the_task_parameters["uuid"]][-1].status
== "Fields missing"
)
def test_capturing_task_unexpected_issue_surrender_flow():
the_task_parameters = dict()
the_task_parameters["uuid"] = "test_uuid"
the_task_parameters["ad_url"] = "test_url"
the_task_parameters["fk_uuid_exploring"] = "test_exploring_uuid"
the_task_parameters["status"] = "Pending"
mock_parsing_flow = MockParsingFlow()
mock_capturing_interface = MockCapturingInterface()
CapturingTask.sleep_time_failed_request = 0 # Override quite long sleep time
task = CapturingTask(
task_parameters=the_task_parameters,
capturing_interface=mock_capturing_interface,
new_parsing_flow=mock_parsing_flow,
url_acquisition_object=MockUrlAttackReturnsFailure,
dead_ad_checker=lambda x: False,
)
task.capture()
assert (
len(mock_capturing_interface.tasks) == 1
and mock_capturing_interface.tasks[the_task_parameters["uuid"]][-1].status
== "Surrender"
)

File diff suppressed because one or more lines are too long

97
tests/mock_classes.py Normal file
View file

@ -0,0 +1,97 @@
from collections import namedtuple
from typing import Dict
from bs4 import BeautifulSoup
from db_layer.capturing_tasks_interface import CapturingTasksInterface
from core.parsing_utils import ParsingFlow
from core.scrapping_utils import UrlAttack
class MockCapturingInterface(CapturingTasksInterface):
task_state_record = namedtuple(
"TaskStateRecord", ["uuid", "uuid_exploring", "status", "ad_url"]
)
def __init__(self):
self.tasks = {}
def update_capturing_task(self, uuid, uuid_exploring, status, ad_url):
if uuid not in self.tasks:
self.tasks[uuid] = []
self.tasks[uuid].append(
MockCapturingInterface.task_state_record(
uuid=uuid, uuid_exploring=uuid_exploring, status=status, ad_url=ad_url
)
)
class MockParsingFlow(ParsingFlow):
def __init__(
self,
issues_to_return: Dict[str, dict] = None,
mock_all_found_fields_are_valid: bool = True,
mock_all_non_optional_fields_were_found: bool = True,
mock_field_values_to_return: Dict[str, dict] = None,
):
args_with_empty_dict_as_default = [
issues_to_return,
mock_field_values_to_return,
]
for arg in args_with_empty_dict_as_default:
if arg is None:
arg = dict()
self._issues = issues_to_return
self._mock_all_found_fields_are_valid = mock_all_found_fields_are_valid
self._mock_field_values_to_return = mock_field_values_to_return
self._mock_all_non_optional_fields_were_found = (
mock_all_non_optional_fields_were_found
)
def execute_flow(self, soup: BeautifulSoup) -> None:
pass
@property
def issues(self) -> Dict[str, dict]:
return self._issues
@property
def all_found_fields_are_valid(self) -> bool:
return self._mock_all_found_fields_are_valid
@property
def all_non_optional_fields_were_found(self) -> bool:
return self._mock_all_non_optional_fields_were_found
@property
def field_values(self) -> Dict:
return self._mock_field_values_to_return
class MockUrlAttack(UrlAttack):
def __init__(self, url: str) -> None:
super().__init__(url=url)
def get_text(self) -> str:
return "<html>this_is_a_fake_html_string</html>"
class MockUrlAttackReturnsSuccess(MockUrlAttack):
def __init__(self, url: str) -> None:
super().__init__(url=url)
def attack(self) -> None:
self.success = True
self.has_been_attacked = True
class MockUrlAttackReturnsFailure(MockUrlAttack):
def __init__(self, url: str) -> None:
super().__init__(url=url)
def attack(self) -> None:
self.success = False
self.has_been_attacked = True