1
1
import pytest
2
+ import os
2
3
from typing import Generator
3
4
from sqlmodel import create_engine , Session , select
4
5
from sqlalchemy import Engine
5
6
from fastapi .testclient import TestClient
6
7
from dotenv import load_dotenv
7
- from utils .core .db import get_connection_url , tear_down_db , set_up_db , create_default_roles
8
+ from utils .core .db import get_connection_url , tear_down_db , set_up_db , create_default_roles , ensure_database_exists
8
9
from utils .core .models import User , PasswordResetToken , EmailUpdateToken , Organization , Role , Account , Invitation
9
10
from utils .core .auth import get_password_hash , create_access_token , create_refresh_token
10
11
from main import app
11
12
from datetime import datetime , UTC , timedelta
12
13
13
- # Load environment variables
14
- load_dotenv (override = True )
15
-
16
14
# Define a custom exception for test setup errors
17
15
class SetupError (Exception ):
18
16
"""Exception raised for errors in the test setup process."""
@@ -21,29 +19,44 @@ def __init__(self, message="An error occurred during test setup"):
21
19
super ().__init__ (self .message )
22
20
23
21
24
- @pytest .fixture (scope = "session" )
25
- def engine () -> Engine :
22
+ @pytest .fixture
23
+ def env_vars (monkeypatch ):
24
+ # Get valid db user, password, host, and port from .env
25
+ load_dotenv ()
26
+ os .environ ["DB_HOST" ] = os .getenv ("DB_HOST" , "localhost" )
27
+ os .environ ["DB_PORT" ] = os .getenv ("DB_PORT" , "5432" )
28
+ os .environ ["DB_USER" ] = os .getenv ("DB_USER" , "appuser" )
29
+ os .environ ["DB_PASSWORD" ] = os .getenv ("DB_PASSWORD" , "testpassword" )
30
+
31
+ # monkeypatch remaining env vars
32
+ with monkeypatch .context () as m :
33
+ m .setenv ("SECRET_KEY" , "testsecretkey" )
34
+ m .setenv ("HOST_NAME" , "Test Organization" )
35
+ m .setenv ("DB_HOST" , os .getenv ("DB_HOST" , "localhost" ))
36
+ m .setenv ("DB_PORT" , os .getenv ("DB_PORT" , "5432" ))
37
+ m .setenv ("DB_USER" , os .getenv ("DB_USER" , "appuser" ))
38
+ m .setenv ("DB_PASSWORD" , os .getenv ("DB_PASSWORD" , "testpassword" ))
39
+ m .setenv ("DB_NAME" , "qual2db4-test-db" )
40
+ m .setenv ("RESEND_API_KEY" , "test" )
41
+ m .
setenv (
"EMAIL_FROM" ,
"[email protected] " )
42
+ m .setenv ("QUALTRICS_BASE_URL" , "test" )
43
+ m .setenv ("QUALTRICS_API_TOKEN" , "test" )
44
+ yield
45
+
46
+
47
+ @pytest .fixture
48
+ def engine (env_vars ) -> Engine :
26
49
"""
27
50
Create a new SQLModel engine for the test database.
28
51
Use PostgreSQL for testing to match production environment.
29
52
"""
30
53
# Use PostgreSQL for testing to match production environment
54
+ ensure_database_exists (get_connection_url ())
31
55
engine = create_engine (get_connection_url ())
32
- return engine
56
+ set_up_db ( drop = True )
33
57
58
+ yield engine
34
59
35
- @pytest .fixture (scope = "session" , autouse = True )
36
- def set_up_database (engine ) -> Generator [None , None , None ]:
37
- """
38
- Set up the test database before running the test suite.
39
- Drop all tables and recreate them to ensure a clean state.
40
- """
41
- # Drop and recreate all tables using the helpers from db.py
42
- tear_down_db ()
43
- set_up_db (drop = False )
44
-
45
- yield
46
-
47
60
# Clean up after tests
48
61
tear_down_db ()
49
62
@@ -57,20 +70,7 @@ def session(engine) -> Generator[Session, None, None]:
57
70
yield session
58
71
59
72
60
- @pytest .fixture (autouse = True )
61
- def clean_db (session : Session ) -> None :
62
- """
63
- Cleans up the database tables before each test.
64
- """
65
- # Don't delete permissions as they are required for tests
66
- for model in (PasswordResetToken , EmailUpdateToken , User , Role , Organization , Account ):
67
- for record in session .exec (select (model )).all ():
68
- session .delete (record )
69
-
70
- session .commit ()
71
-
72
-
73
- @pytest .fixture ()
73
+ @pytest .fixture
74
74
def test_account (session : Session ) -> Account :
75
75
"""
76
76
Creates a test account in the database.
@@ -85,7 +85,7 @@ def test_account(session: Session) -> Account:
85
85
return account
86
86
87
87
88
- @pytest .fixture ()
88
+ @pytest .fixture
89
89
def test_user (session : Session , test_account : Account ) -> User :
90
90
"""
91
91
Creates a test user in the database linked to the test account.
@@ -103,7 +103,7 @@ def test_user(session: Session, test_account: Account) -> User:
103
103
return user
104
104
105
105
106
- @pytest .fixture ()
106
+ @pytest .fixture
107
107
def unauth_client (session : Session ) -> Generator [TestClient , None , None ]:
108
108
"""
109
109
Provides a TestClient instance without authentication.
@@ -112,7 +112,7 @@ def unauth_client(session: Session) -> Generator[TestClient, None, None]:
112
112
yield client
113
113
114
114
115
- @pytest .fixture ()
115
+ @pytest .fixture
116
116
def auth_client (session : Session , test_account : Account , test_user : User ) -> Generator [TestClient , None , None ]:
117
117
"""
118
118
Provides a TestClient instance with valid authentication tokens.
0 commit comments