diff --git a/examples/miniapps/fastapi-sqlalchemy/requirements.txt b/examples/miniapps/fastapi-sqlalchemy/requirements.txt index dfc9d5d1..f2c5ade5 100644 --- a/examples/miniapps/fastapi-sqlalchemy/requirements.txt +++ b/examples/miniapps/fastapi-sqlalchemy/requirements.txt @@ -3,3 +3,6 @@ fastapi uvicorn pyyaml sqlalchemy +pytest +requests +pytest-cov diff --git a/examples/miniapps/fastapi-sqlalchemy/webapp/containers.py b/examples/miniapps/fastapi-sqlalchemy/webapp/containers.py index 40e3a8c0..a5bf81ca 100644 --- a/examples/miniapps/fastapi-sqlalchemy/webapp/containers.py +++ b/examples/miniapps/fastapi-sqlalchemy/webapp/containers.py @@ -13,12 +13,12 @@ class Container(containers.DeclarativeContainer): db = providers.Singleton(Database, db_url=config.db.url) - users_repository = providers.Factory( + user_repository = providers.Factory( UserRepository, session_factory=db.provided.session, ) user_service = providers.Factory( UserService, - users_repository=users_repository, + user_repository=user_repository, ) diff --git a/examples/miniapps/fastapi-sqlalchemy/webapp/services.py b/examples/miniapps/fastapi-sqlalchemy/webapp/services.py index 3f12cf5e..c48cccbb 100644 --- a/examples/miniapps/fastapi-sqlalchemy/webapp/services.py +++ b/examples/miniapps/fastapi-sqlalchemy/webapp/services.py @@ -9,8 +9,8 @@ from .models import User class UserService: - def __init__(self, users_repository: UserRepository) -> None: - self._repository: UserRepository = users_repository + def __init__(self, user_repository: UserRepository) -> None: + self._repository: UserRepository = user_repository def get_users(self) -> Iterator[User]: return self._repository.get_all() diff --git a/examples/miniapps/fastapi-sqlalchemy/webapp/tests.py b/examples/miniapps/fastapi-sqlalchemy/webapp/tests.py new file mode 100644 index 00000000..fe2e6a12 --- /dev/null +++ b/examples/miniapps/fastapi-sqlalchemy/webapp/tests.py @@ -0,0 +1,107 @@ +"""Tests module.""" + +from unittest import mock + +import pytest +from fastapi.testclient import TestClient + +from .repositories import UserRepository, UserNotFoundError +from .models import User +from .application import app + + +@pytest.fixture +def client(): + yield TestClient(app) + + +def test_get_list(client): + repository_mock = mock.Mock(spec=UserRepository) + repository_mock.get_all.return_value = [ + User(id=1, email='test1@email.com', hashed_password='pwd', is_active=True), + User(id=2, email='test2@email.com', hashed_password='pwd', is_active=False), + ] + + with app.container.user_repository.override(repository_mock): + response = client.get('/users') + + assert response.status_code == 200 + data = response.json() + assert data == [ + {'id': 1, 'email': 'test1@email.com', 'hashed_password': 'pwd', 'is_active': True}, + {'id': 2, 'email': 'test2@email.com', 'hashed_password': 'pwd', 'is_active': False}, + ] + + +def test_get_by_id(client): + repository_mock = mock.Mock(spec=UserRepository) + repository_mock.get_by_id.return_value = User( + id=1, + email='xyz@email.com', + hashed_password='pwd', + is_active=True, + ) + + with app.container.user_repository.override(repository_mock): + response = client.get('/users/1') + + assert response.status_code == 200 + data = response.json() + assert data == {'id': 1, 'email': 'xyz@email.com', 'hashed_password': 'pwd', 'is_active': True} + repository_mock.get_by_id.assert_called_once_with(1) + + +def test_get_by_id_404(client): + repository_mock = mock.Mock(spec=UserRepository) + repository_mock.get_by_id.side_effect = UserNotFoundError(1) + + with app.container.user_repository.override(repository_mock): + response = client.get('/users/1') + + assert response.status_code == 404 + + +@mock.patch('webapp.services.uuid4', return_value='xyz') +def test_add(_, client): + repository_mock = mock.Mock(spec=UserRepository) + repository_mock.add.return_value = User( + id=1, + email='xyz@email.com', + hashed_password='pwd', + is_active=True, + ) + + with app.container.user_repository.override(repository_mock): + response = client.post('/users') + + assert response.status_code == 201 + data = response.json() + assert data == {'id': 1, 'email': 'xyz@email.com', 'hashed_password': 'pwd', 'is_active': True} + repository_mock.add.assert_called_once_with(email='xyz@email.com', password='pwd') + + +def test_remove(client): + repository_mock = mock.Mock(spec=UserRepository) + + with app.container.user_repository.override(repository_mock): + response = client.delete('/users/1') + + assert response.status_code == 204 + repository_mock.delete_by_id.assert_called_once_with(1) + + +def test_remove_404(client): + repository_mock = mock.Mock(spec=UserRepository) + repository_mock.delete_by_id.side_effect = UserNotFoundError(1) + + with app.container.user_repository.override(repository_mock): + response = client.delete('/users/1') + + assert response.status_code == 404 + + +def test_status(client): + response = client.get('/status') + assert response.status_code == 200 + data = response.json() + assert data == {'status': 'OK'}