From 84b222dffbccf16e8d4ccbb777dc710326c46b07 Mon Sep 17 00:00:00 2001 From: Sandro Castillo Date: Thu, 28 Oct 2021 17:12:32 -0500 Subject: [PATCH 1/3] fix: TT-365 resolve comments --- .../_activities/_create_activity.py | 73 ++++++++++++++----- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/V2/time_entries/_application/_activities/_create_activity.py b/V2/time_entries/_application/_activities/_create_activity.py index 88bb8181..e1e67705 100644 --- a/V2/time_entries/_application/_activities/_create_activity.py +++ b/V2/time_entries/_application/_activities/_create_activity.py @@ -1,45 +1,82 @@ -from time_entries._infrastructure import ActivitiesJsonDao -from time_entries._domain import ActivityService, _use_cases, Activity - -import azure.functions as func import json import logging import dataclasses +import typing +import azure.functions as func + +from time_entries._infrastructure import ActivitiesJsonDao +from time_entries._domain import ActivityService, _use_cases, Activity -JSON_PATH = ( +_JSON_PATH = ( 'time_entries/_infrastructure/_data_persistence/activities_data.json' ) - def create_activity(req: func.HttpRequest) -> func.HttpResponse: logging.info( 'Python HTTP trigger function processed a request to create an activity.' ) activity_data = req.get_json() - status_code = 200 - if _validate_activity(activity_data): - response = _create_activity(activity_data) - else: - status_code = 404 - response = b'Not possible to create activity, attributes are not correct ' + # status_code = 200 + # if _validate_activity(activity_data): + # response = _create_activity(activity_data) + # else: + # status_code = 404 + # response = b'Not possible to create activity, attributes are not correct ' + + validation_errors = _validate_activity(activity_data) + if validation_errors: + return func.HttpResponse( + body=validation_errors, status_code=400, mimetype="application/json" + ) + + activity_to_create = Activity( + id=None, + name=activity_data['name'], + description=activity_data['description'], + status_code=activity_data['status_code'], + deleted=activity_data['delete'], + tenant_id=activity_data['tenant_id'] + ) + # created_activity = use_case.create_activity(activity_to_create) + created_activity = _create_activity(activity_to_create) + + if not created_activity: + return func.HttpResponse( + body={'error': 'activity could not be created'}, + status_code=500, + mimetype="application/json", + ) + return func.HttpResponse( - body=response, status_code=status_code, mimetype="application/json" + body=json.dumps(created_activity.__dict__), + status_code=201, + mimetype="application/json" ) def _create_activity(activity_data: dict) -> str: activity_use_case = _use_cases.CreateActivityUseCase( - _create_activity_service(JSON_PATH) + _create_activity_service(_JSON_PATH) ) activity = activity_use_case.create_activity(activity_data) return json.dumps(activity.__dict__) if activity else b'Not Found' -def _validate_activity(activity_data: dict) -> bool: - activity_keys = [field.name for field in dataclasses.fields(Activity)] - new_activity_keys = list(activity_data.keys()) - return all(map(lambda key: key in activity_keys, new_activity_keys)) and len(activity_keys) == len(new_activity_keys) +def _validate_activity(activity_data: dict) -> typing.List[str]: +# def _validate_activity(activity_data: dict) -> bool: + + activity_fields = [field.name for field in dataclasses.fields(Activity)] + + # activity_keys = [field.name for field in dataclasses.fields(Activity)] + # new_activity_keys = list(activity_data.keys()) + # return all(map(lambda key: key in activity_keys, new_activity_keys)) and len(activity_keys) == len(new_activity_keys) + + missing_keys = [field for field in activity_fields if field not in activity_data] + return [ + f'The {missing_key} key is missing in the input data' + for missing_key in missing_keys + ] def _create_activity_service(path: str): activity_json = ActivitiesJsonDao(path) From 76a35bff7306600c7ab97bec4e2bd1ae82a2b3d4 Mon Sep 17 00:00:00 2001 From: Daniela Garcia Date: Fri, 29 Oct 2021 09:02:33 -0500 Subject: [PATCH 2/3] fix: TT-365 Resolve comments --- .../azure/activity_azure_endpoints_test.py | 12 ++-- .../_activities/_create_activity.py | 55 ++++++------------- .../_data_persistence/_activities_json_dao.py | 1 + 3 files changed, 23 insertions(+), 45 deletions(-) diff --git a/V2/tests/api/azure/activity_azure_endpoints_test.py b/V2/tests/api/azure/activity_azure_endpoints_test.py index 98d853f1..049c7a82 100644 --- a/V2/tests/api/azure/activity_azure_endpoints_test.py +++ b/V2/tests/api/azure/activity_azure_endpoints_test.py @@ -85,18 +85,18 @@ def test__activity_azure_endpoint__creates_an_activity__when_activity_has_all_at create_temp_activities, ): activities_json, tmp_directory = create_temp_activities - activities._create_activity.JSON_PATH = tmp_directory + activities._create_activity._JSON_PATH = tmp_directory - activity_body = {'id': Faker().uuid4(), 'name': Faker().user_name(), 'description': Faker().sentence(),'deleted': Faker().uuid4() ,'status': 'active', 'tenant_id': Faker().uuid4()} + activity_body = {'id': None, 'name': Faker().user_name(), 'description': Faker().sentence(),'deleted': Faker().uuid4() ,'status': 'active', 'tenant_id': Faker().uuid4()} body = json.dumps(activity_body).encode("utf-8") req = func.HttpRequest( method='POST', body= body, - url='/api/activities/', + url=ACTIVITY_URL, ) - response = activities._create_activity.create_activity(req) + response = activities.create_activity(req) activitiy_json_data = response.get_body() - - assert response.status_code == 200 + print(response) + assert response.status_code == 201 assert activitiy_json_data == body \ No newline at end of file diff --git a/V2/time_entries/_application/_activities/_create_activity.py b/V2/time_entries/_application/_activities/_create_activity.py index e1e67705..b5175996 100644 --- a/V2/time_entries/_application/_activities/_create_activity.py +++ b/V2/time_entries/_application/_activities/_create_activity.py @@ -5,8 +5,8 @@ import azure.functions as func -from time_entries._infrastructure import ActivitiesJsonDao -from time_entries._domain import ActivityService, _use_cases, Activity +from ... import _domain +from ... import _infrastructure _JSON_PATH = ( 'time_entries/_infrastructure/_data_persistence/activities_data.json' @@ -14,72 +14,49 @@ def create_activity(req: func.HttpRequest) -> func.HttpResponse: + activity_dao = _infrastructure.ActivitiesJsonDao(_JSON_PATH) + activity_service = _domain.ActivityService(activity_dao) + use_case = _domain._use_cases.CreateActivityUseCase(activity_service) logging.info( 'Python HTTP trigger function processed a request to create an activity.' ) activity_data = req.get_json() - # status_code = 200 - # if _validate_activity(activity_data): - # response = _create_activity(activity_data) - # else: - # status_code = 404 - # response = b'Not possible to create activity, attributes are not correct ' - + print(activity_data) validation_errors = _validate_activity(activity_data) if validation_errors: return func.HttpResponse( body=validation_errors, status_code=400, mimetype="application/json" ) - - activity_to_create = Activity( - id=None, + activity_to_create = _domain.Activity( + id= None, name=activity_data['name'], description=activity_data['description'], - status_code=activity_data['status_code'], - deleted=activity_data['delete'], + status=activity_data['status'], + deleted=activity_data['deleted'], tenant_id=activity_data['tenant_id'] ) - # created_activity = use_case.create_activity(activity_to_create) - created_activity = _create_activity(activity_to_create) - - if not created_activity: + created_activity = use_case.create_activity(activity_to_create.__dict__) + print("actividad mapeada",activity_to_create) + print("use case",created_activity) + if not create_activity: return func.HttpResponse( body={'error': 'activity could not be created'}, status_code=500, mimetype="application/json", ) - return func.HttpResponse( body=json.dumps(created_activity.__dict__), status_code=201, mimetype="application/json" ) -def _create_activity(activity_data: dict) -> str: - activity_use_case = _use_cases.CreateActivityUseCase( - _create_activity_service(_JSON_PATH) - ) - activity = activity_use_case.create_activity(activity_data) - return json.dumps(activity.__dict__) if activity else b'Not Found' def _validate_activity(activity_data: dict) -> typing.List[str]: -# def _validate_activity(activity_data: dict) -> bool: - - activity_fields = [field.name for field in dataclasses.fields(Activity)] - - # activity_keys = [field.name for field in dataclasses.fields(Activity)] - # new_activity_keys = list(activity_data.keys()) - # return all(map(lambda key: key in activity_keys, new_activity_keys)) and len(activity_keys) == len(new_activity_keys) + activity_fields = [field.name for field in dataclasses.fields(_domain.Activity)] missing_keys = [field for field in activity_fields if field not in activity_data] return [ f'The {missing_key} key is missing in the input data' for missing_key in missing_keys - ] - -def _create_activity_service(path: str): - activity_json = ActivitiesJsonDao(path) - return ActivityService(activity_json) - - + ] \ No newline at end of file diff --git a/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py b/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py index ab8f5765..20eee36f 100644 --- a/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py +++ b/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py @@ -92,6 +92,7 @@ def create_activity(self, activity_data: dict) -> Activity: def __get_activities_from_file(self) -> typing.List[dict]: try: file = open(self.json_data_file_path) + print("") activities = json.load(file) file.close() From a993721c4b4366860351f30a3f8325da51248584 Mon Sep 17 00:00:00 2001 From: Daniela Garcia Date: Fri, 29 Oct 2021 09:15:17 -0500 Subject: [PATCH 3/3] solve requested changes --- .../azure/activity_azure_endpoints_test.py | 1 - .../daos/activities_sql_dao_test.py | 35 +++++++++++++++++++ .../_activities/_create_activity.py | 3 -- .../_data_persistence/_activities_json_dao.py | 1 - 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 V2/tests/integration/daos/activities_sql_dao_test.py diff --git a/V2/tests/api/azure/activity_azure_endpoints_test.py b/V2/tests/api/azure/activity_azure_endpoints_test.py index 049c7a82..05b22801 100644 --- a/V2/tests/api/azure/activity_azure_endpoints_test.py +++ b/V2/tests/api/azure/activity_azure_endpoints_test.py @@ -97,6 +97,5 @@ def test__activity_azure_endpoint__creates_an_activity__when_activity_has_all_at response = activities.create_activity(req) activitiy_json_data = response.get_body() - print(response) assert response.status_code == 201 assert activitiy_json_data == body \ No newline at end of file diff --git a/V2/tests/integration/daos/activities_sql_dao_test.py b/V2/tests/integration/daos/activities_sql_dao_test.py new file mode 100644 index 00000000..98d41d8f --- /dev/null +++ b/V2/tests/integration/daos/activities_sql_dao_test.py @@ -0,0 +1,35 @@ +from time_entries._infrastructure import ActivitiesJsonDao +from time_entries._domain import Activity +from sqlalchemy import create_engine, MetaData +import pytest +import typing + +@pytest.fixture(name='create_fake_activities') +def _create_fake_activities(mocker) -> typing.List[Activity]: + def _creator(activities): + read_data = json.dumps(activities) + mocker.patch('builtins.open', mocker.mock_open(read_data=read_data)) + return [Activity(**activity) for activity in activities] + + return _creator + +def test_get_by_id__returns_an_activity_dto__when_found_one_activity_that_matches_its_id(): + pass + +def test__get_by_id__returns_none__when_no_activity_matches_its_id(): + pass + +def test__get_all__returns_a_list_of_activity_dto_objects__when_one_or_more_activities_are_found(): + pass + +def test_get_all__returns_an_empty_list__when_doesnt_found_any_activities(): + pass + +def test_delete__returns_an_activity_with_inactive_status__when_an_activity_matching_its_id_is_found(): + pass + +def test_delete__returns_none__when_no_activity_matching_its_id_is_found(): + pass + + + diff --git a/V2/time_entries/_application/_activities/_create_activity.py b/V2/time_entries/_application/_activities/_create_activity.py index b5175996..29594e27 100644 --- a/V2/time_entries/_application/_activities/_create_activity.py +++ b/V2/time_entries/_application/_activities/_create_activity.py @@ -21,7 +21,6 @@ def create_activity(req: func.HttpRequest) -> func.HttpResponse: 'Python HTTP trigger function processed a request to create an activity.' ) activity_data = req.get_json() - print(activity_data) validation_errors = _validate_activity(activity_data) if validation_errors: return func.HttpResponse( @@ -37,8 +36,6 @@ def create_activity(req: func.HttpRequest) -> func.HttpResponse: ) created_activity = use_case.create_activity(activity_to_create.__dict__) - print("actividad mapeada",activity_to_create) - print("use case",created_activity) if not create_activity: return func.HttpResponse( body={'error': 'activity could not be created'}, diff --git a/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py b/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py index 20eee36f..ab8f5765 100644 --- a/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py +++ b/V2/time_entries/_infrastructure/_data_persistence/_activities_json_dao.py @@ -92,7 +92,6 @@ def create_activity(self, activity_data: dict) -> Activity: def __get_activities_from_file(self) -> typing.List[dict]: try: file = open(self.json_data_file_path) - print("") activities = json.load(file) file.close()