Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
fix:bug: Close #107 Allow removing id by specifying null
  • Loading branch information
EliuX committed Apr 24, 2020
commit 32a80b4c44eea9dda8803b46d84813f680242ae0
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_create_project_type_should_reject_bad_request(client: FlaskClient,
from time_tracker_api.project_types.project_types_namespace import project_type_dao
invalid_project_type_data = valid_project_type_data.copy()
invalid_project_type_data.update({
"parent_id": None,
"name": None,
})
repository_create_mock = mocker.patch.object(project_type_dao.repository,
'create',
Expand Down Expand Up @@ -166,7 +166,7 @@ def test_update_project_should_reject_bad_request(client: FlaskClient,
from time_tracker_api.project_types.project_types_namespace import project_type_dao
invalid_project_type_data = valid_project_type_data.copy()
invalid_project_type_data.update({
"parent_id": None,
"name": None,
})
repository_update_mock = mocker.patch.object(project_type_dao.repository,
'partial_update',
Expand Down
23 changes: 11 additions & 12 deletions tests/time_tracker_api/time_entries/time_entries_namespace_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from flask_restplus._http import HTTPStatus
from pytest_mock import MockFixture

from commons.data_access_layer.cosmos_db import current_datetime
from commons.data_access_layer.cosmos_db import current_datetime, current_datetime_str

fake = Faker()

Expand All @@ -16,14 +16,14 @@
"project_id": fake.uuid4(),
"activity_id": fake.uuid4(),
"description": fake.paragraph(nb_sentences=2),
"start_date": str(yesterday.isoformat()),
"owner_id": fake.uuid4(),
"tenant_id": fake.uuid4()
"start_date": current_datetime_str(),
}

fake_time_entry = ({
"id": fake.random_int(1, 9999),
"running": True,
"owner_id": fake.uuid4(),
"tenant_id": fake.uuid4(),
})
fake_time_entry.update(valid_time_entry_input)

Expand Down Expand Up @@ -86,21 +86,20 @@ def test_create_time_entry_should_succeed_with_valid_request(client: FlaskClient
repository_create_mock.assert_called_once()


def test_create_time_entry_should_reject_bad_request(client: FlaskClient,
mocker: MockFixture,
valid_header: dict):
def test_create_time_entry_with_missing_req_field_should_return_bad_request(client: FlaskClient,
mocker: MockFixture,
valid_header: dict):
from time_tracker_api.time_entries.time_entries_namespace import time_entries_dao
invalid_time_entry_input = valid_time_entry_input.copy()
invalid_time_entry_input.update({
"project_id": None,
})
repository_create_mock = mocker.patch.object(time_entries_dao.repository,
'create',
return_value=fake_time_entry)

response = client.post("/time-entries",
headers=valid_header,
json=invalid_time_entry_input,
json={
"activity_id": fake.uuid4(),
"start_date": current_datetime_str(),
},
follow_redirects=True)

assert HTTPStatus.BAD_REQUEST == response.status_code
Expand Down
6 changes: 3 additions & 3 deletions time_tracker_api/activities/activities_namespace.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from faker import Faker
from flask_restplus import fields, Resource, Namespace
from flask_restplus import fields, Resource
from flask_restplus._http import HTTPStatus

from time_tracker_api.activities.activities_model import create_dao
from time_tracker_api.api import common_fields
from time_tracker_api.api import common_fields, api

faker = Faker()

ns = Namespace('activities', description='API for activities')
ns = api.namespace('activities', description='Namespace of the API for activities')

# Activity Model
activity_input = ns.model('ActivityInput', {
Expand Down
21 changes: 14 additions & 7 deletions time_tracker_api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,37 @@ def create_attributes_filter(ns: namespace, model: Model, filter_attrib_names: l
return attribs_parser


# Common models structure
# Custom fields
class NullableString(fields.String):
__schema_type__ = ['string', 'null']


class UUID(NullableString):
def __init__(self, *args, **kwargs):
super(UUID, self).__init__(*args, **kwargs)
self.pattern = UUID_REGEX


common_fields = {
'id': fields.String(
'id': UUID(
title='Identifier',
readOnly=True,
required=True,
description='The unique identifier',
pattern=UUID_REGEX,
example=faker.uuid4(),
),
'tenant_id': fields.String(
'tenant_id': UUID(
title='Identifier of Tenant',
readOnly=True,
required=True,
description='Tenant it belongs to',
# pattern=UUID_REGEX, This must be confirmed
example=faker.uuid4(),
),
'deleted': fields.String(
'deleted': UUID(
readOnly=True,
required=True,
title='Last event Identifier',
description='Last event over this resource',
pattern=UUID_REGEX,
),
}

Expand Down
6 changes: 3 additions & 3 deletions time_tracker_api/customers/customers_namespace.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from faker import Faker
from flask_restplus import Namespace, Resource, fields
from flask_restplus import Resource, fields
from flask_restplus._http import HTTPStatus

from time_tracker_api.api import common_fields
from time_tracker_api.api import common_fields, api
from time_tracker_api.customers.customers_model import create_dao

faker = Faker()

ns = Namespace('customers', description='API for customers')
ns = api.namespace('customers', description='Namespace of the API for customers')

# Customer Model
customer_input = ns.model('CustomerInput', {
Expand Down
13 changes: 5 additions & 8 deletions time_tracker_api/project_types/project_types_namespace.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from faker import Faker
from flask_restplus import Namespace, Resource, fields
from flask_restplus import Resource, fields
from flask_restplus._http import HTTPStatus

from time_tracker_api.api import common_fields, create_attributes_filter
from time_tracker_api.api import common_fields, create_attributes_filter, api, UUID
from time_tracker_api.project_types.project_types_model import create_dao
from time_tracker_api.security import UUID_REGEX

faker = Faker()

ns = Namespace('project-types', description='API for project types')
ns = api.namespace('project-types', description='Namespace of the API for project types')

# ProjectType Model
project_type_input = ns.model('ProjectTypeInput', {
Expand All @@ -26,19 +25,17 @@
description='Comments about the project type',
example=faker.paragraph(),
),
'customer_id': fields.String(
'customer_id': UUID(
title='Identifier of the Customer',
required=False,
description='Customer this project type belongs to. '
'If not specified, it will be considered an internal project of the tenant.',
pattern=UUID_REGEX,
example=faker.uuid4(),
),
'parent_id': fields.String(
'parent_id': UUID(
title='Identifier of the parent project type',
required=False,
description='This parent node allows to created a tree-like structure for project types',
pattern=UUID_REGEX,
example=faker.uuid4(),
),
})
Expand Down
13 changes: 5 additions & 8 deletions time_tracker_api/projects/projects_namespace.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from faker import Faker
from flask_restplus import Namespace, Resource, fields
from flask_restplus import Resource, fields
from flask_restplus._http import HTTPStatus

from time_tracker_api.api import common_fields, create_attributes_filter
from time_tracker_api.api import common_fields, create_attributes_filter, UUID, api
from time_tracker_api.projects.projects_model import create_dao
from time_tracker_api.security import UUID_REGEX

faker = Faker()

ns = Namespace('projects', description='API for projects (clients)')
ns = api.namespace('projects', description='Namespace of the API for projects')

# Project Model
project_input = ns.model('ProjectInput', {
Expand All @@ -26,19 +25,17 @@
description='Description about the project',
example=faker.paragraph(),
),
'customer_id': fields.String(
'customer_id': UUID(
title='Identifier of the Customer',
required=False,
description='Customer this project type belongs to. '
'If not specified, it will be considered an internal project of the tenant.',
pattern=UUID_REGEX,
example=faker.uuid4(),
),
'project_type_id': fields.String(
'project_type_id': UUID(
title='Identifier of the project type',
required=False,
description='Id of the project type it belongs. This allows grouping the projects.',
pattern=UUID_REGEX,
example=faker.uuid4(),
),
})
Expand Down
15 changes: 6 additions & 9 deletions time_tracker_api/time_entries/time_entries_namespace.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
from datetime import timedelta

from faker import Faker
from flask_restplus import fields, Resource, Namespace
from flask_restplus import fields, Resource
from flask_restplus._http import HTTPStatus

from commons.data_access_layer.cosmos_db import current_datetime, datetime_str, current_datetime_str
from commons.data_access_layer.database import COMMENTS_MAX_LENGTH
from time_tracker_api.api import common_fields, create_attributes_filter
from time_tracker_api.security import UUID_REGEX
from time_tracker_api.api import common_fields, create_attributes_filter, api, UUID
from time_tracker_api.time_entries.time_entries_model import create_dao

faker = Faker()

ns = Namespace('time-entries', description='API for time entries')
ns = api.namespace('time-entries', description='Namespace of the API for time entries')

# TimeEntry Model
time_entry_input = ns.model('TimeEntryInput', {
'project_id': fields.String(
'project_id': UUID(
title='Project',
required=True,
description='The id of the selected project',
pattern=UUID_REGEX,
example=faker.uuid4(),
),
'start_date': fields.DateTime(
Expand All @@ -30,11 +28,10 @@
description='When the user started doing this activity',
example=datetime_str(current_datetime() - timedelta(days=1)),
),
'activity_id': fields.String(
'activity_id': UUID(
title='Activity',
required=False,
description='The id of the selected activity',
pattern=UUID_REGEX,
example=faker.uuid4(),
),
'description': fields.String(
Expand Down Expand Up @@ -86,7 +83,7 @@
description='Whether this time entry is currently running or not',
example=faker.boolean(),
),
'owner_id': fields.String(
'owner_id': UUID(
required=True,
readOnly=True,
title='Owner of time entry',
Expand Down