Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pytest==5.2.0

# Mocking
pytest-mock==2.0.0
Faker==4.0.2

# Coverage
coverage==4.5.1
6 changes: 6 additions & 0 deletions time_tracker_api/activities/activities_namespace.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from flask_restplus import fields, Resource, Namespace
from time_tracker_api.api import audit_fields
from faker import Faker

faker = Faker()

ns = Namespace('activities', description='API for activities')

Expand All @@ -10,10 +13,12 @@
title='Name',
max_length=50,
description='Canonical name of the activity',
example=faker.word(['Development', 'Training']),
),
'description': fields.String(
title='Description',
description='Comments about the activity',
example=faker.paragraph(),
),
})

Expand All @@ -23,6 +28,7 @@
required=True,
title='Identifier',
description='The unique identifier',
example=faker.random_int(1, 9999),
)
}
activity_response_fields.update(audit_fields)
Expand Down
8 changes: 7 additions & 1 deletion time_tracker_api/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from flask_restplus import Api, fields
from faker import Faker

faker = Faker()

api = Api(version='1.0.1', title="TimeTracker API",
description="API for the TimeTracker project")
Expand All @@ -8,19 +11,22 @@
'created_at': fields.Date(
readOnly=True,
title='Created',
description='Date of creation'
description='Date of creation',
example=faker.iso8601(end_datetime=None),
),
'tenant_id': fields.String(
readOnly=True,
title='Tenant',
max_length=64,
description='The tenant this belongs to',
example=faker.random_int(1, 9999),
),
'created_by': fields.String(
readOnly=True,
title='Creator',
max_length=64,
description='User that created it',
example=faker.random_int(1, 9999),
),
}

Expand Down
20 changes: 10 additions & 10 deletions time_tracker_api/projects/projects_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@ def __init__(self):
def get_all(self):
return self.projects

def get(self, uid):
def get(self, id):
for project in self.projects:
if project.get('uid') == uid:
if project.get('id') == id:
return project
raise MissingResource("Project '%s' not found" % uid)
raise MissingResource("Project '%s' not found" % id)

def create(self, project):
self.counter += 1
project['uid'] = str(self.counter)
project['id'] = str(self.counter)
self.projects.append(project)
return project

def update(self, uid, data):
project = self.get(uid)
def update(self, id, data):
project = self.get(id)
if project:
project.update(data)
return project
else:
raise MissingResource("Project '%s' not found" % uid)
raise MissingResource("Project '%s' not found" % id)

def delete(self, uid):
if uid:
project = self.get(uid)
def delete(self, id):
if id:
project = self.get(id)
self.projects.remove(project)

def flush(self):
Expand Down
31 changes: 19 additions & 12 deletions time_tracker_api/projects/projects_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
from .projects_model import project_dao
from time_tracker_api.errors import MissingResource
from time_tracker_api.api import audit_fields
from faker import Faker

faker = Faker()

ns = Namespace('projects', description='API for projects (clients)')

Expand All @@ -11,17 +14,20 @@
required=True,
title='Name',
max_length=50,
description='Name of the project'
description='Name of the project',
example=faker.company(),
),
'description': fields.String(
title='Description',
description='Description about the project'
description='Description about the project',
example=faker.paragraph(),
),
'type': fields.String(
required=True,
title='Type',
max_length=30,
description='If it is `Costumer`, `Training` or other type',
example=faker.word(['Customer', 'Training']),
),
})

Expand All @@ -31,6 +37,7 @@
required=True,
title='Identifier',
description='The unique identifier',
example=faker.random_int(1, 9999),
)
}
project_response_fields.update(audit_fields)
Expand Down Expand Up @@ -66,24 +73,24 @@ def post(self):
help='Is the project active?')


@ns.route('/<string:uid>')
@ns.route('/<string:id>')
@ns.response(404, 'Project not found')
@ns.param('uid', 'The project identifier')
@ns.param('id', 'The project identifier')
class Project(Resource):
@ns.doc('get_project')
@ns.marshal_with(project)
def get(self, uid):
def get(self, id):
"""Retrieve a project"""
return project_dao.get(uid)
return project_dao.get(id)

