Skip to content

Commit 921a6b0

Browse files
authored
Merge pull request #25 from getmarkus/cm-branch-23
refactor: remove unused test settings and improve database checks
2 parents 76243b6 + deb1d56 commit 921a6b0

File tree

9 files changed

+42
-46
lines changed

9 files changed

+42
-46
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,5 @@ Temporary Items
203203
*.sqlite
204204
*.sqlite3
205205
*.sqlite-journal
206-
*.sqlite3-journal
206+
*.sqlite3-journal
207+
*.db-journal

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Simple python template I am experimenting with around a set of overlapping conce
1111
uv run fastapi dev main.py
1212
uv run pytest
1313

14+
uvx dynaconf list
15+
1416
atlas schema inspect -u "sqlite://issues.db" --format "{{ sql . }}" > migrate.sql
1517
```
1618

app/resource_adapters/persistence/sqlmodel/database.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Generator
22

33
from loguru import logger
4-
from sqlalchemy import text
4+
from sqlalchemy import inspect, text
55
from sqlalchemy.engine import Engine
66
from sqlalchemy.pool import StaticPool
77
from sqlmodel import Session, SQLModel, create_engine
@@ -51,12 +51,27 @@ def get_engine(database_url: str | None = None) -> Engine:
5151

5252
if settings.database_schema:
5353
SQLModel.metadata.schema = settings.database_schema
54+
# with self.engine.connect() as conn:
5455
# if not conn.dialect.has_schema(conn, db_schema):
5556
# logger.warning(f"Schema '{db_schema}' not found in database. Creating...")
5657
# conn.execute(sa.schema.CreateSchema(db_schema))
5758
# conn.commit()
5859

59-
SQLModel.metadata.create_all(_engine)
60-
logger.info("Database tables created successfully")
60+
# Check if tables exist before creating them
61+
inspector = inspect(_engine)
62+
existing_tables = inspector.get_table_names(
63+
schema=settings.database_schema if settings.database_schema else None
64+
)
65+
if not existing_tables:
66+
# if settings.database_schema:
67+
# # Create schema if it doesn't exist
68+
# if not inspector.has_schema(settings.database_schema):
69+
# logger.info(f"Creating schema '{settings.database_schema}'")
70+
# with _engine.begin() as conn:
71+
# conn.execute(text(f'CREATE SCHEMA IF NOT EXISTS {settings.database_schema}'))
72+
SQLModel.metadata.create_all(_engine)
73+
logger.info("Database tables created successfully")
74+
else:
75+
logger.info("Database tables already exist, skipping creation")
6176

6277
return _engine

app/tests/conftest.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,20 @@
33

44
import pytest
55
from _pytest.config import Config
6-
from _pytest.nodes import Item
76
from fastapi import FastAPI
87
from fastapi.testclient import TestClient
98
from sqlmodel import Session, delete
109

1110
from app.core.factory import create_app
1211
from app.resource_adapters.persistence.sqlmodel.database import get_engine
1312
from app.resource_adapters.persistence.sqlmodel.issues import Issue
13+
from config import settings
1414

1515

16-
def pytest_configure(config: Config) -> None:
17-
"""Register env marker."""
18-
config.addinivalue_line(
19-
"markers", "env(name): mark test to run only on named environment"
20-
)
21-
22-
23-
def pytest_runtest_setup(item: Item) -> None:
24-
"""Set up environment for each test based on env marker."""
25-
envnames = [mark.args[0] for mark in item.iter_markers(name="env")]
26-
if envnames:
27-
# Set environment to the first env marker found
28-
os.environ["APP_ENV"] = envnames[0]
29-
else:
30-
# Default to testing environment if no env marker
31-
os.environ["APP_ENV"] = "testing"
16+
@pytest.fixture(scope="session", autouse=True)
17+
def set_test_settings():
18+
"""Fixture to force the use of the 'testing' environment for all tests."""
19+
settings.configure(FORCE_ENV_FOR_DYNACONF="testing")
3220

3321

3422
def pytest_unconfigure(config: Config) -> None:
@@ -46,7 +34,10 @@ async def test_lifespan(app: FastAPI):
4634

4735

4836
# Create test app using the factory with test lifespan
49-
app = create_app(lifespan_handler=test_lifespan)
37+
@pytest.fixture(name="app")
38+
def test_app():
39+
"""Create test app instance only during test execution."""
40+
return create_app(lifespan_handler=test_lifespan)
5041

5142

5243
@pytest.fixture(name="session")
@@ -60,6 +51,6 @@ def test_session():
6051

6152

6253
@pytest.fixture(name="client")
63-
def client_fixture():
54+
def client_fixture(app: FastAPI):
6455
with TestClient(app) as client:
6556
yield client

app/tests/test_issues.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from app.resource_adapters.persistence.sqlmodel.issues import SQLModelIssueRepository
99

1010

11-
@pytest.mark.env("testing")
1211
def test_analyze_issue_command(client: TestClient, session: Session):
1312
# Test case 1: Successful analysis
1413
issue_number = 1
@@ -26,7 +25,6 @@ def test_analyze_issue_command(client: TestClient, session: Session):
2625
assert response.issue_number == issue_number
2726

2827

29-
@pytest.mark.env("development")
3028
def test_analyze_issue_client(client: TestClient, session: Session):
3129
# Test case 1: Successful analysis
3230
issue_number = 1

config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
settings_files=[
1717
"settings.toml", # Base settings
1818
".secrets.toml", # Secret settings
19-
"settings.test.toml", # Test-specific settings, loaded when APP_ENV=testing
2019
],
2120
environments=True,
2221
load_dotenv=True,

main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class HealthCheck(BaseModel):
5252
..., description="Required. Status of the service: pass, fail, or warn"
5353
)
5454
version: Optional[str] = Field(None, description="Version of the service")
55+
env: Optional[str] = Field(None, description="Environment of the service")
5556
description: Optional[str] = Field(
5657
None, description="Human-friendly description of the service"
5758
)
@@ -66,6 +67,7 @@ def create_health_response(is_healthy: bool, check_name: str) -> JSONResponse:
6667
response = HealthCheck(
6768
status=status,
6869
version=settings.project_name,
70+
env=settings.current_env,
6971
description=f"Service {status}",
7072
checks={
7173
check_name: {

settings.test.toml

Lines changed: 0 additions & 18 deletions
This file was deleted.

settings.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ migrate_database = false
77
sqlite_wal_mode = false
88
# in-memory, sqlmodel
99
model_config = "sqlmodel"
10-
env_smoke_test = ""
1110

1211
# CORS Settings
1312
backend_cors_origins = []
@@ -36,4 +35,11 @@ cors_allow_methods = [
3635
] # Be more restrictive in production
3736

3837
[testing]
39-
# Test-specific settings
38+
# sqlite:///./test.db sqlite://
39+
database_url = "sqlite://"
40+
database_schema = ""
41+
# in-memory, sqlmodel
42+
model_config = "sqlmodel"
43+
migrate_database = false
44+
sqlite_wal_mode = false
45+
backend_cors_origins = ["http://testserver"]

0 commit comments

Comments
 (0)