Skip to content

Commit

Permalink
add config endpoint tests
Browse files Browse the repository at this point in the history
  • Loading branch information
diversemix committed Sep 21, 2023
1 parent 9d90789 commit 21cabf9
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 12 deletions.
11 changes: 3 additions & 8 deletions app/api/api_v1/routers/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from fastapi import APIRouter, HTTPException, Request, status
from app.model.config import ConfigReadDTO
import app.service.config as config_service
from app.errors import RepositoryError

Expand All @@ -9,8 +10,8 @@
_LOGGER = logging.getLogger(__file__)


@r.get("/config")
async def get_config(request: Request):
@r.get("/config", response_model=ConfigReadDTO)
async def get_config(request: Request) -> ConfigReadDTO:
user = request.state.user
_LOGGER.info(f"User {user.email} is getting config")
try:
Expand All @@ -19,10 +20,4 @@ async def get_config(request: Request):
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail=e.message
)

if config is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Config not found"
)

return config
1 change: 1 addition & 0 deletions app/repository/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
import app.repository.collection as collection_repo
import app.repository.app_user as app_user_repo
import app.clients.aws.s3bucket as s3bucket_repo
import app.repository.config as config_repo
9 changes: 8 additions & 1 deletion app/service/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
from app.errors import RepositoryError
from app.model.config import ConfigReadDTO
import app.repository.config as config_repo

from sqlalchemy import exc
Expand All @@ -9,7 +10,13 @@
_LOGGER = logging.getLogger(__name__)


def get():
def get() -> ConfigReadDTO:
"""
Gets the config
:raises RepositoryError: If there is an issue getting the config
:return ConfigReadDTO: The config for the application
"""
try:
with db_session.get_db() as db:
return config_repo.get(db)
Expand Down
18 changes: 18 additions & 0 deletions unit_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import app.service.family as family_service
import app.service.collection as collection_service
import app.service.config as config_service
import app.service.token as token_service
from app.repository import (
family_repo,
Expand All @@ -21,6 +22,7 @@
organisation_repo,
collection_repo,
app_user_repo,
config_repo,
)

from unit_tests.mocks.repos.app_user_repo import mock_app_user_repo
Expand All @@ -29,9 +31,11 @@
from unit_tests.mocks.repos.geography_repo import mock_geography_repo
from unit_tests.mocks.repos.metadata_repo import mock_metadata_repo
from unit_tests.mocks.repos.organisation_repo import mock_organisation_repo
from unit_tests.mocks.repos.config_repo import mock_config_repo

from unit_tests.mocks.services.family_service import mock_family_service
from unit_tests.mocks.services.collection_service import mock_collection_service
from unit_tests.mocks.services.config_service import mock_config_service


@pytest.fixture
Expand Down Expand Up @@ -86,6 +90,13 @@ def collection_repo_mock(monkeypatch, mocker):
yield collection_repo


@pytest.fixture
def config_repo_mock(monkeypatch, mocker):
"""Mocks the repository for a single test."""
mock_config_repo(config_repo, monkeypatch, mocker)
yield config_repo


# ----- Mock services


Expand All @@ -103,6 +114,13 @@ def collection_service_mock(monkeypatch, mocker):
yield collection_service


@pytest.fixture
def config_service_mock(monkeypatch, mocker):
"""Mocks the service for a single test."""
mock_config_service(config_service, monkeypatch, mocker)
yield config_service


# ----- User tokens


Expand Down
22 changes: 22 additions & 0 deletions unit_tests/mocks/repos/config_repo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Optional
from pytest import MonkeyPatch

from sqlalchemy import exc

from app.model.config import ConfigReadDTO


def mock_config_repo(config_repo, monkeypatch: MonkeyPatch, mocker):
config_repo.return_empty = False
config_repo.throw_repository_error = False

def maybe_throw():
if config_repo.throw_repository_error:
raise exc.SQLAlchemyError("")

def mock_get(_) -> Optional[ConfigReadDTO]:
maybe_throw()
return ConfigReadDTO(geographies=[], taxonomies={}, languages={})

monkeypatch.setattr(config_repo, "get", mock_get)
mocker.spy(config_repo, "get")
19 changes: 19 additions & 0 deletions unit_tests/mocks/services/config_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from pytest import MonkeyPatch
from app.errors import RepositoryError

from app.model.config import ConfigReadDTO


def mock_config_service(config_service, monkeypatch: MonkeyPatch, mocker):
config_service.throw_repository_error = False

def maybe_throw():
if config_service.throw_repository_error:
raise RepositoryError("bad repo")

def mock_get_config() -> ConfigReadDTO:
maybe_throw()
return ConfigReadDTO(geographies=[], taxonomies={}, languages={})

monkeypatch.setattr(config_service, "get", mock_get_config)
mocker.spy(config_service, "get")
7 changes: 7 additions & 0 deletions unit_tests/routers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Test Approach

In the routers we mock the service to generate the different behaviours.

We then test that these behaviours (such as a db error) result in the correct HTTP response (in the case of a db error it should be a 503).

This ensures we are just unit testing the behaviour of the routers.
21 changes: 18 additions & 3 deletions unit_tests/routers/test_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
from fastapi import status
from fastapi.testclient import TestClient


def test_get_config(client: TestClient, user_header_token):
# TODO: Finish the config tests by adding mock for repo
pass
def test_get_config(client: TestClient, user_header_token, config_service_mock):
response = client.get("/api/v1/config", headers=user_header_token)
assert response.status_code == status.HTTP_200_OK
data = response.json()
keys = data.keys()
assert "geographies" in keys
assert "taxonomies" in keys
assert "languages" in keys
assert config_service_mock.get.call_count == 1


def test_get_config_when_db_error(
client: TestClient, user_header_token, config_service_mock
):
config_service_mock.throw_repository_error = True
response = client.get("/api/v1/config", headers=user_header_token)
assert response.status_code == status.HTTP_503_SERVICE_UNAVAILABLE

0 comments on commit 21cabf9

Please sign in to comment.