Skip to content

Commit 937c741

Browse files
committed
Merge branch 'main' into develop
2 parents ecef703 + a255719 commit 937c741

File tree

4 files changed

+43
-13
lines changed

4 files changed

+43
-13
lines changed

.github/workflows/ci-cd.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
python-version: ['3.11', '3.12', '3.13']
2121

2222
steps:
23-
- uses: actions/checkout@v5
23+
- uses: actions/checkout@v6
2424
with:
2525
fetch-depth: 0
2626

@@ -30,7 +30,7 @@ jobs:
3030
python-version: ${{ matrix.python-version }}
3131

3232
- name: Cache pip dependencies
33-
uses: actions/cache@v4
33+
uses: actions/cache@v5
3434
with:
3535
path: ~/.cache/pip
3636
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
@@ -75,7 +75,7 @@ jobs:
7575
needs: test
7676

7777
steps:
78-
- uses: actions/checkout@v5
78+
- uses: actions/checkout@v6
7979

8080
- name: Set up Python
8181
uses: actions/setup-python@v6
@@ -98,7 +98,7 @@ jobs:
9898
safety check
9999
100100
- name: Upload security scan results
101-
uses: actions/upload-artifact@v5
101+
uses: actions/upload-artifact@v6
102102
if: always()
103103
with:
104104
name: security-reports
@@ -116,7 +116,7 @@ jobs:
116116

117117
steps:
118118
- name: Checkout repository
119-
uses: actions/checkout@v5
119+
uses: actions/checkout@v6
120120

121121
- name: Log in to Container Registry
122122
uses: docker/login-action@v3
@@ -184,7 +184,7 @@ jobs:
184184

185185
steps:
186186
- name: Checkout repository
187-
uses: actions/checkout@v5
187+
uses: actions/checkout@v6
188188

189189
- name: Initialize CodeQL
190190
uses: github/codeql-action/init@v4
@@ -203,7 +203,7 @@ jobs:
203203
if: github.event_name == 'release' && github.event.action == 'published'
204204

205205
steps:
206-
- uses: actions/checkout@v5
206+
- uses: actions/checkout@v6
207207
with:
208208
fetch-depth: 0
209209

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ dev = [
5252
"mypy>=1.0.0",
5353
"bandit>=1.7.0",
5454
"safety>=2.3.0",
55+
"isort"
5556
]
5657
test = [
5758
"pytest>=7.0.0",

tests/conftest.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66

77
import pytest
88
from fastapi.testclient import TestClient
9-
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
9+
from sqlalchemy.ext.asyncio import (
10+
AsyncSession,
11+
async_sessionmaker,
12+
create_async_engine,
13+
)
1014
from sqlalchemy.pool import StaticPool
1115

1216
from writing_assistant.app.auth import get_user_manager
@@ -26,6 +30,31 @@
2630
)
2731

2832

33+
def pytest_sessionfinish(session, exitstatus):
34+
"""Clean up async engine after all tests complete."""
35+
import asyncio
36+
37+
# Dispose of the async engine to close all connections and threads
38+
try:
39+
# Try to dispose using the current event loop if available
40+
try:
41+
loop = asyncio.get_event_loop()
42+
if not loop.is_closed() and not loop.is_running():
43+
loop.run_until_complete(test_engine.dispose())
44+
else:
45+
# Create a new event loop for cleanup
46+
asyncio.run(test_engine.dispose())
47+
except RuntimeError:
48+
# No event loop exists, create one
49+
asyncio.run(test_engine.dispose())
50+
except Exception:
51+
# Fallback: try to close the underlying sync engine
52+
try:
53+
test_engine.sync_engine.dispose(close=True)
54+
except Exception:
55+
pass
56+
57+
2958
@pytest.fixture(scope="function")
3059
async def async_db_session() -> AsyncGenerator[AsyncSession, None]:
3160
"""Create a fresh database for each test."""

tests/test_main_coverage.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,16 @@ def test_get_user_preferences_empty(authenticated_client):
116116
assert data["preferences"] == {}
117117

118118

119-
def test_get_user_preferences_with_data(authenticated_client, async_db_session, test_user):
119+
async def test_get_user_preferences_with_data(authenticated_client, async_db_session, test_user):
120120
"""Test getting user preferences with saved data."""
121121
import json
122122

123123
# Set preferences on user
124124
test_user.preferences = json.dumps({"theme": "dark", "fontSize": 14})
125125
async_db_session.add(test_user)
126126

127-
# Use sync over async to commit
128-
import asyncio
129-
asyncio.get_event_loop().run_until_complete(async_db_session.commit())
127+
# Commit the changes
128+
await async_db_session.commit()
130129

131130
response = authenticated_client.get("/user/preferences")
132131
assert response.status_code == 200
@@ -413,9 +412,10 @@ def test_create_snapshot_cleanup_old(authenticated_client):
413412
)
414413

415414
# Create 12 snapshots
415+
import time
416416
for i in range(12):
417417
authenticated_client.post("/documents/snapshot/cleanup.json")
418-
asyncio.sleep(0.01) # Small delay to ensure different timestamps
418+
time.sleep(0.01) # Small delay to ensure different timestamps
419419

420420
# List snapshots
421421
response = authenticated_client.get("/documents/snapshots/cleanup.json")

0 commit comments

Comments
 (0)