-
Notifications
You must be signed in to change notification settings - Fork 0
TT-352 create v2 read activites flask endpoint #324
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 20 commits
1065bde
3bb39b0
b15c301
7a2565c
8bdbdfe
bc998fe
9d0e21e
4c467c7
408c016
a936f0a
47bb34b
1f92569
2ce4987
361a864
bb87c54
1006410
39f5221
9539885
9e090bc
b0cc467
13133d1
7b582b7
a2d912c
b4987e6
4866913
fd84ea1
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 |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| from flask import Flask | ||
| from flask_wtf.csrf import CSRFProtect | ||
| from flask_restplus import Namespace, Resource, Api | ||
| from http import HTTPStatus | ||
| from . import activities_endpoints | ||
|
|
||
| csrf = CSRFProtect() | ||
|
|
||
|
|
||
| def create_app(test_config=None): | ||
| app = Flask(__name__) | ||
| csrf.init_app(app) | ||
|
|
||
| api = Api( | ||
| app, | ||
| version='1.0', | ||
| title='Time Tracker API', | ||
| description='API for the TimeTracker project', | ||
| ) | ||
|
|
||
| if test_config is not None: | ||
| app.config.from_mapping(test_config) | ||
|
|
||
| activities_namespace = Namespace('activities', description='Endpoint for activities') | ||
| activities_namespace.route('/')(activities_endpoints.Activities) | ||
| activities_namespace.route('/<string:activity_id>')(activities_endpoints.Activity) | ||
|
|
||
| api.add_namespace(activities_namespace) | ||
|
|
||
| return app |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| from V2.source import use_cases | ||
| from flask_restplus import Resource | ||
| from http import HTTPStatus | ||
|
|
||
|
|
||
| class Activities(Resource): | ||
| def get(self): | ||
| return [activity.__dict__ for activity in use_cases.get_list_activities()] | ||
|
|
||
|
|
||
| class Activity(Resource): | ||
| def get(self, activity_id: str): | ||
| try: | ||
| return use_cases.get_activity_by_id(activity_id).__dict__ | ||
| except AttributeError: | ||
| return {'message': 'Activity not found'}, HTTPStatus.NOT_FOUND |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| from ._get_activities_use_case import get_list_activities | ||
| from ._get_activity_by_id_use_case import get_activity_by_id |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| from V2.source.services.activity_service import ActivityService | ||
| from V2.source.daos.activities_json_dao import ActivitiesJsonDao | ||
| from V2.source.dtos.activity import Activity | ||
| import typing | ||
|
|
||
|
|
||
| def get_list_activities() -> typing.List[Activity]: | ||
| activity_json = ActivitiesJsonDao('./V2/source/activities_data.json') | ||
| activities = ActivityService(activity_json) | ||
|
|
||
| return activities.get_all() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| from V2.source.services.activity_service import ActivityService | ||
| from V2.source.daos.activities_json_dao import ActivitiesJsonDao | ||
| from V2.source.dtos.activity import Activity | ||
|
|
||
|
|
||
| def get_activity_by_id(id: str) -> Activity: | ||
| activity_json = ActivitiesJsonDao('./V2/source/activities_data.json') | ||
| activity = ActivityService(activity_json) | ||
|
|
||
| return activity.get_by_id(id) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| from V2.source.entry_points.flask_api import create_app | ||
| from V2.source import use_cases | ||
| from V2.source.dtos.activity import Activity | ||
| import json | ||
| import pytest | ||
| from http import HTTPStatus | ||
| from pytest_mock import MockFixture | ||
| from flask.testing import FlaskClient | ||
| from faker import Faker | ||
| from werkzeug.exceptions import NotFound | ||
|
|
||
| fake = Faker() | ||
|
|
||
| valid_id = fake.uuid4() | ||
|
|
||
| fake_activity = { | ||
| "name": fake.company(), | ||
| "description": fake.paragraph(), | ||
| "tenant_id": fake.uuid4(), | ||
| "id": valid_id, | ||
| "deleted": fake.date(), | ||
| "status": fake.boolean(), | ||
| } | ||
| fake_activity_dto = Activity(**fake_activity) | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def client(): | ||
| app = create_app({'TESTING': True}) | ||
| with app.test_client() as client: | ||
| yield client | ||
|
|
||
|
|
||
| def test__activities_class__uses_the_get_activities_use_case__to_retrieve_activities(client: FlaskClient, | ||
|
||
| mocker: MockFixture): | ||
| use_cases.get_list_activities = mocker.Mock(return_value=[]) | ||
|
||
|
|
||
| response = client.get("/activities/") | ||
| json_data = json.loads(response.data) | ||
|
|
||
| assert response.status_code == HTTPStatus.OK | ||
| assert [] == json_data | ||
|
|
||
|
|
||
| def test__activity_class__returns_an_activity__when_activity_matches_its_id(client: FlaskClient, mocker: MockFixture): | ||
|
||
| use_cases.get_activity_by_id = mocker.Mock(return_value=fake_activity_dto) | ||
|
|
||
| response = client.get("/activities/%s" % valid_id) | ||
|
|
||
| assert response.status_code == HTTPStatus.OK | ||
| assert fake_activity == json.loads(response.data) | ||
|
|
||
|
|
||
| def test__activity_class__returns_an_activity__when_no_activity_matches_its_id(client: FlaskClient, | ||
|
||
| mocker: MockFixture): | ||
| invalid_id = fake.uuid4() | ||
| use_cases.get_activity_by_id = mocker.Mock(side_effect=NotFound) | ||
|
|
||
| response = client.get("/activities/%s" % invalid_id) | ||
|
|
||
| assert response.status_code == HTTPStatus.NOT_FOUND | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import pytest | ||
| from pytest_mock import MockFixture | ||
| from faker import Faker | ||
|
|
||
| from V2.source import use_cases | ||
| from V2.source.daos.activities_json_dao import ActivitiesJsonDao | ||
|
|
||
| fake = Faker() | ||
|
|
||
|
|
||
| def test__get_list_activities_function__uses_the_activities_service__to_retrieve_activities(mocker: MockFixture): | ||
|
||
| expected_activities = mocker.Mock() | ||
| use_cases.get_list_activities = mocker.Mock(return_value=expected_activities) | ||
|
|
||
| actual_activities = use_cases.get_list_activities() | ||
|
|
||
| assert use_cases.get_list_activities.called | ||
| assert expected_activities == actual_activities | ||
|
|
||
|
|
||
| def test__get_activity_by_id_function__uses_the_activities_service__to_retrieve_activity(mocker: MockFixture): | ||
| expected_activity = mocker.Mock() | ||
| use_cases.get_activity_by_id = mocker.Mock(return_value=expected_activity) | ||
|
|
||
| actual_activity = use_cases.get_activity_by_id(fake.uuid4()) | ||
|
|
||
| assert use_cases.get_activity_by_id.called | ||
| assert expected_activity == actual_activity | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
|
|
||
| #Required by Flask | ||
| Flask==1.1.1 | ||
| Flask-WTF==0.15.1 | ||
| flake8==3.7.9 | ||
| WSGIserver==1.3 | ||
| Werkzeug==0.16.1 | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.