diff --git a/api/src/api/opportunities_v1/opportunity_routes.py b/api/src/api/opportunities_v1/opportunity_routes.py index f618e58c5..c705cb20d 100644 --- a/api/src/api/opportunities_v1/opportunity_routes.py +++ b/api/src/api/opportunities_v1/opportunity_routes.py @@ -54,13 +54,10 @@ "funding_category": {"one_of": ["recovery_act", "arts", "natural_resources"]}, "funding_instrument": {"one_of": ["cooperative_agreement", "grant"]}, "opportunity_status": {"one_of": ["forecasted", "posted"]}, - "post_date": { - "start_date": "2024-01-01", - "end_date": "2024-02-01" - }, + "post_date": {"start_date": "2024-01-01", "end_date": "2024-02-01"}, "close_date": { "start_date": "2024-01-01", - } + }, }, "pagination": { "order_by": "opportunity_id", diff --git a/api/src/api/opportunities_v1/opportunity_schemas.py b/api/src/api/opportunities_v1/opportunity_schemas.py index bdc388221..e4392e96a 100644 --- a/api/src/api/opportunities_v1/opportunity_schemas.py +++ b/api/src/api/opportunities_v1/opportunity_schemas.py @@ -2,7 +2,7 @@ from src.api.schemas.extension import Schema, fields, validators from src.api.schemas.response_schema import AbstractResponseSchema, PaginationMixinSchema -from src.api.schemas.search_schema import StrSearchSchemaBuilder, DateSearchSchemaBuilder +from src.api.schemas.search_schema import DateSearchSchemaBuilder, StrSearchSchemaBuilder from src.constants.lookup_constants import ( ApplicantType, FundingCategory, @@ -322,19 +322,14 @@ class OpportunitySearchFilterV1Schema(Schema): ) post_date = fields.Nested( - DateSearchSchemaBuilder("PostDateFilterV1Schema") - .with_start_date() - .with_end_date() - .build() + DateSearchSchemaBuilder("PostDateFilterV1Schema").with_start_date().with_end_date().build() ) close_date = fields.Nested( - DateSearchSchemaBuilder("CloseDateFilterV1Schema") - .with_start_date() - .with_end_date() - .build() + DateSearchSchemaBuilder("CloseDateFilterV1Schema").with_start_date().with_end_date().build() ) + class OpportunityFacetV1Schema(Schema): opportunity_status = fields.Dict( keys=fields.String(), diff --git a/api/src/api/schemas/search_schema.py b/api/src/api/schemas/search_schema.py index e9fa890dd..adfe819e8 100644 --- a/api/src/api/schemas/search_schema.py +++ b/api/src/api/schemas/search_schema.py @@ -34,6 +34,7 @@ def validates_non_empty(self, data: dict, **kwargs: Any) -> None: ] ) + class BaseSearchSchemaBuilder: def __init__(self, schema_class_name: str): # The schema class name is used on the endpoint @@ -43,6 +44,7 @@ def __init__(self, schema_class_name: str): def build(self) -> Schema: return BaseSearchSchema.from_dict(self.schema_fields, name=self.schema_class_name) # type: ignore + class StrSearchSchemaBuilder(BaseSearchSchemaBuilder): """ Builder for setting up a filter in a search endpoint schema. @@ -77,6 +79,7 @@ class OpportunitySearchFilterSchema(Schema): .build() ) """ + def __init__(self, schema_class_name: str): super().__init__(schema_class_name) @@ -111,6 +114,7 @@ def with_one_of( def build(self) -> Schema: return super().build() + class DateSearchSchemaBuilder(BaseSearchSchemaBuilder): """ Builder for setting up a filter for a date in the search endpoint schema. @@ -150,16 +154,17 @@ class DateSearchSchemaBuilder(BaseSearchSchemaBuilder): .build() ) """ + def __init__(self, schema_class_name: str): super().__init__(schema_class_name) - def with_start_date(self) -> "StrSearchSchemaBuilder": + def with_start_date(self) -> "DateSearchSchemaBuilder": self.schema_fields["start_date"] = fields.Date(allow_none=True) return self - def with_end_date(self) -> "StrSearchSchemaBuilder": + def with_end_date(self) -> "DateSearchSchemaBuilder": self.schema_fields["end_date"] = fields.Date(allow_none=True) return self def build(self) -> Schema: - return super().build() \ No newline at end of file + return super().build() diff --git a/api/tests/src/api/opportunities_v1/conftest.py b/api/tests/src/api/opportunities_v1/conftest.py index 6e76fa71e..8b5e4c977 100644 --- a/api/tests/src/api/opportunities_v1/conftest.py +++ b/api/tests/src/api/opportunities_v1/conftest.py @@ -66,10 +66,10 @@ def get_search_request( if agency_one_of is not None: filters["agency"] = {"one_of": agency_one_of} - + if post_date is not None: filters["post_date"] = post_date - + if close_date is not None: filters["close_date"] = close_date diff --git a/api/tests/src/api/opportunities_v1/test_opportunity_route_search.py b/api/tests/src/api/opportunities_v1/test_opportunity_route_search.py index 8f8216d13..35fb409e8 100644 --- a/api/tests/src/api/opportunities_v1/test_opportunity_route_search.py +++ b/api/tests/src/api/opportunities_v1/test_opportunity_route_search.py @@ -721,7 +721,12 @@ def test_search_filters_200( (get_search_request(post_date={"start_date": None, "end_date": None}), 200), (get_search_request(post_date={"start_date": "2020-01-01", "end_date": None}), 200), (get_search_request(post_date={"start_date": None, "end_date": "2020-02-01"}), 200), - (get_search_request(post_date={"start_date": "2020-01-01", "end_date": "2020-02-01"}), 200), + ( + get_search_request( + post_date={"start_date": "2020-01-01", "end_date": "2020-02-01"} + ), + 200, + ), (get_search_request(post_date={"start_date": "I am not a date"}), 422), (get_search_request(post_date={"start_date": "123-456-789"}), 422), (get_search_request(post_date={"start_date": "5"}), 422), @@ -730,7 +735,6 @@ def test_search_filters_200( (get_search_request(post_date={"end_date": "123-456-789"}), 422), (get_search_request(post_date={"end_date": "5"}), 422), (get_search_request(post_date={"end_date": 5}), 422), - # Close Date (get_search_request(close_date={"start_date": None}), 200), (get_search_request(close_date={"end_date": None}), 200), @@ -739,7 +743,12 @@ def test_search_filters_200( (get_search_request(close_date={"start_date": None, "end_date": None}), 200), (get_search_request(close_date={"start_date": "2020-01-01", "end_date": None}), 200), (get_search_request(close_date={"start_date": None, "end_date": "2020-02-01"}), 200), - (get_search_request(close_date={"start_date": "2020-01-01", "end_date": "2020-02-01"}), 200), + ( + get_search_request( + close_date={"start_date": "2020-01-01", "end_date": "2020-02-01"} + ), + 200, + ), (get_search_request(close_date={"start_date": "I am not a date"}), 422), (get_search_request(close_date={"start_date": "123-456-789"}), 422), (get_search_request(close_date={"start_date": "5"}), 422), @@ -748,7 +757,7 @@ def test_search_filters_200( (get_search_request(close_date={"end_date": "123-456-789"}), 422), (get_search_request(close_date={"end_date": "5"}), 422), (get_search_request(close_date={"end_date": 5}), 422), - ] + ], ) def test_search_validate_date_filters( self, client, api_auth_token, search_request, expected_status_code