-
Notifications
You must be signed in to change notification settings - Fork 0
feat: TT-425 add time entries summary for a given range of dates #365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ | |
|
|
||
|
|
||
| TIME_ENTRY_URL = "/api/time-entries/" | ||
| TIME_ENTRY_SUMMARY_URL = "/api/time-entries/summary/" | ||
|
|
||
|
|
||
| @pytest.fixture(name='insert_time_entry') | ||
|
|
@@ -272,3 +273,79 @@ def test__get_latest_entries_azure_endpoint__returns_not_found__when_recieve_an_ | |
|
|
||
| assert response.status_code == HTTPStatus.NOT_FOUND | ||
| assert response.get_body().decode("utf-8") == ResponseEnums.NOT_FOUND.value | ||
|
|
||
|
|
||
| def test__time_entry_azure_endpoint__returns_the_summary( | ||
| test_db, time_entry_factory, insert_time_entry, activity_factory, insert_activity, insert_project | ||
| ): | ||
| inserted_project = insert_project() | ||
| inserted_activity = insert_activity(activity_factory(), test_db) | ||
| existent_time_entries = time_entry_factory(activity_id=inserted_activity.id, | ||
| owner_id=69, | ||
| start_date='11/10/2021', | ||
| end_date='11/11/2021', | ||
| project_id=inserted_project.id) | ||
| inserted_time_entries = insert_time_entry(existent_time_entries, test_db).__dict__ | ||
|
|
||
| req = func.HttpRequest( | ||
| method='GET', | ||
| body=None, | ||
| url=TIME_ENTRY_SUMMARY_URL, | ||
| params={'owner_id': inserted_time_entries['owner_id'], | ||
| 'start_date': '11/10/2021', | ||
| 'end_date': '11/11/2021'}, | ||
| ) | ||
|
|
||
| response = azure_time_entries.get_time_entries_summary(req) | ||
| time_entries_obtained = response.get_body().decode("utf-8") | ||
| assert response.status_code == HTTPStatus.OK.value | ||
| assert json.loads(time_entries_obtained) == [inserted_time_entries] | ||
|
|
||
|
|
||
| def test__time_entry_summary_azure_endpoint__returns_not_found_with_invalid_owner_id( | ||
| test_db, insert_activity, activity_factory | ||
| ): | ||
| insert_activity(activity_factory(), test_db) | ||
|
|
||
| request_params = { | ||
| "method": 'GET', | ||
| "body": None, | ||
| "url": TIME_ENTRY_SUMMARY_URL, | ||
| "params": {"owner_id": Faker().pyint()} | ||
| } | ||
|
|
||
| req_owner_id = func.HttpRequest(**request_params) | ||
| response_owner_id = azure_time_entries._get_time_entries_summary.get_time_entries_summary(req_owner_id) | ||
|
|
||
| assert response_owner_id.status_code == HTTPStatus.NOT_FOUND.value | ||
| assert response_owner_id.get_body().decode() == ResponseEnums.NOT_FOUND.value | ||
|
|
||
|
|
||
| def test__time_entry_summary_azure_endpoint__returns_invalid_date_format_with_invalid_date_format( | ||
| test_db, insert_activity, activity_factory | ||
| ): | ||
| insert_activity(activity_factory(), test_db) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the purpose of creating an activity if it is not used |
||
|
|
||
| wrong_date_format = "30/11/2021" | ||
| right_date_format = "11/30/2021" | ||
|
|
||
| request_params = { | ||
| "method": 'GET', | ||
| "body": None, | ||
| "url": TIME_ENTRY_SUMMARY_URL, | ||
| "params": {"owner_id": 1, "start_date": wrong_date_format, "end_date": right_date_format}, | ||
| } | ||
|
|
||
| req_owner_id = func.HttpRequest(**request_params) | ||
| response_owner_id = azure_time_entries._get_time_entries_summary.get_time_entries_summary(req_owner_id) | ||
|
|
||
| assert response_owner_id.status_code == HTTPStatus.NOT_FOUND.value | ||
| assert response_owner_id.get_body().decode() == ResponseEnums.INVALID_DATE_FORMAT.value | ||
|
|
||
| request_params["params"] = {"owner_id": 1, "start_date": right_date_format, "end_date": wrong_date_format} | ||
| req_start_date = func.HttpRequest(**request_params) | ||
|
|
||
| response_start_date = azure_time_entries._get_time_entries_summary.get_time_entries_summary(req_start_date) | ||
|
|
||
| assert response_start_date.status_code == HTTPStatus.NOT_FOUND.value | ||
| assert response_start_date.get_body().decode() == ResponseEnums.INVALID_DATE_FORMAT.value | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import json | ||
| from http import HTTPStatus | ||
| import datetime | ||
|
|
||
| import azure.functions as func | ||
|
|
||
| from ... import _domain | ||
| from ... import _infrastructure | ||
| from time_tracker._infrastructure import DB | ||
| from time_tracker.utils.enums import ResponseEnums | ||
|
|
||
|
|
||
| def get_time_entries_summary(req: func.HttpRequest) -> func.HttpResponse: | ||
| database = DB() | ||
| time_entry_dao = _infrastructure.TimeEntriesSQLDao(database) | ||
| time_entry_service = _domain.TimeEntryService(time_entry_dao) | ||
| use_case = _domain._use_cases.GetTimeEntriesSummaryUseCase(time_entry_service) | ||
|
|
||
| response_params = { | ||
| "body": ResponseEnums.NOT_FOUND.value, | ||
| "status_code": HTTPStatus.NOT_FOUND, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should go HTTPStatus.NOT_FOUND.value if not take everything as 200, at same for others status There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not corrected yet |
||
| "mimetype": ResponseEnums.MIME_TYPE.value, | ||
| } | ||
|
|
||
| try: | ||
| owner_id = req.params.get("owner_id") | ||
| start_date = req.params.get("start_date") | ||
| end_date = req.params.get("end_date") | ||
|
|
||
| if not owner_id or not start_date or not end_date: | ||
| return func.HttpResponse(**response_params) | ||
|
|
||
| if not _validate_time_format(start_date) or not _validate_time_format(end_date): | ||
| response_params["body"] = ResponseEnums.INVALID_DATE_FORMAT.value | ||
| return func.HttpResponse(**response_params) | ||
|
|
||
| time_entries = use_case.get_time_entries_summary( | ||
| int(owner_id), start_date, end_date | ||
| ) | ||
|
|
||
| if not time_entries: | ||
| return func.HttpResponse(**response_params) | ||
|
|
||
| response_params["body"] = json.dumps(time_entries, default=str) | ||
| response_params["status_code"] = HTTPStatus.OK | ||
jer8856 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| return func.HttpResponse(**response_params) | ||
|
|
||
| except ValueError: | ||
| response_params["body"] = ResponseEnums.INVALID_ID.value | ||
| response_params["status_code"] = HTTPStatus.BAD_REQUEST | ||
jer8856 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return func.HttpResponse(**response_params) | ||
|
|
||
|
|
||
| def _validate_time_format(time: str) -> bool: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perhaps this functionality can be implemented globally |
||
| try: | ||
| datetime.datetime.strptime(time, "%m/%d/%Y") | ||
| except ValueError: | ||
| return False | ||
| return True | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,4 +10,5 @@ | |
| GetTimeEntriesUseCase, | ||
| GetTimeEntryUseCase, | ||
| GetLastestTimeEntryUseCase, | ||
| GetTimeEntriesSummaryUseCase, | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import typing | ||
jer8856 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| from time_tracker.time_entries._domain import TimeEntry, TimeEntryService | ||
|
|
||
|
|
||
| class GetTimeEntriesSummaryUseCase: | ||
|
|
||
| def __init__(self, time_entry_service: TimeEntryService): | ||
| self.time_entry_service = time_entry_service | ||
|
|
||
| def get_time_entries_summary(self, owner_id: int, start_date: str, end_date: str) -> typing.List[TimeEntry]: | ||
| return self.time_entry_service.get_time_entries_summary(owner_id, start_date, end_date) | ||
Uh oh!
There was an error while loading. Please reload this page.