Skip to content

Commit 14a4acd

Browse files
add /bpa/organizations/autoregister route with tests
1 parent 996583c commit 14a4acd

2 files changed

Lines changed: 88 additions & 1 deletion

File tree

routers/bpa_register.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import httpx
12
import logging
3+
24
from datetime import datetime, timezone
5+
from typing import List
36

47
from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
58
from httpx import HTTPStatusError
69
from sqlmodel import Session
10+
from starlette import status
711
from starlette.responses import JSONResponse
812

913
from auth.ses import EmailService
@@ -13,9 +17,10 @@
1317
from db.setup import get_db_session
1418
from routers.errors import RegistrationRoute
1519
from schemas.biocommons import Auth0UserData, BiocommonsRegisterData
16-
from schemas.bpa import BPARegistrationRequest
20+
from schemas.bpa import BPARegistrationRequest, OrgOut
1721
from schemas.responses import RegistrationErrorResponse, RegistrationResponse
1822
from schemas.service import Resource, Service
23+
from services.ckan_client import CKANClient, get_ckan_client
1924

2025
logger = logging.getLogger(__name__)
2126

@@ -142,3 +147,36 @@ def _create_bpa_user_record(auth0_user_data: Auth0UserData, session: Session) ->
142147
session.add(bpa_membership)
143148
session.commit()
144149
return db_user
150+
151+
@router.get(
152+
"/organizations/autoregister",
153+
response_model=List[OrgOut],
154+
summary="List CKAN organizations eligible for auto-registration",
155+
)
156+
def list_autoregister_organizations(
157+
ckan: CKANClient = Depends(get_ckan_client),
158+
) -> List[OrgOut]:
159+
"""
160+
Returns the minimal set of CKAN organizations eligible for auto-registration,
161+
suitable for populating the portal dropdown.
162+
"""
163+
try:
164+
return ckan.get_autoregister_organizations()
165+
except httpx.HTTPError as e:
166+
# Network / HTTP errors talking to CKAN
167+
raise HTTPException(
168+
status_code=status.HTTP_502_BAD_GATEWAY,
169+
detail=f"Upstream CKAN error: {str(e)}",
170+
)
171+
except ValueError as e:
172+
# CKAN Action API returned success=false
173+
raise HTTPException(
174+
status_code=status.HTTP_502_BAD_GATEWAY,
175+
detail=str(e),
176+
)
177+
except Exception:
178+
# Unknown error
179+
raise HTTPException(
180+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
181+
detail="Unexpected server error.",
182+
)

tests/test_bpa_register.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
PlatformMembership,
1111
PlatformMembershipHistory,
1212
)
13+
from main import app
1314
from schemas import Service
1415
from schemas.biocommons import BiocommonsRegisterData
1516
from tests.datagen import (
1617
Auth0UserDataFactory,
1718
BPARegistrationDataFactory,
1819
random_auth0_id,
1920
)
21+
from services.ckan_client import get_ckan_client
2022

2123

2224
@pytest.fixture
@@ -272,3 +274,50 @@ def test_all_organizations_selected(
272274
assert len(bpa_service.resources) == len(mock_settings.organizations)
273275

274276
email_service_cls.return_value.send.assert_called_once()
277+
278+
279+
class _DummyCKAN:
280+
def __init__(self, return_value=None, raise_exc=None):
281+
self.return_value = [] if return_value is None else return_value
282+
self.raise_exc = raise_exc
283+
self.called = False
284+
285+
def get_autoregister_organizations(self):
286+
self.called = True
287+
if self.raise_exc:
288+
raise self.raise_exc
289+
return self.return_value
290+
291+
292+
def test_get_bpa_orgs_success(test_client):
293+
"""Test successful retrieval of BPA organizations."""
294+
mock_organizations = [
295+
{"id": "org1", "name": "Org One", "title": "Org One"},
296+
{"id": "org2", "name": "Org Two", "title": "Org Two"},
297+
{"id": "org3", "name": "Org Three", "title": "Org Three"},
298+
]
299+
dummy = _DummyCKAN(return_value=mock_organizations)
300+
301+
# Override the FastAPI dependency used by the route
302+
app.dependency_overrides[get_ckan_client] = lambda: dummy
303+
try:
304+
response = test_client.get("/bpa/organizations/autoregister")
305+
finally:
306+
app.dependency_overrides.pop(get_ckan_client, None)
307+
308+
assert response.status_code == 200
309+
assert response.json() == mock_organizations
310+
assert dummy.called is True
311+
312+
313+
def test_get_bpa_orgs_failure(test_client):
314+
"""If the underlying client raises, expect a 502 from the error handler."""
315+
dummy = _DummyCKAN(raise_exc=ValueError("boom"))
316+
317+
app.dependency_overrides[get_ckan_client] = lambda: dummy
318+
try:
319+
response = test_client.get("/bpa/organizations/autoregister")
320+
finally:
321+
app.dependency_overrides.pop(get_ckan_client, None)
322+
323+
assert response.status_code == 502

0 commit comments

Comments
 (0)