Skip to content

Commit

Permalink
test(kong): begin writing tests for kong
Browse files Browse the repository at this point in the history
  • Loading branch information
brucetony committed Mar 13, 2024
1 parent c18d156 commit 8f7753b
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 12 deletions.
7 changes: 1 addition & 6 deletions gateway/models/kong.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ class DataStoreType(Enum):
FHIR: str = "fhir"


class Services(BaseModel):
"""Data store list response model."""
data: list[Service]
offset: int | None = None


class ServiceRequest(CreateServiceRequest):
"""Improved version of the CreateServiceRequest with better defaults."""
protocol: str | None = "http"
Expand All @@ -27,6 +21,7 @@ class ServiceRequest(CreateServiceRequest):
client_certificate: CreateServiceRequestClientCertificate | None = None
tls_verify: bool | None = None
ca_certificates: list[str] | None = None
enabled: bool = True


class LinkDataStoreProject(BaseModel):
Expand Down
38 changes: 34 additions & 4 deletions gateway/routers/kong.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
from kong_admin_client.rest import ApiException
from starlette import status

# from gateway.auth import idp_oauth2_scheme
from gateway.conf import gateway_settings
from gateway.models.kong import Services, ServiceRequest, HttpMethodCode, ProtocolCode, LinkDataStoreProject, \
from gateway.models.kong import ServiceRequest, HttpMethodCode, ProtocolCode, LinkDataStoreProject, \
Disconnect, LinkProjectAnalysis

kong_router = APIRouter(
Expand All @@ -24,7 +23,7 @@
kong_admin_url = gateway_settings.KONG_ADMIN_SERVICE_URL


@kong_router.get("/datastore", response_model=Services)
@kong_router.get("/datastore", response_model=ListRoute200Response, status_code=status.HTTP_200_OK)
async def list_data_stores():
"""List all available data stores."""
configuration = kong_admin_client.Configuration(host=kong_admin_url)
Expand All @@ -49,7 +48,7 @@ async def list_data_stores():
)


@kong_router.get("/datastore/{project_name}", status_code=status.HTTP_200_OK, response_model=ListRoute200Response)
@kong_router.get("/datastore/{project_name}", response_model=ListRoute200Response, status_code=status.HTTP_200_OK)
async def list_data_stores_by_project(
project_name: Annotated[str, Path(description="Unique name of project.")]
):
Expand Down Expand Up @@ -84,6 +83,37 @@ async def list_data_stores_by_project(
)


@kong_router.delete("/datastore/{data_store_name}", status_code=status.HTTP_200_OK)
async def delete_data_store(
data_store_name: Annotated[str, Path(description="Unique name of the data store.")]
):
"""List all the data stores connected to this project."""
configuration = kong_admin_client.Configuration(host=kong_admin_url)

try:
with kong_admin_client.ApiClient(configuration) as api_client:
api_instance = kong_admin_client.ServicesApi(api_client)
api_instance.delete_service(service_id_or_name=data_store_name)

logger.info(f"Data store {data_store_name} deleted")

return status.HTTP_200_OK

except ApiException as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=str(e),
headers={"WWW-Authenticate": "Bearer"},
)

except Exception as e:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"Service error: {e}",
headers={"WWW-Authenticate": "Bearer"},
)


@kong_router.put("/datastore", response_model=Service, status_code=status.HTTP_201_CREATED)
async def create_data_store(data: Annotated[ServiceRequest, Body(
description="Required information for creating a new data store.",
Expand Down
2 changes: 1 addition & 1 deletion gateway/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@ def get_health() -> HealthCheck:
)

if __name__ == "__main__":
uvicorn.run("server:app", host="127.0.0.1", port=8081, reload=True)
uvicorn.run("server:app", host="127.0.0.1", port=8081)
35 changes: 34 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

from gateway.conf import gateway_settings
from gateway.server import app
from tests.pseudo_auth import get_oid_test_jwk, BearerAuth
from tests.constants import KONG_TEST_DS, KONG_TEST_PROJECT
from tests.pseudo_auth import get_oid_test_jwk, BearerAuth, fakeauth


@pytest.fixture(scope="package")
Expand Down Expand Up @@ -57,3 +58,35 @@ def hub_token() -> BearerAuth:
assert token

return BearerAuth(token)


@pytest.fixture(scope="module")
def setup_kong(test_client):
"""Setup Kong instance with test data."""
test_datastore = {
"name": KONG_TEST_DS,
"protocol": "http",
"host": "server.fire.ly",
"port": 80,
"path": "/mydefinedpath",
}
test_project_link = {
"data_store_id": KONG_TEST_DS,
"project_id": KONG_TEST_PROJECT,
"methods": [
"GET",
"POST",
"PUT",
"DELETE"
],
"ds_type": "fhir",
"protocols": ["http"],
}

test_client.put("/datastore", auth=fakeauth, json=test_datastore)
test_client.put("/datastore/project", auth=fakeauth, json=test_project_link)

yield

test_client.put(f"/disconnect/{KONG_TEST_PROJECT}", auth=fakeauth)
test_client.delete(f"/datastore/{KONG_TEST_DS}", auth=fakeauth)
3 changes: 3 additions & 0 deletions tests/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""String constants for tests."""
KONG_TEST_DS = "unitTestDataStore"
KONG_TEST_PROJECT = "unitTestProject"
39 changes: 39 additions & 0 deletions tests/test_kong.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Unit tests for the kong endpoints."""
from starlette import status

from tests.constants import KONG_TEST_DS, KONG_TEST_PROJECT
from tests.pseudo_auth import fakeauth


class TestKong:
"""Kong EP tests. Dependent on having a running instance of Kong and admin URL defined in ENV."""

def test_list_data_stores(self, test_client, setup_kong):
"""Test the list_data_stores method."""
r = test_client.get("/datastore", auth=fakeauth)
assert r.status_code == status.HTTP_200_OK

json_data = r.json()
data = json_data["data"]

assert len(data) # should not be none
assert isinstance(data, list)
assert len(data) > 0 # minimum 1

data_store_names = [ds["name"] for ds in data]
assert KONG_TEST_DS in data_store_names

def test_list_data_stores_by_project(self, test_client, setup_kong):
"""Test the list_data_stores_by_project method."""
r = test_client.get(f"/datastore/{KONG_TEST_PROJECT}", auth=fakeauth)
assert r.status_code == status.HTTP_200_OK

json_data = r.json()
data = json_data["data"]
assert len(data) == 1 # should only be one named this

data_store = data[0]

assert data_store["protocols"] == ["http"]
assert data_store["name"] == KONG_TEST_DS
assert data_store["methods"] == ["GET", "POST", "PUT", "DELETE"]

0 comments on commit 8f7753b

Please sign in to comment.