Skip to content

Commit 45251d2

Browse files
committed
feat: TT-401 Implemented service, end-point, dao, test- time entries
1 parent b869c09 commit 45251d2

File tree

23 files changed

+366
-1
lines changed

23 files changed

+366
-1
lines changed

V2/serverless.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,13 @@ functions:
7676
- POST
7777
route: activities/
7878
authLevel: anonymous
79+
80+
create_time_entry:
81+
handler: time_tracker/time_entries/interface.create_time_entry
82+
events:
83+
- http: true
84+
x-azure-settings:
85+
methods:
86+
- POST
87+
route: time-entries/
88+
authLevel: anonymous
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from time_tracker.time_entries._application import _time_entries as time_entries
2+
from faker import Faker
3+
4+
import azure.functions as func
5+
import json
6+
7+
8+
ACTIVITY_URL = "/api/time-entries/"
9+
10+
11+
def test__time_entry_azure_endpoint__creates_an_time_entry__when_time_entry_has_all_attributes(
12+
create_temp_time_entries,
13+
):
14+
time_entries_json, tmp_directory = create_temp_time_entries
15+
time_entries._create_time_entry._JSON_PATH = tmp_directory
16+
17+
time_entry_body = {
18+
"id" : None,
19+
"start_date" : Faker().date(),
20+
"owner_id" : Faker().random_int(),
21+
"description": Faker().sentence(),
22+
"activity_id" : Faker().random_int(),
23+
"uri": "http://timetracker.com",
24+
"technologies" : ["jira","git"],
25+
"end_date": Faker().date(),
26+
"deleted": Faker().random_int(),
27+
"timezone_offset": "300",
28+
"project_id": Faker().random_int(),
29+
}
30+
body = json.dumps(time_entry_body).encode("utf-8")
31+
req = func.HttpRequest(
32+
method="POST",
33+
body=body,
34+
url=ACTIVITY_URL,
35+
)
36+
37+
response = time_entries.create_time_entry(req)
38+
time_entry_json_data = response.get_body()
39+
assert response.status_code == 201
40+
assert time_entry_json_data == body

V2/tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# flake8: noqa
2-
from fixtures import _activity_factory, _create_fake_dao, _create_fake_database
2+
from fixtures import _activity_factory, _create_fake_dao, _create_fake_database
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import json
2+
import pytest
3+
import typing
4+
5+
from faker import Faker
6+
7+
from time_tracker.time_entries._infrastructure import TimeEntriesJsonDao
8+
from time_tracker.time_entries._domain import TimeEntry
9+
10+
11+
@pytest.fixture(name="create_fake_time_entries")
12+
def _create_fake_time_entries(mocker) -> typing.List[TimeEntry]:
13+
def _creator(time_entries):
14+
read_data = json.dumps(time_entries)
15+
mocker.patch("builtins.open", mocker.mock_open(read_data=read_data))
16+
return [TimeEntry(**time_entry) for time_entry in time_entries]
17+
18+
return _creator
19+
20+
21+
def test_create_time_entry__returns_an_time_entry_dto__when_create_an_time_entry_that_matches_attributes(
22+
create_fake_time_entries,
23+
):
24+
create_fake_time_entries([])
25+
26+
time_entries_json_dao = TimeEntriesJsonDao(Faker().file_path())
27+
time_entry_data = {
28+
"id" : None,
29+
"start_date" : Faker().date(),
30+
"owner_id" : Faker().random_int(),
31+
"description": Faker().sentence(),
32+
"activity_id" : Faker().random_int(),
33+
"uri": "http://hola.com",
34+
"technologies" : ["jira","git"],
35+
"end_date": Faker().date(),
36+
"deleted": Faker().random_int(),
37+
"timezone_offset": "UTC-5",
38+
"project_id": Faker().random_int(),
39+
}
40+
result = time_entries_json_dao.create(time_entry_data)
41+
assert result == TimeEntry(**time_entry_data)
42+
43+
44+
45+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from faker import Faker
2+
3+
from time_tracker.time_entries._domain import TimeEntryService
4+
5+
def test__create_time_entries__uses_the_time_entry_dao__to_create_an_time_entry(mocker):
6+
expected_time_entry = mocker.Mock()
7+
time_entry_dao = mocker.Mock(
8+
create=mocker.Mock(return_value=expected_time_entry)
9+
)
10+
time_entry_service = TimeEntryService(time_entry_dao)
11+
12+
actual_time_entry = time_entry_service.create(Faker().pydict())
13+
14+
assert time_entry_dao.create.called
15+
assert expected_time_entry == actual_time_entry
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from faker import Faker
2+
3+
from pytest_mock import MockFixture
4+
5+
from time_tracker.time_entries._domain import _use_cases
6+
7+
def test__create_time_entry_function__uses_the_time_entries_service__to_create_time_entry(
8+
mocker: MockFixture,
9+
):
10+
expected_time_entry = mocker.Mock()
11+
time_entry_service = mocker.Mock(
12+
create=mocker.Mock(return_value=expected_time_entry)
13+
)
14+
15+
time_entry_use_case = _use_cases.CreateTimeEntryUseCase(time_entry_service)
16+
actual_time_entry = time_entry_use_case.create_time_entry(Faker().pydict())
17+
18+
assert time_entry_service.create.called
19+
assert expected_time_entry == actual_time_entry
20+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from ._time_entries import create_time_entry
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from ._create_time_entry import create_time_entry
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import dataclasses
2+
import json
3+
import typing
4+
5+
import azure.functions as func
6+
7+
from ... import _domain
8+
from ... import _infrastructure
9+
10+
_JSON_PATH = (
11+
'time_entries/_infrastructure/_data_persistence/time_entries_data.json'
12+
)
13+
14+
def create_time_entry(req: func.HttpRequest) -> func.HttpResponse:
15+
16+
time_entry_dao = _infrastructure.TimeEntriesJsonDao(_JSON_PATH)
17+
time_entry_service = _domain.TimeEntryService(time_entry_dao)
18+
use_case = _domain._use_cases.CreateTimeEntryUseCase(time_entry_service)
19+
20+
time_entry_data = req.get_json()
21+
22+
time_entry_to_create = _domain.TimeEntry(
23+
id=None,
24+
start_date=time_entry_data["start_date"],
25+
owner_id=time_entry_data["owner_id"],
26+
description=time_entry_data["description"],
27+
activity_id=time_entry_data["activity_id"],
28+
uri=time_entry_data["uri"],
29+
technologies=time_entry_data["technologies"],
30+
end_date=time_entry_data["end_date"],
31+
deleted=time_entry_data["deleted"],
32+
timezone_offset=time_entry_data["timezone_offset"],
33+
project_id=time_entry_data["project_id"]
34+
)
35+
36+
created_time_entry = use_case.create_time_entry(time_entry_to_create.__dict__)
37+
38+
if not created_time_entry:
39+
return func.HttpResponse(
40+
body=json.dumps({'error': 'time_entry could not be created'}),
41+
status_code=500,
42+
mimetype="application/json"
43+
)
44+
45+
return func.HttpResponse(
46+
body=json.dumps(created_time_entry.__dict__),
47+
status_code=201,
48+
mimetype="application/json"
49+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from ._entities import TimeEntry
2+
from ._persistence_contracts import TimeEntriesDao
3+
from ._services import TimeEntryService
4+
from ._use_cases import (
5+
CreateTimeEntryUseCase,
6+
)

0 commit comments

Comments
 (0)