diff --git a/middleware/primary_resource_logic/agencies.py b/middleware/primary_resource_logic/agencies.py index 04d95cba..7182ec30 100644 --- a/middleware/primary_resource_logic/agencies.py +++ b/middleware/primary_resource_logic/agencies.py @@ -3,6 +3,7 @@ from flask import Response, request from database_client.database_client import DatabaseClient +from database_client.db_client_dataclasses import OrderByParameters from database_client.subquery_logic import SubqueryParameterManager from middleware.access_logic import AccessInfo from middleware.custom_dataclasses import DeferredFunction @@ -49,7 +50,13 @@ def get_agencies( entry_name="agencies", relation=Relations.AGENCIES_EXPANDED.value, db_client_method=DatabaseClient.get_agencies, - db_client_additional_args={"build_metadata": True}, + db_client_additional_args={ + "build_metadata": True, + "order_by": OrderByParameters.construct_from_args( + sort_by=dto.sort_by, + sort_order=dto.sort_order + ), + }, subquery_parameters=SUBQUERY_PARAMS, ), page=dto.page, diff --git a/middleware/primary_resource_logic/data_requests.py b/middleware/primary_resource_logic/data_requests.py index 30979793..332b2392 100644 --- a/middleware/primary_resource_logic/data_requests.py +++ b/middleware/primary_resource_logic/data_requests.py @@ -233,7 +233,13 @@ def get_data_requests_wrapper( :param access_info: :return: """ - db_client_additional_args = {"build_metadata": True} + db_client_additional_args = { + "build_metadata": True, + "order_by": OrderByParameters.construct_from_args( + sort_by=dto.sort_by, + sort_order=dto.sort_order + ) + } if dto.request_status is not None: db_client_additional_args["where_mappings"] = { "request_status": dto.request_status.value diff --git a/tests/helper_scripts/helper_classes/RequestValidator.py b/tests/helper_scripts/helper_classes/RequestValidator.py index 46e880b4..99b43142 100644 --- a/tests/helper_scripts/helper_classes/RequestValidator.py +++ b/tests/helper_scripts/helper_classes/RequestValidator.py @@ -7,8 +7,10 @@ from flask.testing import FlaskClient from marshmallow import Schema +from database_client.enums import SortOrder, RequestStatus from middleware.util import update_if_not_none from resources.endpoint_schema_config import SchemaConfigs +from tests.helper_scripts.constants import DATA_REQUESTS_BY_ID_ENDPOINT from tests.helper_scripts.helper_functions import get_authorization_header, add_query_params from tests.helper_scripts.run_and_validate_request import http_methods, run_and_validate_request from utilities.enums import RecordCategories @@ -258,4 +260,40 @@ def get_user_by_id( headers=headers, expected_schema=expected_schema, expected_response_status=expected_response_status + ) + + def update_data_request( + self, + data_request_id: int, + headers: dict, + entry_data: dict + ): + return self.put( + endpoint=DATA_REQUESTS_BY_ID_ENDPOINT.format( + data_request_id=data_request_id), + headers=headers, + json={"entry_data": entry_data} + ) + + def get_data_requests( + self, + headers: dict, + request_status: Optional[RequestStatus] = None, + sort_by: Optional[str] = None, + sort_order: Optional[SortOrder] = None + ): + query_params = {} + update_if_not_none( + dict_to_update=query_params, + secondary_dict={ + "sort_by": sort_by, + "sort_order": sort_order.value if sort_order is not None else None, + "request_status": request_status.value if request_status is not None else None + }, + ) + return self.get( + endpoint="/api/data-requests", + headers=headers, + query_parameters=query_params, + expected_schema=SchemaConfigs.DATA_REQUESTS_GET_MANY.value.primary_output_schema ) \ No newline at end of file diff --git a/tests/integration/test_agencies.py b/tests/integration/test_agencies.py index e2e8095e..2da0f75b 100644 --- a/tests/integration/test_agencies.py +++ b/tests/integration/test_agencies.py @@ -68,7 +68,7 @@ def test_agencies_get(test_data_creator_flask: TestDataCreatorFlask): response_json = run_and_validate_request( flask_client=tdc.flask_client, http_method="get", - endpoint=AGENCIES_BASE_ENDPOINT + "?page=2", + endpoint=AGENCIES_BASE_ENDPOINT + "?page=1&sort_by=name&sort_order=ASC", headers=tus.api_authorization_header, expected_schema=SchemaConfigs.AGENCIES_GET_MANY.value.primary_output_schema, ) @@ -77,6 +77,24 @@ def test_agencies_get(test_data_creator_flask: TestDataCreatorFlask): response_json=response_json, expected_non_null_columns=["id"], ) + data_asc = response_json["data"] + + response_json = run_and_validate_request( + flask_client=tdc.flask_client, + http_method="get", + endpoint=AGENCIES_BASE_ENDPOINT + "?page=1&sort_by=name&sort_order=DESC", + headers=tus.api_authorization_header, + expected_schema=SchemaConfigs.AGENCIES_GET_MANY.value.primary_output_schema, + ) + + assert_expected_get_many_result( + response_json=response_json, + expected_non_null_columns=["id"], + ) + data_desc = response_json["data"] + + assert data_asc != data_desc + assert data_asc[0]["name"] < data_desc[0]["name"] def test_agencies_get_by_id(test_data_creator_flask: TestDataCreatorFlask): diff --git a/tests/integration/test_data_requests.py b/tests/integration/test_data_requests.py index 1f444e65..99240e1e 100644 --- a/tests/integration/test_data_requests.py +++ b/tests/integration/test_data_requests.py @@ -9,7 +9,7 @@ from database_client.database_client import DatabaseClient from database_client.db_client_dataclasses import WhereMapping -from database_client.enums import RequestUrgency, LocationType, RequestStatus +from database_client.enums import RequestUrgency, LocationType, RequestStatus, SortOrder from middleware.constants import DATA_KEY from middleware.enums import PermissionsEnum, RecordType from middleware.util import get_enum_values @@ -63,9 +63,9 @@ def test_data_requests_get( ): tdc = test_data_creator_flask + # Delete all data from the data requests table tdc.db_client.execute_raw_sql("""DELETE FROM data_requests""") tdc.clear_test_data() - # Delete all data from the data requests table tus_creator = tdc.standard_user() @@ -78,72 +78,59 @@ def test_data_requests_get( data_source_id=ds_info.id, ) - # Add another data source, and set its approval status to `Active` + # Add another data_request, and set its approval status to `Active` dr_info_2 = tdc.data_request(tus_creator) - json_data = run_and_validate_request( - flask_client=tdc.flask_client, - http_method="put", - endpoint=DATA_REQUESTS_BY_ID_ENDPOINT.format(data_request_id=dr_info_2.id), + tdc.request_validator.update_data_request( + data_request_id=dr_info_2.id, headers=tdc.get_admin_tus().jwt_authorization_header, - json={"entry_data": {"request_status": "Active"}}, + entry_data={"request_status": "Active"}, ) - expected_schema = SchemaConfigs.DATA_REQUESTS_GET_MANY.value.primary_output_schema - # Modify exclude to account for old data which did not have archive_reason and creator_user_id - expected_schema.exclude.update( - ["data.archive_reason", "data.creator_user_id", "data.internal_notes"] - ) - json_data = run_and_validate_request( - flask_client=tdc.flask_client, - http_method="get", - endpoint=DATA_REQUESTS_BASE_ENDPOINT, + data = tdc.request_validator.get_data_requests( headers=tus_creator.jwt_authorization_header, - expected_schema=expected_schema, - ) - assert len(json_data[DATA_KEY]) == 2 + )[DATA_KEY] - # Validate that at least one entry returned has data_sources - # TODO: This passes in test but not stage, which uses actual data requests which are not yet linked to data sources. - # an_entry_has_data_sources = False - # for entry in json_data[DATA_KEY]: - # data_sources = entry["data_sources"] - # if len(data_sources) > 0: - # DataSourceExpandedSchema().load(data_sources[0]) - # an_entry_has_data_sources = True - # break - # assert an_entry_has_data_sources + assert len(data) == 2 # Give user admin permission tdc.db_client.add_user_permission( user_email=tus_creator.user_info.email, permission=PermissionsEnum.DB_WRITE ) - admin_json_data = run_and_validate_request( - flask_client=tdc.flask_client, - http_method="get", - endpoint=DATA_REQUESTS_BASE_ENDPOINT, + admin_data = tdc.request_validator.get_data_requests( headers=tus_creator.jwt_authorization_header, - ) + )[DATA_KEY] # Assert admin columns are greater than user columns - assert len(admin_json_data[DATA_KEY][0]) > len(json_data[DATA_KEY][0]) + assert len(admin_data[0]) > len(data[0]) # Run get again, this time filtering the request status to be active - json_data = run_and_validate_request( - flask_client=tdc.flask_client, - http_method="get", - endpoint=add_query_params( - url=DATA_REQUESTS_BASE_ENDPOINT, - params={"request_status": "Active"}, - ), + data = tdc.request_validator.get_data_requests( headers=tus_creator.jwt_authorization_header, - expected_schema=expected_schema, - ) + request_status=RequestStatus.ACTIVE + )[DATA_KEY] # The more recent data request should be returned, but the old one should be filtered out - assert len(json_data[DATA_KEY]) == 1 - assert int(json_data[DATA_KEY][0]["id"]) == int(dr_info_2.id) + assert len(data) == 1 + assert int(data[0]["id"]) == int(dr_info_2.id) + + # Create additional intake data request to populate + tdc.data_request(tus_creator) + + # Test sorting + def get_sorted_data_requests(sort_order: SortOrder): + return tdc.request_validator.get_data_requests( + headers=tus_creator.jwt_authorization_header, + request_status=RequestStatus.INTAKE, + sort_by="id", + sort_order=sort_order, + ) + + data_asc = get_sorted_data_requests(SortOrder.ASCENDING)[DATA_KEY] + data_desc = get_sorted_data_requests(SortOrder.DESCENDING)[DATA_KEY] + + assert int(data_asc[0]["id"]) < int(data_desc[0]["id"]) def test_data_requests_post(