diff --git a/deployments/api/API_REFERENCE.md b/deployments/api/API_REFERENCE.md
index 91871712..ee975323 100644
--- a/deployments/api/API_REFERENCE.md
+++ b/deployments/api/API_REFERENCE.md
@@ -54,7 +54,7 @@
**Request Body:** `OGFieldResource`
- `id`: integer | null
-- `source_data`: array[GemSource-Input | WoodMacSource-Input | RMISource-Input | LLMSource-Input]
+- `source_data`: array[GemSource-Input | WoodMacSource-Input | RMISource-Input | LLMSource-Input | CCRSource-Input | ALBSource-Input | BCSource-Input]
- `repointed_to`: integer | null
- `constituents`: array[integer]
- `provenance`: object[string, array[object] | null]
@@ -63,7 +63,7 @@
**Response:** `200`
- `id`: integer | null
-- `source_data`: array[GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView]
+- `source_data`: array[GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView | CCRSourceView | ALBSourceView | BCSourceView]
- `repointed_to`: integer | null
- `constituents`: array[integer]
- `provenance`: object[string, array[object] | null]
@@ -77,8 +77,12 @@
**Response:** `200`
-- `field`: string
-- `values`: array[string]
+- `basin`: array[string]
+- `country`: array[string]
+- `field_status`: array[string]
+- `primary_hydrocarbon_group`: array[string]
+- `region`: array[string]
+- `state_province`: array[string]
---
@@ -133,18 +137,7 @@
- `last_updated_by_id`: integer
- `reviewed_at`: string | null
- `reviewed_by_id`: integer | null
-
----
-
-### `GET /api/v1/oil-gas-fields/merge-candidates/{id}/preview`
-
-
-
-**Response:** `200`
-
-- `resource_ids`: array[integer]
-- `data`: OilGasFieldBase
-- `provenance`: object[string, string | null]
+- `compare`: array[FieldComparisonView]
---
@@ -219,6 +212,7 @@
- `fid_year`: integer | null
- `field_status`: string | null
- `id`: integer
+- `requested_resource_id`: integer | null
---
@@ -231,7 +225,8 @@
- `id`: integer
- `data`: OilGasFieldBase
- `provenance`: object[string, string | null]
-- `source_data`: array[GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView]
+- `source_data`: array[GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView | CCRSourceView | ALBSourceView | BCSourceView]
+- `requested_resource_id`: integer | null
---
@@ -245,16 +240,30 @@
---
+### `PUT /api/v1/oil-gas-fields/{id}/fields/{field}/sources/priority`
+
+
+
+**Request Body:** `SetFieldPriorityRequest`
+
+- `ordered_source_pks`: array[integer]
+
+**Response:** `200`
+
+- array[OGFieldSourceValueView]
+
+---
+
### `POST /api/v1/oil-gas-fields/{id}/sources`
-**Request Body:** GemSource-Input | WoodMacSource-Input | RMISource-Input | LLMSource-Input
+**Request Body:** GemSource-Input | WoodMacSource-Input | RMISource-Input | LLMSource-Input | CCRSource-Input | ALBSource-Input | BCSource-Input
**Response:** `200`
-- GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView
+- GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView | CCRSourceView | ALBSourceView | BCSourceView
---
@@ -264,12 +273,12 @@
-**Request Body:** GemSource-Input | WoodMacSource-Input | RMISource-Input | LLMSource-Input
+**Request Body:** GemSource-Input | WoodMacSource-Input | RMISource-Input | LLMSource-Input | CCRSource-Input | ALBSource-Input | BCSource-Input
**Response:** `200`
-- GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView
+- GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView | CCRSourceView | ALBSourceView | BCSourceView
---
@@ -279,7 +288,7 @@
**Response:** `200`
-- `items`: array[GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView]
+- `items`: array[GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView | CCRSourceView | ALBSourceView | BCSourceView]
- `total_count`: integer
- `page`: integer
- `page_size`: integer
@@ -293,7 +302,7 @@
**Response:** `200`
-- GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView
+- GemSourceView | WoodMacSourceView | RMISourceView | LLMSourceView | CCRSourceView | ALBSourceView | BCSourceView
---
@@ -303,6 +312,6 @@
**Response:** `200`
-- GemSource-Output | WoodMacSource-Output | RMISource-Output | LLMSource-Output
+- GemSource-Output | WoodMacSource-Output | RMISource-Output | LLMSource-Output | CCRSource-Output | ALBSource-Output | BCSource-Output
---
diff --git a/deployments/api/src/stitch/api/db/og_field_resource_actions.py b/deployments/api/src/stitch/api/db/og_field_resource_actions.py
index 540c4a75..0565aab2 100644
--- a/deployments/api/src/stitch/api/db/og_field_resource_actions.py
+++ b/deployments/api/src/stitch/api/db/og_field_resource_actions.py
@@ -14,8 +14,7 @@
)
from stitch.api.auth import CurrentUser
from stitch.api.entities import (
- FilterOptionField,
- OGFieldFilterOptionsParams,
+ FILTER_OPTION_FIELDS,
OGFieldQueryParams,
)
from stitch.api.db.og_field_source_actions import (
@@ -38,13 +37,11 @@
from .model.oil_gas_field_source_value import (
ATTRIBUTE_NAMES,
materialize_value,
- value_attr_for,
)
from .queries import (
- add_ranking,
base_resource_query,
- construct_base_query_statement,
field_source_candidates,
+ filter_option_rows,
)
from .utils import (
coalesce_resources,
@@ -53,7 +50,6 @@
)
-_FILTER_OPTION_FIELDS: frozenset[str] = frozenset(get_args(FilterOptionField))
_ALL_SOURCES: frozenset[OGSISrcKey] = frozenset(get_args(OGSISrcKey))
@@ -93,29 +89,13 @@ async def query(
async def filter_options(
session: AsyncSession,
- params: OGFieldFilterOptionsParams,
licensed_sources: Collection[OGSISrcKey] | None = None,
-) -> list[str]:
- """Return distinct coalesced resource values for one filterable field.
-
- Reads the shared coalescing core narrowed to the single field, so values are
- priority/override-coalesced and licensed before being deduped and sorted.
- ``params.source`` is ignored (see ``query``).
- """
- if params.field not in _FILTER_OPTION_FIELDS:
- raise HTTPException(
- status_code=422,
- detail=f"field={params.field} is not supported for resource filter options.",
- )
-
- base_cte = construct_base_query_statement(licensed_sources)
- filtered = select(base_cte).where(base_cte.c.colname == params.field).cte()
- ranked = add_ranking(filtered).cte("ranked")
- value_col = getattr(ranked.c, value_attr_for(params.field))
- labeled = value_col.label("value")
- stmt = select(labeled).where(value_col.is_not(None)).distinct().order_by(labeled)
- values = await session.scalars(stmt)
- return list(values.all())
+) -> dict[str, list[str]]:
+ """Distinct coalesced values for every filterable field, in one query."""
+ options: dict[str, list[str]] = {field: [] for field in FILTER_OPTION_FIELDS}
+ for colname, value in await session.execute(filter_option_rows(licensed_sources)):
+ options[colname].append(value)
+ return options
async def get(
diff --git a/deployments/api/src/stitch/api/db/queries.py b/deployments/api/src/stitch/api/db/queries.py
index 61a6781d..5f4ec5b3 100644
--- a/deployments/api/src/stitch/api/db/queries.py
+++ b/deployments/api/src/stitch/api/db/queries.py
@@ -38,7 +38,7 @@
ResourceModel,
)
from stitch.api.db.model.oil_gas_field_source_value import value_attr_for
-from stitch.api.entities import OGFieldQueryParams
+from stitch.api.entities import FILTER_OPTION_FIELDS, OGFieldQueryParams
from stitch.ogsi.model.types import OGSISrcKey
# Single source of truth for the source-list field metadata. This is a shared
@@ -88,6 +88,19 @@ def _participating_columns(params: OGFieldQueryParams) -> list[str]:
return list(dict.fromkeys(participating))
+def _override_join(resource_id: Any) -> ColumnElement[bool]:
+ """Join condition matching an override row to its value row."""
+ m = MembershipModel
+ v = OilGasFieldSourceValueModel
+ o = OGFieldResourceSourcePriority
+ return and_(
+ o.resource_id == resource_id,
+ o.source_pk == m.source_pk,
+ o.source == m.source,
+ o.colname == v.colname,
+ )
+
+
def construct_base_query_statement(
licensed_sources: Collection[OGSISrcKey] | None = None,
resource_ids: Collection[int] | None = None,
@@ -120,21 +133,7 @@ def construct_base_query_statement(
.join(p, p.source == m.source)
.join(s, and_(s.id == m.source_pk, s.source == m.source))
.join(v, v.source_pk == m.source_pk)
- # Override join at the value grain (source_pk, colname), matching v exactly,
- # so at most one override row per value row -- no fan-out. o.source ==
- # m.source is the same dual-key guard as the header join above: source_pk
- # and source aren't FK-tied, so matching source_pk alone could apply a
- # stray override with a mismatched (source, source_pk) pair to the wrong
- # membership. Requiring both fails safe to the default instead.
- .outerjoin(
- o,
- and_(
- o.resource_id == r.id,
- o.source_pk == m.source_pk,
- o.source == m.source,
- o.colname == v.colname,
- ),
- )
+ .outerjoin(o, _override_join(r.id))
.where(
r.repointed_id.is_(None),
m.status == MembershipStatus.ACTIVE,
@@ -250,6 +249,47 @@ def coalesced_winner_rows(
)
+def filter_option_rows(
+ licensed_sources: Collection[OGSISrcKey] | None = None,
+) -> Select[tuple[str, str]]:
+ """Distinct winning ``(colname, value)`` pairs for every filterable field."""
+ m = MembershipModel
+ v = OilGasFieldSourceValueModel
+ p = OGFieldSourcePriority
+ o = OGFieldResourceSourcePriority
+
+ base = (
+ select(
+ m.resource_id.label("resource_id"),
+ m.source.label("source"),
+ m.source_pk.label("source_pk"),
+ o.priority.label("override_priority"),
+ p.priority.label("default_priority"),
+ v.colname.label("colname"),
+ v.value_text,
+ )
+ .select_from(m)
+ .join(v, v.source_pk == m.source_pk)
+ .join(p, p.source == m.source)
+ .outerjoin(o, _override_join(m.resource_id))
+ .where(
+ m.status == MembershipStatus.ACTIVE,
+ v.colname.in_(FILTER_OPTION_FIELDS),
+ )
+ )
+ if licensed_sources is not None:
+ base = base.where(m.source.in_(list(dict.fromkeys(licensed_sources))))
+
+ ranked = add_ranking(base.cte("filter_option_base")).cte("filter_option_ranked")
+ c = ranked.c
+ return (
+ select(c.colname, c.value_text)
+ .where(c.value_text.is_not(None)) # rn == 1 already applied by add_ranking
+ .distinct()
+ .order_by(c.colname, c.value_text)
+ )
+
+
def field_source_candidates(
resource_id: int,
field: str,
diff --git a/deployments/api/src/stitch/api/entities.py b/deployments/api/src/stitch/api/entities.py
index 92752b8c..ca841be0 100644
--- a/deployments/api/src/stitch/api/entities.py
+++ b/deployments/api/src/stitch/api/entities.py
@@ -98,19 +98,6 @@ def total_pages(self) -> int:
"resource_id",
]
-FilterOptionField = Literal[
- "name",
- "name_local",
- "basin",
- "state_province",
- "region",
- "country",
- "field_status",
- "location_type",
- "production_conventionality",
- "primary_hydrocarbon_group",
-]
-
class OGFieldFilterParams(BaseModel):
q: str | None = None
@@ -136,14 +123,18 @@ class OGFieldQueryParams(PaginationParams, OGFieldFilterParams, OGFieldSortParam
source: list[OGSISrcKey] = Field(default_factory=lambda: list(OGSI_SOURCE_DEFAULT))
-class OGFieldFilterOptionsParams(BaseModel):
- field: FilterOptionField
- source: list[OGSISrcKey] = Field(default_factory=lambda: list(OGSI_SOURCE_DEFAULT))
+class OGFieldFilterOptionsResponse(BaseModel):
+ """Every filterable field's distinct coalesced values, one list per field."""
+ basin: list[str]
+ country: list[str]
+ field_status: list[str]
+ primary_hydrocarbon_group: list[str]
+ region: list[str]
+ state_province: list[str]
-class OGFieldFilterOptionsResponse(BaseModel):
- field: FilterOptionField
- values: list[str]
+
+FILTER_OPTION_FIELDS: tuple[str, ...] = tuple(OGFieldFilterOptionsResponse.model_fields)
class MergeCandidateStatus(StrEnum):
diff --git a/deployments/api/src/stitch/api/routers/oil_gas_fields.py b/deployments/api/src/stitch/api/routers/oil_gas_fields.py
index 4b5d4d7b..9e0c5c04 100644
--- a/deployments/api/src/stitch/api/routers/oil_gas_fields.py
+++ b/deployments/api/src/stitch/api/routers/oil_gas_fields.py
@@ -13,7 +13,6 @@
)
from stitch.api.entities import (
- OGFieldFilterOptionsParams,
OGFieldFilterOptionsResponse,
MergeCandidateCreateRequest,
MergeCandidateDetailView,
@@ -84,20 +83,20 @@ async def get_all_resources(
)
+# Must stay above GET /{id}: Starlette matches routes in declaration order, so a
+# later static path would be swallowed by the id route.
@router.get("/filter-options", response_model=OGFieldFilterOptionsResponse)
async def get_resource_filter_options(
*,
uow: UnitOfWorkDep,
_user: CurrentUser,
claims: Claims,
- params: Annotated[OGFieldFilterOptionsParams, Query()],
) -> OGFieldFilterOptionsResponse:
- values = await resource_actions.filter_options(
+ opts = await resource_actions.filter_options(
session=uow.session,
- params=params,
licensed_sources=licensed_sources(claims),
)
- return OGFieldFilterOptionsResponse(field=params.field, values=values)
+ return OGFieldFilterOptionsResponse(**opts)
@router.get(
diff --git a/deployments/api/tests/db/test_resource_actions.py b/deployments/api/tests/db/test_resource_actions.py
index 1f048271..3699581f 100644
--- a/deployments/api/tests/db/test_resource_actions.py
+++ b/deployments/api/tests/db/test_resource_actions.py
@@ -21,8 +21,9 @@
OilGasFieldSourceValueModel,
ResourceModel,
)
+from stitch.api.db.queries import filter_option_rows
from stitch.api.entities import (
- OGFieldFilterOptionsParams,
+ FILTER_OPTION_FIELDS,
OGFieldQueryParams,
User,
)
@@ -955,6 +956,7 @@ async def test_returns_distinct_sorted_coalesced_values(
seeded_integration_session,
test_user,
{"source": "rmi", "country": "USA"},
+ {"source": "llm", "country": "GBR"},
)
await _create_resource_with_sources(
seeded_integration_session,
@@ -967,12 +969,9 @@ async def test_returns_distinct_sorted_coalesced_values(
{"source": "rmi", "country": None},
)
- values = await resource_actions.filter_options(
- seeded_integration_session,
- OGFieldFilterOptionsParams(field="country"),
- )
+ options = await resource_actions.filter_options(seeded_integration_session)
- assert values == ["CAN", "USA"]
+ assert options["country"] == ["CAN", "USA"]
@pytest.mark.anyio
async def test_honors_licensed_sources_after_coalescing(
@@ -992,29 +991,51 @@ async def test_honors_licensed_sources_after_coalescing(
{"source": "rmi", "country": "USA"},
)
- values = await resource_actions.filter_options(
+ options = await resource_actions.filter_options(
seeded_integration_session,
- OGFieldFilterOptionsParams(field="country"),
licensed_sources=frozenset({"gem", "wm", "llm"}),
)
- assert values == ["CAN"]
+ assert options["country"] == ["CAN"]
@pytest.mark.anyio
- async def test_excludes_repointed_and_inactive_memberships(
+ async def test_licensing_promotes_next_priority_value(
self,
seeded_integration_session: AsyncSession,
test_user: User,
):
- active_id = await _create_resource_with_sources(
+ """Dropping the winning source's license promotes the runner-up value,
+ rather than blanking the field.
+ """
+ await _create_resource_with_sources(
seeded_integration_session,
test_user,
- {"source": "rmi", "country": "USA"},
+ {"source": "wm", "country": "USA"},
+ {"source": "gem", "country": "CAN"},
)
- repointed_to_id = await _create_resource_with_sources(
+
+ with_wm = await resource_actions.filter_options(
+ seeded_integration_session,
+ licensed_sources=frozenset({"gem", "wm"}),
+ )
+ assert with_wm["country"] == ["USA"]
+
+ without_wm = await resource_actions.filter_options(
+ seeded_integration_session,
+ licensed_sources=frozenset({"gem"}),
+ )
+ assert without_wm["country"] == ["CAN"]
+
+ @pytest.mark.anyio
+ async def test_excludes_inactive_memberships(
+ self,
+ seeded_integration_session: AsyncSession,
+ test_user: User,
+ ):
+ await _create_resource_with_sources(
seeded_integration_session,
test_user,
- {"source": "rmi", "country": "BRA"},
+ {"source": "rmi", "country": "USA"},
)
inactive_id = await _create_resource_with_sources(
seeded_integration_session,
@@ -1022,12 +1043,6 @@ async def test_excludes_repointed_and_inactive_memberships(
{"source": "rmi", "country": "CAN"},
)
- repointed_resource = await seeded_integration_session.get(
- ResourceModel, repointed_to_id
- )
- assert repointed_resource is not None
- repointed_resource.repointed_id = active_id
-
inactive_membership = await seeded_integration_session.scalar(
select(MembershipModel).where(MembershipModel.resource_id == inactive_id)
)
@@ -1035,36 +1050,68 @@ async def test_excludes_repointed_and_inactive_memberships(
inactive_membership.status = MembershipStatus.INACTIVE
await seeded_integration_session.flush()
- values = await resource_actions.filter_options(
+ options = await resource_actions.filter_options(seeded_integration_session)
+
+ assert options["country"] == ["USA"]
+
+ @pytest.mark.anyio
+ async def test_returns_every_field_including_empty_ones(
+ self,
+ seeded_integration_session: AsyncSession,
+ test_user: User,
+ ):
+ await _create_resource_with_sources(
seeded_integration_session,
- OGFieldFilterOptionsParams(field="country"),
+ test_user,
+ {"source": "rmi", "country": "USA"},
)
- assert values == ["USA"]
+ options = await resource_actions.filter_options(seeded_integration_session)
- def test_postgres_distinct_query_orders_by_selected_value_alias(self):
- """The rewritten filter_options construction compiles on Postgres.
+ assert set(options.keys()) == set(FILTER_OPTION_FIELDS)
+ assert options["country"] == ["USA"]
+ assert options["field_status"] == []
+ assert options["basin"] == []
- Mirrors ``filter_options``: distinct over the coalesced value column for
- one field, ordered by the selected alias.
- """
- params = OGFieldFilterOptionsParams(field="basin")
- base_cte = resource_actions.construct_base_query_statement(
- licensed_sources=frozenset({"gem", "wm", "rmi", "llm"}),
+ @pytest.mark.anyio
+ async def test_returns_each_field_from_one_pass(
+ self,
+ seeded_integration_session: AsyncSession,
+ test_user: User,
+ ):
+ await _create_resource_with_sources(
+ seeded_integration_session,
+ test_user,
+ {
+ "source": "rmi",
+ "country": "USA",
+ "state_province": "Texas",
+ "basin": "Permian",
+ "region": "North America",
+ },
)
- filtered = (
- resource_actions.select(base_cte)
- .where(base_cte.c.colname == params.field)
- .cte()
+ await _create_resource_with_sources(
+ seeded_integration_session,
+ test_user,
+ {
+ "source": "gem",
+ "country": "CAN",
+ "state_province": "Alberta",
+ "basin": "Texas",
+ },
)
- ranked = resource_actions.add_ranking(filtered).cte("ranked")
- value_col = getattr(ranked.c, resource_actions.value_attr_for(params.field))
- labeled = value_col.label("value")
- stmt = (
- resource_actions.select(labeled)
- .where(value_col.is_not(None), value_col != "")
- .distinct()
- .order_by(labeled)
+
+ options = await resource_actions.filter_options(seeded_integration_session)
+
+ assert options["country"] == ["CAN", "USA"]
+ assert options["state_province"] == ["Alberta", "Texas"]
+ assert options["basin"] == ["Permian", "Texas"]
+ assert options["region"] == ["North America"]
+
+ def test_postgres_distinct_query_orders_by_selected_columns(self):
+ """``filter_option_rows`` compiles on Postgres."""
+ stmt = filter_option_rows(
+ licensed_sources=frozenset({"gem", "wm", "rmi", "llm"}),
)
sql = str(
@@ -1074,8 +1121,10 @@ def test_postgres_distinct_query_orders_by_selected_value_alias(self):
)
)
- assert "SELECT DISTINCT ranked.value_text AS value" in sql
- assert "ORDER BY value" in sql
+ assert "SELECT DISTINCT" in sql
+ assert "ORDER BY" in sql
+ ordered = sql[sql.index("ORDER BY") :]
+ assert "colname" in ordered and "value_text" in ordered
@pytest.mark.anyio
async def test_only_unlicensed_selected_sources_still_return_resource(
diff --git a/deployments/api/tests/routers/test_query_param_validation.py b/deployments/api/tests/routers/test_query_param_validation.py
index 9e326814..2d6a97f0 100644
--- a/deployments/api/tests/routers/test_query_param_validation.py
+++ b/deployments/api/tests/routers/test_query_param_validation.py
@@ -61,16 +61,6 @@ async def test_sort_by_source_returns_422(self, integration_client: AsyncClient)
)
assert resp.status_code == 422
- @pytest.mark.anyio
- async def test_invalid_filter_options_field_returns_422(
- self, async_client: AsyncClient
- ):
- """filter-options field must be one of the supported coalesced scalar fields."""
- resp = await async_client.get(
- "/oil-gas-fields/filter-options", params={"field": "owners"}
- )
- assert resp.status_code == 422
-
@pytest.mark.anyio
async def test_unknown_field_in_sources_path_returns_422(
self, async_client: AsyncClient
diff --git a/deployments/api/tests/routers/test_resources_unit.py b/deployments/api/tests/routers/test_resources_unit.py
index e9388be6..408d5c04 100644
--- a/deployments/api/tests/routers/test_resources_unit.py
+++ b/deployments/api/tests/routers/test_resources_unit.py
@@ -229,17 +229,31 @@ async def override_get_uow():
app.dependency_overrides[get_uow] = override_get_uow
with patch("stitch.api.routers.oil_gas_fields.resource_actions") as mock_repo:
- mock_repo.filter_options = AsyncMock(return_value=["CAN", "USA"])
-
- response = await async_client.get(
- "/oil-gas-fields/filter-options?field=country"
+ mock_repo.filter_options = AsyncMock(
+ return_value=dict(
+ basin=["Permian"],
+ country=["CAN", "USA"],
+ field_status=[],
+ primary_hydrocarbon_group=[],
+ region=["North America"],
+ state_province=["Alberta", "Texas"],
+ )
)
+ response = await async_client.get("/oil-gas-fields/filter-options")
+
assert response.status_code == 200
- assert response.json() == {"field": "country", "values": ["CAN", "USA"]}
+ assert response.json() == {
+ "basin": ["Permian"],
+ "country": ["CAN", "USA"],
+ "field_status": [],
+ "primary_hydrocarbon_group": [],
+ "region": ["North America"],
+ "state_province": ["Alberta", "Texas"],
+ }
@pytest.mark.anyio
- async def test_passes_licensed_sources_and_source_filters(
+ async def test_passes_licensed_sources(
self,
async_client,
mock_uow,
@@ -250,17 +264,22 @@ async def override_get_uow():
app.dependency_overrides[get_uow] = override_get_uow
with patch("stitch.api.routers.oil_gas_fields.resource_actions") as mock_repo:
- mock_repo.filter_options = AsyncMock(return_value=["CAN", "USA"])
-
- response = await async_client.get(
- "/oil-gas-fields/filter-options?field=country&source=gem&source=wm"
+ mock_repo.filter_options = AsyncMock(
+ return_value=dict(
+ basin=[],
+ country=["CAN", "USA"],
+ field_status=[],
+ primary_hydrocarbon_group=[],
+ region=[],
+ state_province=[],
+ )
)
+ response = await async_client.get("/oil-gas-fields/filter-options")
+
assert response.status_code == 200
mock_repo.filter_options.assert_awaited_once()
call_kwargs = mock_repo.filter_options.call_args.kwargs
assert call_kwargs["licensed_sources"] == frozenset(
{"rmi", "gem", "wm", "ccr", "alb", "bc", "llm"}
)
- assert call_kwargs["params"].field == "country"
- assert call_kwargs["params"].source == ["gem", "wm"]
diff --git a/deployments/stitch-frontend/src/components/FilterBar.jsx b/deployments/stitch-frontend/src/components/FilterBar.jsx
index 71801b79..64865730 100644
--- a/deployments/stitch-frontend/src/components/FilterBar.jsx
+++ b/deployments/stitch-frontend/src/components/FilterBar.jsx
@@ -2,35 +2,9 @@ import FilterDropdown from "./FilterDropdown";
import { FILTER_FIELDS, EMPTY_FILTERS } from "../config/filters";
import { useResourceFilterOptions } from "../hooks/useResources";
-function FilterFieldDropdown({
- endpoint,
- field,
- label,
- formatValue,
- selected,
- onChange,
-}) {
- const { data } = useResourceFilterOptions(endpoint, field);
- // The API sorts by the stored value, which can differ from the order of the
- // labels we display (country codes vs. country names), so sort by label.
- const options = (data?.values ?? [])
- .map((value) => ({
- value,
- label: formatValue ? formatValue(value) : value,
- }))
- .sort((a, b) => a.label.localeCompare(b.label, "en"));
-
- return (
-