Skip to content

Commit b002e5c

Browse files
committed
fix: TT-357 Testing of methods create and update
2 parents 2a96b8c + 8e1d71c commit b002e5c

File tree

25 files changed

+417
-41
lines changed

25 files changed

+417
-41
lines changed

.gitignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ node_modules
2929
# Serverless directories
3030
.serverless/
3131

32-
# Azure Functions json config
33-
host.json
34-
local.settings.json
35-
3632
# Files generated for development
3733
.env
3834
timetracker-api-postman-collection.json

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,27 @@
22

33
<!--next-version-placeholder-->
44

5+
## v0.42.0 (2021-11-03)
6+
### Feature
7+
* TT-365 / TT-369 POST V2 Activity ([#329](https://github.com/ioet/time-tracker-backend/issues/329)) ([`6c3687b`](https://github.com/ioet/time-tracker-backend/commit/6c3687b5ca60893be23b6ad663de3081af964272))
8+
9+
## v0.41.0 (2021-10-28)
10+
### Feature
11+
* TT-366 V2 - PUT update activity ([#331](https://github.com/ioet/time-tracker-backend/issues/331)) ([`500a5d0`](https://github.com/ioet/time-tracker-backend/commit/500a5d0261497ce9aa9a9040342fea94dbe70704))
12+
13+
## v0.40.0 (2021-10-27)
14+
### Feature
15+
* TT-367 V2 - Delete Activity ([#330](https://github.com/ioet/time-tracker-backend/issues/330)) ([`6ba8320`](https://github.com/ioet/time-tracker-backend/commit/6ba8320c6ddd6599679dfbbbaf9ac1dba9addb8d))
16+
* TT-358 Use serverless to create Azure endpoint ([#328](https://github.com/ioet/time-tracker-backend/issues/328)) ([`464f281`](https://github.com/ioet/time-tracker-backend/commit/464f28193d986f12ccea6c785eee1f818b5989fb))
17+
18+
### Fix
19+
* TT-385 adding library Flask-SQLAlchemy ([#332](https://github.com/ioet/time-tracker-backend/issues/332)) ([`22de108`](https://github.com/ioet/time-tracker-backend/commit/22de108ef0bd7de0f130a697e5068cad308f76e2))
20+
* TT-001 commit to bring the changes to production ([#327](https://github.com/ioet/time-tracker-backend/issues/327)) ([`1d65c1d`](https://github.com/ioet/time-tracker-backend/commit/1d65c1d65c5a29bb6330dc8d52ae1bd5c38003be))
21+
* TT-335 patch to give admin permissions to certain users ([#323](https://github.com/ioet/time-tracker-backend/issues/323)) ([`c0b51c9`](https://github.com/ioet/time-tracker-backend/commit/c0b51c9b3127c7d231448e038a713fcc6126c093))
22+
23+
### Documentation
24+
* TT-000 test 2 release ([#326](https://github.com/ioet/time-tracker-backend/issues/326)) ([`7294e2e`](https://github.com/ioet/time-tracker-backend/commit/7294e2e14641ee45f408c593e768cc7f2e07e742))
25+
526
## v0.39.1 (2021-10-06)
627
### Fix
728
* TT-339 skip users with azureioet.onmicrosoft.com extension from user search ([#322](https://github.com/ioet/time-tracker-backend/issues/322)) ([`8b37d4a`](https://github.com/ioet/time-tracker-backend/commit/8b37d4a7a890b9e4880efedd19dc733e60c5e7cf))

V2/serverless.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,24 @@ functions:
5555
methods:
5656
- DELETE
5757
route: activities/{id}
58-
authLevel: anonymous
58+
authLevel: anonymous
59+
60+
update_activity:
61+
handler: time_entries/interface.update_activity
62+
events:
63+
- http: true
64+
x-azure-settings:
65+
methods:
66+
- PUT
67+
route: activities/{id}
68+
authLevel: anonymous
69+
70+
create_activity:
71+
handler: time_entries/interface.create_activity
72+
events:
73+
- http: true
74+
x-azure-settings:
75+
methods:
76+
- POST
77+
route: activities/
78+
authLevel: anonymous

V2/tests/api/azure/activity_azure_endpoints_test.py

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
import typing
33
import json
44
import uuid
5-
5+
from faker import Faker
66

77
import azure.functions as func
88

99
import time_entries._application._activities as azure_activities
1010
import time_entries._domain as domain
1111
import time_entries._infrastructure as infrastructure
1212

13+
ACTIVITY_URL = '/api/activities/'
14+
15+
1316
@pytest.fixture(name='create_fake_database')
1417
def _create_fake_database() -> domain.ActivitiesDao:
1518
db_fake = infrastructure.DB('sqlite:///:memory:')
@@ -41,7 +44,7 @@ def test__activity_azure_endpoint__returns_all_activities(
4144
):
4245
database, activity_data = create_fake_database
4346
azure_activities._get_activities.DATABASE = database
44-
req = func.HttpRequest(method='GET', body=None, url='/api/activities')
47+
req = func.HttpRequest(method='GET', body=None, url=ACTIVITY_URL)
4548

4649
response = azure_activities._get_activities.get_activities(req)
4750
activities_json_data = response.get_body().decode("utf-8")
@@ -61,7 +64,7 @@ def test__activity_azure_endpoint__returns_an_activity__when_activity_matches_it
6164
req = func.HttpRequest(
6265
method='GET',
6366
body=None,
64-
url='/api/activities/',
67+
url=ACTIVITY_URL,
6568
route_params={"id": str(activity_data[0]['id'])},
6669
)
6770

@@ -82,7 +85,7 @@ def test__activity_azure_endpoint__returns_an_activity_with_inactive_status__whe
8285
req = func.HttpRequest(
8386
method='DELETE',
8487
body=None,
85-
url='/api/activities/',
88+
url=ACTIVITY_URL,
8689
route_params={"id": str(activity_data[0]['id'])},
8790
)
8891

@@ -91,3 +94,47 @@ def test__activity_azure_endpoint__returns_an_activity_with_inactive_status__whe
9194

9295
assert response.status_code == 200
9396
assert activity_json_data['status'] == 'inactive'
97+
98+
99+
def test__update_activity_azure_endpoint__returns_an_activity__when_found_an_activity_to_update(
100+
create_fake_database,
101+
):
102+
database, activity_data = create_fake_database
103+
azure_activities._update_activity.DATABASE = database
104+
activity_body = {"description": Faker().sentence()}
105+
req = func.HttpRequest(
106+
method='PUT',
107+
body=json.dumps(activity_body).encode("utf-8"),
108+
url=ACTIVITY_URL,
109+
route_params={"id": str(activity_data[0]['id'])},
110+
)
111+
112+
activity_data[0]["id"] = activity_data[0]["id"].hex
113+
114+
response = azure_activities._update_activity.update_activity(req)
115+
activitiy_json_data = response.get_body().decode("utf-8")
116+
new_activity = {**activity_data[0], **activity_body}
117+
118+
assert response.status_code == 200
119+
assert activitiy_json_data == json.dumps(new_activity)
120+
121+
def test__activity_azure_endpoint__creates_an_activity__when_activity_has_all_attributes(
122+
create_fake_database,
123+
):
124+
database, activity_data = create_fake_database
125+
azure_activities._update_activity.DATABASE = database
126+
127+
activity_body = {'id': None, 'name': Faker().user_name(), 'description': Faker().sentence(),'deleted': Faker().uuid4() ,'status': 'active', 'tenant_id': Faker().uuid4()}
128+
body = json.dumps(activity_body).encode("utf-8")
129+
req = func.HttpRequest(
130+
method='POST',
131+
body= body,
132+
url=ACTIVITY_URL,
133+
)
134+
135+
136+
response = azure_activities._create_activity.create_activity(req)
137+
activitiy_json_data = json.loads(response.get_body())
138+
activity_body['id'] = activitiy_json_data['id']
139+
assert response.status_code == 201
140+
assert activitiy_json_data == activity_body

V2/tests/integration/daos/activities_json_dao_test.py

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
import typing
77

88

9+
fake_activities = [
10+
{
11+
'id': Faker().uuid4(),
12+
'name': Faker().user_name(),
13+
'description': Faker().sentence(),
14+
'deleted': Faker().uuid4(),
15+
'status': 'active',
16+
'tenant_id': Faker().uuid4(),
17+
}
18+
]
19+
20+
921
@pytest.fixture(name='create_fake_activities')
1022
def _create_fake_activities(mocker) -> typing.List[Activity]:
1123
def _creator(activities):
@@ -20,18 +32,7 @@ def test_get_by_id__returns_an_activity_dto__when_found_one_activity_that_matche
2032
create_fake_activities,
2133
):
2234
activities_json_dao = ActivitiesJsonDao(Faker().file_path())
23-
activities = create_fake_activities(
24-
[
25-
{
26-
"name": "test_name",
27-
"description": "test_description",
28-
"tenant_id": "test_tenant_id",
29-
"id": "test_id",
30-
"deleted": "test_deleted",
31-
"status": "test_status",
32-
}
33-
]
34-
)
35+
activities = create_fake_activities(fake_activities)
3536
activity_dto = activities.pop()
3637

3738
result = activities_json_dao.get_by_id(activity_dto.id)
@@ -55,19 +56,7 @@ def test__get_all__returns_a_list_of_activity_dto_objects__when_one_or_more_acti
5556
):
5657
activities_json_dao = ActivitiesJsonDao(Faker().file_path())
5758
number_of_activities = 3
58-
activities = create_fake_activities(
59-
[
60-
{
61-
"name": "test_name",
62-
"description": "test_description",
63-
"tenant_id": "test_tenant_id",
64-
"id": "test_id",
65-
"deleted": "test_deleted",
66-
"status": "test_status",
67-
}
68-
]
69-
* number_of_activities
70-
)
59+
activities = create_fake_activities(fake_activities * number_of_activities)
7160

7261
result = activities_json_dao.get_all()
7362

@@ -117,3 +106,44 @@ def test_delete__returns_none__when_no_activity_matching_its_id_is_found(
117106
result = activities_json_dao.delete(Faker().uuid4())
118107

119108
assert result is None
109+
110+
111+
def test_update__returns_an_activity_dto__when_found_one_activity_to_update(
112+
create_fake_activities,
113+
):
114+
activities_json_dao = ActivitiesJsonDao(Faker().file_path())
115+
activities = create_fake_activities(fake_activities)
116+
activity_dto = activities.pop()
117+
activity_data = {"description": Faker().sentence()}
118+
119+
result = activities_json_dao.update(activity_dto.id, activity_data)
120+
new_activity = {**activity_dto.__dict__, **activity_data}
121+
122+
assert result == Activity(**new_activity)
123+
124+
125+
def test_update__returns_none__when_doesnt_found_one_activity_to_update(
126+
create_fake_activities,
127+
):
128+
activities_json_dao = ActivitiesJsonDao(Faker().file_path())
129+
create_fake_activities([])
130+
activity_data = {"description": Faker().sentence()}
131+
132+
result = activities_json_dao.update('', activity_data)
133+
134+
assert result == None
135+
136+
def test_create_activity__returns_an_activity_dto__when_create_an_activity_that_matches_attributes(create_fake_activities):
137+
create_fake_activities([])
138+
139+
activities_json_dao = ActivitiesJsonDao(Faker().file_path())
140+
activity_data = {
141+
"name": "test_name",
142+
"description": "test_description",
143+
"tenant_id": "test_tenant_id",
144+
"id": "test_id",
145+
"deleted": "test_deleted",
146+
"status": "test_status",
147+
}
148+
result = activities_json_dao.create_activity(activity_data)
149+
assert result == Activity(**activity_data)

V2/tests/unit/services/activity_service_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,32 @@ def test__delete_activity__uses_the_activity_dao__to_change_activity_status(
4141

4242
assert activity_dao.delete.called
4343
assert expected_activity == deleted_activity
44+
45+
46+
def test__update_activity__uses_the_activity_dao__to_update_one_activity(
47+
mocker,
48+
):
49+
expected_activity = mocker.Mock()
50+
activity_dao = mocker.Mock(
51+
update=mocker.Mock(return_value=expected_activity)
52+
)
53+
activity_service = ActivityService(activity_dao)
54+
55+
updated_activity = activity_service.update(
56+
Faker().uuid4(), Faker().pydict()
57+
)
58+
59+
assert activity_dao.update.called
60+
assert expected_activity == updated_activity
61+
62+
def test__create_activity__uses_the_activity_dao__to_create_an_activity(mocker):
63+
expected_activity = mocker.Mock()
64+
activity_dao = mocker.Mock(
65+
create_activity=mocker.Mock(return_value=expected_activity)
66+
)
67+
activity_service = ActivityService(activity_dao)
68+
69+
actual_activity = activity_service.create_activity(Faker().pydict())
70+
71+
assert activity_dao.create_activity.called
72+
assert expected_activity == actual_activity

V2/tests/unit/use_cases/activities_use_case_test.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ def test__get_activity_by_id_function__uses_the_activity_service__to_retrieve_ac
3636
assert expected_activity == actual_activity
3737

3838

39+
def test__create_activity_function__uses_the_activities_service__to_create_activity(
40+
mocker: MockFixture,
41+
):
42+
expected_activity = mocker.Mock()
43+
activity_service = mocker.Mock(
44+
create_activity=mocker.Mock(return_value=expected_activity)
45+
)
46+
47+
activity_use_case = _use_cases.CreateActivityUseCase(activity_service)
48+
actual_activity = activity_use_case.create_activity(fake.pydict())
49+
50+
assert activity_service.create_activity.called
51+
assert expected_activity == actual_activity
52+
3953
def test__delete_activity_function__uses_the_activity_service__to_change_activity_status(
4054
mocker: MockFixture,
4155
):
@@ -49,3 +63,19 @@ def test__delete_activity_function__uses_the_activity_service__to_change_activit
4963

5064
assert activity_service.delete.called
5165
assert expected_activity == deleted_activity
66+
67+
def test__update_activity_function__uses_the_activities_service__to_update_an_activity(
68+
mocker: MockFixture,
69+
):
70+
expected_activity = mocker.Mock()
71+
activity_service = mocker.Mock(
72+
update=mocker.Mock(return_value=expected_activity)
73+
)
74+
75+
activity_use_case = _use_cases.UpdateActivityUseCase(activity_service)
76+
updated_activity = activity_use_case.update_activity(
77+
fake.uuid4(), fake.pydict()
78+
)
79+
80+
assert activity_service.update.called
81+
assert expected_activity == updated_activity
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
from ._activities import get_activities
22
from ._activities import delete_activity
3+
from ._activities import update_activity
4+
from ._activities import create_activity
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
from ._get_activities import get_activities
22
from ._delete_activity import delete_activity
3+
from ._update_activity import update_activity
4+
from ._create_activity import create_activity

0 commit comments

Comments
 (0)