@ns.doc('update_project_status')
@ns.expect(project)
@ns.response(204, 'State of the project successfully updated')
def post(self, uid):
def post(self, id):
"""Updates a project using form data"""
try:
update_data = project_update_parser.parse_args()
return project_dao.update(uid, update_data), 200
return project_dao.update(id, update_data), 200
except ValueError:
abort(code=400)
except MissingResource as e:
Expand All @@ -92,13 +99,13 @@ def post(self, uid):
@ns.doc('put_project')
@ns.expect(project_input)
@ns.marshal_with(project)
def put(self, uid):
def put(self, id):
"""Create or replace a project"""
return project_dao.update(uid, ns.payload)
return project_dao.update(id, ns.payload)

@ns.doc('delete_project')
@ns.response(204, 'Project deleted successfully')
def delete(self, uid):
def delete(self, id):
"""Deletes a project"""
project_dao.delete(uid)
project_dao.delete(id)
return None, 204
17 changes: 11 additions & 6 deletions time_tracker_api/technologies/technologies_namespace.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from flask_restplus import Namespace, Resource, fields
from time_tracker_api.api import audit_fields
from faker import Faker

faker = Faker()

ns = Namespace('technologies', description='API for technologies used')

Expand All @@ -9,7 +12,8 @@
required=True,
title='Name',
max_length=50,
description='Name of the technology'
description='Name of the technology',
example=faker.word(['Java', 'Python', 'Elixir'])
),
})

Expand All @@ -19,6 +23,7 @@
required=True,
title='Identifier',
description='The unique identifier',
example=faker.random_int(1, 9999),
),
}
technology_response_fields.update(audit_fields)
Expand Down Expand Up @@ -46,25 +51,25 @@ def post(self):
return ns.payload, 201


@ns.route('/<string:uid>')
@ns.route('/<string:id>')
@ns.response(404, 'Technology not found')
@ns.param('uid', 'The technology identifier')
@ns.param('id', 'The technology identifier')
class Technology(Resource):
@ns.doc('get_technology')
@ns.marshal_with(technology)
def get(self, uid):
def get(self, id):
"""Retrieve a technology"""
return {}

@ns.doc('put_technology')
@ns.expect(technology_input)
@ns.marshal_with(technology)
def put(self, uid):
def put(self, id):
"""Updates a technology"""
return ns.payload()

@ns.doc('delete_technology')
@ns.response(204, 'Technology deleted successfully')
def delete(self, uid):
def delete(self, id):
"""Deletes a technology"""
return None, 204
15 changes: 13 additions & 2 deletions time_tracker_api/time_entries/time_entries_namespace.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from flask_restplus import fields, Resource, Namespace
from time_tracker_api.api import audit_fields
from time_tracker_api import database
from faker import Faker

faker = Faker()

ns = Namespace('time-entries', description='API for time entries')

Expand All @@ -11,12 +14,14 @@
title='Project',
max_length=64,
description='The id of the selected project',
example=faker.random_int(1, 9999),
),
'activity_id': fields.String(
required=False,
title='Activity',
max_length=64,
description='The id of the selected activity',
example=faker.random_int(1, 9999),
),
'technologies': fields.String(
required=True,
Expand All @@ -26,17 +31,20 @@
),
'description': fields.String(
title='Comments',
description='Comments about the time entry'
description='Comments about the time entry',
example=faker.paragraph(),
),
'start_date': fields.DateTime(
required=True,
title='Start date',
description='When the user started doing this activity',
example=faker.iso8601(end_datetime=None),
),
'end_date': fields.DateTime(
required=True,
title='End date',
description='When the user ended doing this activity',
example=faker.iso8601(end_datetime=None),
),
})

Expand All @@ -46,11 +54,13 @@
required=True,
title='Identifier',
description='The unique identifier',
example=faker.random_int(1, 9999),
),
'running': fields.Boolean(
readOnly=True,
title='Is it running?',
description='Whether this time entry is currently running or not'
description='Whether this time entry is currently running or not',
example=faker.boolean(),
),
}
time_entry_response_fields.update(audit_fields)
Expand All @@ -64,6 +74,7 @@

model = database.create('time-entries')


@ns.route('')
class TimeEntries(Resource):
@ns.doc('list_time_entries')
Expand Down