from collections.abc import Iterator from pathlib import Path from unittest import mock import fakeredis import pytest from fansifter_common.adapters.db import Database from fansifter_common.adapters.db.models.utils import autodiscover_models from fansifter_common.adapters.twilio.client import TwilioClient from pytest_mock import MockerFixture from app.adapters.kms import KMSClient from app.adapters.ows_text_campaigns import OwsTextCampaignsClient from app.adapters.postgres import PgModel, postgres_db from app.adapters.snowflake import Model, snowflake_db @pytest.fixture(scope="session", autouse=True) def _db(session_mocker: MockerFixture) -> Iterator[None]: db_path = Path(__file__).parent.parent.parent / "test.db" session_mocker.patch( "app.adapters.snowflake.snowflake_db.__wrapped__", new=Database( url="sqlite:///" + str(db_path), session_args={ "expire_on_commit": False, "autoflush": True, }, ), ) yield db_path.unlink(missing_ok=True) @pytest.fixture(scope="session") def _db_setup() -> Iterator[None]: autodiscover_models("app") Model.metadata.create_all(bind=snowflake_db.engine) yield Model.metadata.drop_all(bind=snowflake_db.engine) @pytest.fixture(scope="session", autouse=True) def _pg_db(session_mocker: MockerFixture) -> Iterator[None]: db_path = Path(__file__).parent.parent.parent / "test_pg.db" session_mocker.patch( "app.adapters.postgres.postgres_db.__wrapped__", new=Database( url="sqlite:///" + str(db_path), session_args={ "expire_on_commit": False, "autoflush": True, }, ), ) yield db_path.unlink(missing_ok=True) @pytest.fixture(scope="session") def _pg_db_setup(_db_setup: None) -> Iterator[None]: PgModel.metadata.create_all(bind=postgres_db.engine) yield PgModel.metadata.drop_all(bind=postgres_db.engine) @pytest.fixture(autouse=True) def _db_marker(request: pytest.FixtureRequest) -> Iterator[None]: """Use the `db` marker to run a test in a transaction.""" marker = request.node.get_closest_marker("db") if not marker: yield return _ = request.getfixturevalue("_db_setup") _ = request.getfixturevalue("_pg_db_setup") with ( snowflake_db.global_context(), snowflake_db.rollback_transaction(), postgres_db.global_context(), postgres_db.rollback_transaction(), ): yield @pytest.fixture(scope="session", autouse=True) def redis_client(session_mocker: MockerFixture) -> fakeredis.FakeRedis: fake_redis_client = fakeredis.FakeRedis() session_mocker.patch( "app.adapters.redis.redis_client.__wrapped__", new=fake_redis_client ) return fake_redis_client @pytest.fixture(autouse=True) def _reset_redis_client(redis_client: fakeredis.FakeRedis) -> None: redis_client.flushall() @pytest.fixture(scope="session", autouse=True) def ows_text_campaigns_client_mock(session_mocker: MockerFixture) -> mock.MagicMock: mocked_ows_text_campaigns_client = session_mocker.MagicMock( spec=OwsTextCampaignsClient ) session_mocker.patch( "app.adapters.ows_text_campaigns.ows_text_campaigns_client.__wrapped__", new=mocked_ows_text_campaigns_client, ) return mocked_ows_text_campaigns_client @pytest.fixture(autouse=True) def _reset_ows_text_campaigns_client_mock( ows_text_campaigns_client_mock: mock.MagicMock, ) -> None: ows_text_campaigns_client_mock.reset_mock(return_value=True, side_effect=True) ows_text_campaigns_client_mock.render_messages_batch.side_effect = None ows_text_campaigns_client_mock.render_messages_batch.return_value = [] @pytest.fixture(scope="session", autouse=True) def twilio_client_mock(session_mocker: MockerFixture) -> mock.MagicMock: mocked_twilio_client = session_mocker.MagicMock(spec=TwilioClient) session_mocker.patch( "app.adapters.twilio.twilio_client.__wrapped__", new=mocked_twilio_client ) return mocked_twilio_client @pytest.fixture(autouse=True) def _reset_twilio_client_mock(twilio_client_mock: mock.MagicMock) -> None: twilio_client_mock.reset_mock(return_value=True, side_effect=True) @pytest.fixture(scope="session", autouse=True) def kms_client_mock(session_mocker: MockerFixture) -> mock.MagicMock: mocked_kms_client = session_mocker.MagicMock(spec=KMSClient) session_mocker.patch( "app.adapters.kms.kms_client.__wrapped__", new=mocked_kms_client ) return mocked_kms_client @pytest.fixture(autouse=True) def _reset_kms_client_mock(kms_client_mock: mock.MagicMock) -> None: kms_client_mock.reset_mock(return_value=True, side_effect=True) kms_client_mock.decrypt.side_effect = lambda value: value