Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Commit

Permalink
initial pass - draft commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Rwolfe-Nava committed Aug 1, 2024
1 parent 9150efd commit 91f442b
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
7 changes: 7 additions & 0 deletions api/src/api/opportunities_v1/opportunity_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@
"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"
},
"close_date": {
"start_date": "2024-01-01",
}
},
"pagination": {
"order_by": "opportunity_id",
Expand Down
13 changes: 13 additions & 0 deletions api/src/api/opportunities_v1/opportunity_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,19 @@ class OpportunitySearchFilterV1Schema(Schema):
.build()
)

post_date = fields.Nested(
StrSearchSchemaBuilder("PostDateFilterV1Schema")
.with_start_date()
.with_end_date()
.build()
)

close_date = fields.Nested(
StrSearchSchemaBuilder("CloseDateFilterV1Schema")
.with_start_date()
.with_end_date()
.build()
)

class OpportunityFacetV1Schema(Schema):
opportunity_status = fields.Dict(
Expand Down
30 changes: 29 additions & 1 deletion api/src/api/schemas/search_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class StrSearchSchemaBuilder:
}
This helps generate the filters for a given field. At the moment,
only a one_of filter is implemented.
only a one_of filter is implemented. Support for start_date and
end_date filters have been partially implemented.
Usage::
Expand All @@ -68,6 +69,25 @@ class OpportunitySearchFilterSchema(Schema):
.with_one_of(example="example_value", minimum_length=5)
.build()
)
example_start_date_field = fields.Nested(
StrSearchSchemaBuilder("ExampleStartDateFieldSchema")
.with_start_date()
.build()
)
example_end_date_field = fields.Nested(
StrSearchSchemaBuilder("ExampleEndDateFieldSchema")
.with_end_date()
.build()
)
example_startend_date_field = fields.Nested(
StrSearchSchemaBuilder("ExampleStartEndDateFieldSchema")
.with_start_date()
.with_end_date()
.build()
)
"""

def __init__(self, schema_class_name: str):
Expand Down Expand Up @@ -102,6 +122,14 @@ def with_one_of(
self.schema_fields["one_of"] = fields.List(list_type, validate=[validators.Length(min=1)])

return self

def with_start_date(self) -> "StrSearchSchemaBuilder":
self.schema_fields["start_date"] = fields.Date(allow_none=True)
return self

def with_end_date(self) -> "StrSearchSchemaBuilder":
self.schema_fields["end_date"] = fields.Date(allow_none=True)
return self

def build(self) -> Schema:
return BaseSearchSchema.from_dict(self.schema_fields, name=self.schema_class_name) # type: ignore
8 changes: 8 additions & 0 deletions api/tests/src/api/opportunities_v1/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ def get_search_request(
applicant_type_one_of: list[ApplicantType] | None = None,
opportunity_status_one_of: list[OpportunityStatus] | None = None,
agency_one_of: list[str] | None = None,
post_date: dict | None = None,
close_date: dict | None = None,
format: str | None = None,
):
req = {
Expand Down Expand Up @@ -64,6 +66,12 @@ 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

if len(filters) > 0:
req["filters"] = filters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,47 @@ def test_search_filters_200(
):
call_search_and_validate(client, api_auth_token, search_request, expected_results)

@pytest.mark.parametrize(
"search_request, expected_status_code",
[
# Post Date
(get_search_request(post_date={"start_date": None}), 200),
(get_search_request(post_date={"end_date": None}), 200),
(get_search_request(post_date={"start_date": "2020-01-01"}), 200),
(get_search_request(post_date={"end_date": "2020-02-01"}), 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": "I am not a date"}), 422),
(get_search_request(post_date={"end_date": "I am not a date"}), 422),
# Close Date
(get_search_request(close_date={"start_date": None}), 200),
(get_search_request(close_date={"end_date": None}), 200),
(get_search_request(close_date={"start_date": "2020-01-01"}), 200),
(get_search_request(close_date={"end_date": "2020-02-01"}), 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": "I am not a date"}), 422),
(get_search_request(close_date={"end_date": "I am not a date"}), 422)
]
)
def test_search_validate_date_filters(
self, client, api_auth_token, search_request, expected_status_code
):
resp = client.post(
"/v1/opportunities/search", json=search_request, headers={"X-Auth": api_auth_token}
)
assert resp.status_code == expected_status_code

if resp.status_code == 422:
json = resp.get_json()
error = json["errors"][0]
assert json["message"] == "Validation error"
assert error["message"] == "Not a valid date."

@pytest.mark.parametrize(
"search_request, expected_results",
[
Expand Down

0 comments on commit 91f442b

Please sign in to comment.