Skip to content

Commit 60a0dc7

Browse files
ararcosmandres2015
andauthored
feat: TT-403 delete v2 time entries (#346)
* feat: TT-401 Implemented service, end-point, dao, test- time entries * feat: TT-401 validated request create time entry * fix: TT-401 implemented faker url * feat: TT-403 created end-point to DELETE of time_entries * fix: TT-403 validation of id as integer * fix: TT-403 remove method POST * feat: TT-403 rebase with master * feat: TT-403 tests added * refactor: TT-403 correct flake8 lint syntax * fix: TT-403 comments solved * fix: TT-403 correction of rebase * refactor: TT-403 renamed of delete test Co-authored-by: mandres2015 <[email protected]>
1 parent 5f107f3 commit 60a0dc7

File tree

16 files changed

+191
-5
lines changed

16 files changed

+191
-5
lines changed

V2/serverless.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,13 @@ functions:
8686
- POST
8787
route: time-entries/
8888
authLevel: anonymous
89+
90+
delete_time_entry:
91+
handler: time_tracker/time_entries/interface.delete_time_entry
92+
events:
93+
- http: true
94+
x-azure-settings:
95+
methods:
96+
- DELETE
97+
route: time-entries/{id}
98+
authLevel: anonymous

V2/tests/api/azure/time_entry_azure_endpoints_test.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
1+
import pytest
12
import json
23

34
import azure.functions as func
45

56
import time_tracker.time_entries._application._time_entries as azure_time_entries
7+
from time_tracker._infrastructure import DB
8+
from time_tracker.time_entries import _domain as domain_time_entries
9+
from time_tracker.time_entries import _infrastructure as infrastructure_time_entries
10+
611

712
TIME_ENTRY_URL = "/api/time-entries/"
813

914

15+
@pytest.fixture(name='insert_time_entry')
16+
def _insert_time_entry() -> domain_time_entries.TimeEntry:
17+
def _new_time_entry(time_entry: domain_time_entries.TimeEntry, database: DB):
18+
dao = infrastructure_time_entries.TimeEntriesSQLDao(database)
19+
new_time_entry = dao.create(time_entry)
20+
return new_time_entry
21+
return _new_time_entry
22+
23+
1024
def test__time_entry_azure_endpoint__creates_an_time_entry__when_time_entry_has_all_attributes(
1125
test_db, time_entry_factory, activity_factory, insert_activity
1226
):
@@ -26,3 +40,39 @@ def test__time_entry_azure_endpoint__creates_an_time_entry__when_time_entry_has_
2640

2741
assert response.status_code == 201
2842
assert time_entry_json_data == time_entry_body
43+
44+
45+
def test__delete_time_entries_azure_endpoint__returns_an_time_entry_with_true_deleted__when_its_id_is_found(
46+
test_db, time_entry_factory, insert_time_entry, insert_activity, activity_factory,
47+
):
48+
inserted_activity = insert_activity(activity_factory(), test_db).__dict__
49+
time_entry_body = time_entry_factory(activity_id=inserted_activity["id"], technologies="[jira,sql]")
50+
inserted_time_entry = insert_time_entry(time_entry_body, test_db)
51+
52+
req = func.HttpRequest(
53+
method='DELETE',
54+
body=None,
55+
url=TIME_ENTRY_URL,
56+
route_params={"id": inserted_time_entry.id},
57+
)
58+
59+
response = azure_time_entries._delete_time_entry.delete_time_entry(req)
60+
time_entry_json_data = json.loads(response.get_body().decode("utf-8"))
61+
62+
assert response.status_code == 200
63+
assert time_entry_json_data['deleted'] is True
64+
65+
66+
def test__delete_time_entries_azure_endpoint__returns_a_status_code_400__when_time_entry_recive_invalid_id(
67+
):
68+
req = func.HttpRequest(
69+
method="DELETE",
70+
body=None,
71+
url=TIME_ENTRY_URL,
72+
route_params={"id": "invalid id"},
73+
)
74+
75+
response = azure_time_entries._delete_time_entry.delete_time_entry(req)
76+
77+
assert response.status_code == 400
78+
assert response.get_body() == b'Invalid Format ID'

V2/tests/fixtures.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
@pytest.fixture(name='activity_factory')
1111
def _activity_factory() -> activities_domain.Activity:
1212
def _make_activity(
13-
name: str = Faker().name(), description: str = Faker().sentence(), deleted: bool = False, status: int = 1
13+
name: str = Faker().name(),
14+
description: str = Faker().sentence(),
15+
deleted: bool = False,
16+
status: int = 1,
1417
):
1518
activity = activities_domain.Activity(
1619
id=None,
@@ -20,6 +23,7 @@ def _make_activity(
2023
status=status
2124
)
2225
return activity
26+
2327
return _make_activity
2428

2529

V2/tests/integration/daos/time_entries_dao_test.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pytest
2-
2+
from faker import Faker
33

44
import time_tracker.time_entries._domain as domain
55
import time_tracker.time_entries._infrastructure as infrastructure
@@ -46,3 +46,26 @@ def test__time_entry__returns_None__when_not_saves_correctly(
4646
inserted_time_entry = dao.create(time_entry_to_insert)
4747

4848
assert inserted_time_entry is None
49+
50+
51+
def test_delete__returns_an_time_entry_with_true_deleted__when_an_time_entry_matching_its_id_is_found(
52+
create_fake_dao, test_db, time_entry_factory, insert_activity, activity_factory
53+
):
54+
dao = create_fake_dao(test_db)
55+
inserted_activity = insert_activity(activity_factory(), dao.db)
56+
existent_time_entry = time_entry_factory(activity_id=inserted_activity.id, technologies="[jira,sql]")
57+
inserted_time_entry = dao.create(existent_time_entry)
58+
59+
result = dao.delete(inserted_time_entry.id)
60+
61+
assert result.deleted is True
62+
63+
64+
def test_delete__returns_none__when_no_time_entry_matching_its_id_is_found(
65+
create_fake_dao, test_db
66+
):
67+
dao = create_fake_dao(test_db)
68+
69+
result = dao.delete(Faker().pyint())
70+
71+
assert result is None

V2/tests/unit/services/time_entry_service_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from faker import Faker
2+
13
from time_tracker.time_entries._domain import TimeEntryService
24

35

@@ -12,3 +14,18 @@ def test__create_time_entries__uses_the_time_entry_dao__to_create_an_time_entry(
1214

1315
assert time_entry_dao.create.called
1416
assert expected_time_entry == actual_time_entry
17+
18+
19+
def test__delete_time_entry__uses_the_time_entry_dao__to_delete_time_entry_selected(
20+
mocker,
21+
):
22+
expected_time_entry = mocker.Mock()
23+
time_entry_dao = mocker.Mock(
24+
delete=mocker.Mock(return_value=expected_time_entry)
25+
)
26+
27+
time_entry_service = TimeEntryService(time_entry_dao)
28+
deleted_time_entry = time_entry_service.delete(Faker().pyint())
29+
30+
assert time_entry_dao.delete.called
31+
assert expected_time_entry == deleted_time_entry

V2/tests/unit/use_cases/time_entries_use_case_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from pytest_mock import MockFixture
2+
from faker import Faker
23

34
from time_tracker.time_entries._domain import _use_cases
45

@@ -16,3 +17,16 @@ def test__create_time_entry_function__uses_the_time_entries_service__to_create_t
1617

1718
assert time_entry_service.create.called
1819
assert expected_time_entry == actual_time_entry
20+
21+
22+
def test__delete_time_entry_function__uses_the_time_entry_service__to_delete_time_entry_selected(
23+
mocker: MockFixture,
24+
):
25+
expected_time_entry = mocker.Mock()
26+
time_entry_service = mocker.Mock(delete=mocker.Mock(return_value=expected_time_entry))
27+
28+
time_entry_use_case = _use_cases.DeleteTimeEntryUseCase(time_entry_service)
29+
deleted_time_entry = time_entry_use_case.delete_time_entry(Faker().pyint())
30+
31+
assert time_entry_service.delete.called
32+
assert expected_time_entry == deleted_time_entry
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# flake8: noqa
2-
from ._time_entries import create_time_entry
2+
from ._time_entries import create_time_entry, delete_time_entry
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# flake8: noqa
2-
from ._create_time_entry import create_time_entry
2+
from ._create_time_entry import create_time_entry
3+
from ._delete_time_entry import delete_time_entry
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import json
2+
3+
import azure.functions as func
4+
5+
from ... import _domain
6+
from ... import _infrastructure
7+
from time_tracker._infrastructure import DB
8+
9+
10+
def delete_time_entry(req: func.HttpRequest) -> func.HttpResponse:
11+
time_entry_dao = _infrastructure.TimeEntriesSQLDao(DB())
12+
time_entry_service = _domain.TimeEntryService(time_entry_dao)
13+
use_case = _domain._use_cases.DeleteTimeEntryUseCase(time_entry_service)
14+
15+
try:
16+
time_entry_id = int(req.route_params.get("id"))
17+
deleted_time_entry = use_case.delete_time_entry(time_entry_id)
18+
if not deleted_time_entry:
19+
return func.HttpResponse(
20+
body="Not found",
21+
status_code=404,
22+
mimetype="application/json"
23+
)
24+
25+
return func.HttpResponse(
26+
body=json.dumps(deleted_time_entry.__dict__, default=str),
27+
status_code=200,
28+
mimetype="application/json",
29+
)
30+
31+
except ValueError:
32+
return func.HttpResponse(
33+
body=b"Invalid Format ID",
34+
status_code=400,
35+
mimetype="application/json"
36+
)

V2/time_tracker/time_entries/_domain/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
from ._services import TimeEntryService
55
from ._use_cases import (
66
CreateTimeEntryUseCase,
7+
DeleteTimeEntryUseCase
78
)

0 commit comments

Comments
 (0)