diff --git a/.gitignore b/.gitignore index 9699da54..c4f6932f 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,6 @@ migration_status.csv env.* # SSL certificate for cosmos emulator -emulatorcert.crt \ No newline at end of file +emulatorcert.crt + +seed_database.json \ No newline at end of file diff --git a/tests/time_tracker_api/projects/projects_model_test.py b/tests/time_tracker_api/projects/projects_model_test.py index 8579ab30..c6b63c40 100644 --- a/tests/time_tracker_api/projects/projects_model_test.py +++ b/tests/time_tracker_api/projects/projects_model_test.py @@ -5,11 +5,18 @@ CustomerCosmosDBModel, CustomerCosmosDBDao, ) +from time_tracker_api.project_types.project_types_model import ( + ProjectTypeCosmosDBModel, + ProjectTypeCosmosDBDao, +) from time_tracker_api.projects.projects_model import ( ProjectCosmosDBRepository, ProjectCosmosDBModel, create_dao, ) +from faker import Faker + +fake = Faker() @patch( @@ -77,3 +84,57 @@ def test_get_project_with_their_customer( assert isinstance(project, ProjectCosmosDBModel) assert project.__dict__['customer_name'] == customer_data['name'] + + +def test_get_all_projects_with_customers( + mocker, +): + customer_id = fake.uuid4() + project_type_id = fake.uuid4() + + customer_data = { + 'id': customer_id, + 'name': fake.company(), + 'description': fake.paragraph(), + 'tenant_id': fake.uuid4(), + } + + project_data = { + 'customer_id': customer_id, + 'id': fake.uuid4(), + 'name': fake.company(), + 'description': fake.paragraph(), + 'project_type_id': project_type_id, + 'tenant_id': fake.uuid4(), + } + + project_type_dao = { + 'id': project_type_id, + 'name': fake.name(), + 'description': fake.paragraph(), + 'tenant_id': fake.uuid4(), + } + + expected_customer = CustomerCosmosDBModel(customer_data) + expected_project = ProjectCosmosDBModel(project_data) + expected_project_type = ProjectTypeCosmosDBModel(project_type_dao) + + customer_dao_get_all_mock = mocker.patch.object( + CustomerCosmosDBDao, 'get_all' + ) + customer_dao_get_all_mock.return_value = [expected_customer] + + projects_repository_find_all_mock = mocker.patch.object( + ProjectCosmosDBRepository, 'find_all' + ) + projects_repository_find_all_mock.return_value = [expected_project] + + project_type_dao_get_all_mock = mocker.patch.object( + ProjectTypeCosmosDBDao, 'get_all' + ) + project_type_dao_get_all_mock.return_value = [expected_project_type] + projects = create_dao().get_all() + + assert isinstance(projects[0], ProjectCosmosDBModel) + assert projects[0].__dict__['customer_name'] == customer_data['name'] + assert len(projects) == 1 diff --git a/time_tracker_api/project_types/project_types_model.py b/time_tracker_api/project_types/project_types_model.py index 47f1eb13..9024e73e 100644 --- a/time_tracker_api/project_types/project_types_model.py +++ b/time_tracker_api/project_types/project_types_model.py @@ -2,7 +2,11 @@ from azure.cosmos import PartitionKey -from commons.data_access_layer.cosmos_db import CosmosDBModel, CosmosDBDao, CosmosDBRepository +from commons.data_access_layer.cosmos_db import ( + CosmosDBModel, + CosmosDBDao, + CosmosDBRepository, +) from time_tracker_api.database import CRUDDao, APICosmosDBDao @@ -17,7 +21,7 @@ class ProjectTypeDao(CRUDDao): 'uniqueKeys': [ {'paths': ['/name', '/customer_id', '/deleted']}, ] - } + }, } @@ -32,7 +36,9 @@ class ProjectTypeCosmosDBModel(CosmosDBModel): tenant_id: str def __init__(self, data): - super(ProjectTypeCosmosDBModel, self).__init__(data) # pragma: no cover + super(ProjectTypeCosmosDBModel, self).__init__( + data + ) # pragma: no cover def __repr__(self): return '' % self.name # pragma: no cover @@ -41,12 +47,13 @@ def __str___(self): return "the project type \"%s\"" % self.name # pragma: no cover -def create_dao() -> ProjectTypeDao: - repository = CosmosDBRepository.from_definition(container_definition, - mapper=ProjectTypeCosmosDBModel) +class ProjectTypeCosmosDBDao(APICosmosDBDao, ProjectTypeDao): + def __init__(self, repository): + CosmosDBDao.__init__(self, repository) - class ProjectTypeCosmosDBDao(APICosmosDBDao, ProjectTypeDao): - def __init__(self): - CosmosDBDao.__init__(self, repository) - return ProjectTypeCosmosDBDao() +def create_dao() -> ProjectTypeDao: + repository = CosmosDBRepository.from_definition( + container_definition, mapper=ProjectTypeCosmosDBModel + ) + return ProjectTypeCosmosDBDao(repository) diff --git a/time_tracker_api/projects/projects_model.py b/time_tracker_api/projects/projects_model.py index 805d6130..0d767251 100644 --- a/time_tracker_api/projects/projects_model.py +++ b/time_tracker_api/projects/projects_model.py @@ -134,15 +134,17 @@ def get_all( """ event_ctx = self.create_event_context("read-many") customer_dao = customers_create_dao() + customer_status = kwargs.get('customer_status', None) + customer_conditions = ( + {'status': customer_status} if customer_status else None + ) + customers = customer_dao.get_all( - max_count=kwargs.get('max_count', None) + conditions=customer_conditions, + max_count=kwargs.get('max_count', None), ) - customers_id = [ - customer.id - for customer in customers - if customer.status == 'active' - ] + customers_id = [customer.id for customer in customers] conditions = conditions if conditions else {} diff --git a/time_tracker_api/projects/projects_namespace.py b/time_tracker_api/projects/projects_namespace.py index 82dbaf2b..7030f63e 100644 --- a/time_tracker_api/projects/projects_namespace.py +++ b/time_tracker_api/projects/projects_namespace.py @@ -70,39 +70,45 @@ }, ) -project_type_nested_field = ns.model('ProjectType', { - 'name': fields.String( - title='Name', - required=True, - max_length=50, - description='Name of the project type', - example=faker.random_element(["Customer", "Training", "Internal"]), - ), - 'description': NullableString( - title='Description', - required=False, - max_length=250, - description='Comments about the project type', - example=faker.paragraph(), - ) -}) +project_type_nested_field = ns.model( + 'ProjectType', + { + 'name': fields.String( + title='Name', + required=True, + max_length=50, + description='Name of the project type', + example=faker.random_element(["Customer", "Training", "Internal"]), + ), + 'description': NullableString( + title='Description', + required=False, + max_length=250, + description='Comments about the project type', + example=faker.paragraph(), + ), + }, +) -customer_nested_field = ns.model('Customer', { - 'name': fields.String( - title='Name', - required=True, - max_length=50, - description='Name of the customer', - example=faker.company(), - ), - 'description': NullableString( - title='Description', - required=False, - max_length=250, - description='Description about the customer', - example=faker.paragraph(), - ) -}) +customer_nested_field = ns.model( + 'Customer', + { + 'name': fields.String( + title='Name', + required=True, + max_length=50, + description='Name of the customer', + example=faker.company(), + ), + 'description': NullableString( + title='Description', + required=False, + max_length=250, + description='Description about the customer', + example=faker.paragraph(), + ), + }, +) project_response_fields = { # TODO: Remove this DEAD CODE @@ -135,7 +141,9 @@ class Projects(Resource): def get(self): """List all projects""" conditions = attributes_filter.parse_args() - return project_dao.get_all(conditions=conditions) + return project_dao.get_all( + conditions=conditions, customer_status='active' + ) @ns.doc('create_project') @ns.response(HTTPStatus.CONFLICT, 'This project already exists')