Implement tests

This commit is contained in:
Keannu Christian Bernasol 2025-09-13 20:05:13 +08:00
parent 7b1d9d2b4c
commit 0baf619ace
19 changed files with 432 additions and 48 deletions

View file

@ -23,7 +23,9 @@ class Config(BaseModel):
"""
SECRET_KEY: StrictStr = Field(
min_length=32, description="Secret key for the API", required=True
min_length=32,
description="Secret key for the API",
json_schema_extra={"required": True},
)
DEBUG: bool = Field(default=False, description="API debug mode")
TIMEZONE: TimeZoneName = "UTC"
@ -34,7 +36,7 @@ class Config(BaseModel):
description="Allowed hosts by the API.", default_factory=list
)
USE_TZ: bool = Field(
required=True,
json_schema_extra={"required": True},
default=True,
description="Whether the backend API defaults to using timezone-aware datetimes.",
)
@ -44,41 +46,45 @@ class Config(BaseModel):
description="Whether to serve media files locally as oppossed to using a cloud storage solution.",
)
SMTP_HOST: StrictStr = Field(
required=True, description="SMTP server address")
SMTP_PORT: int = Field(
default=587, description="SMTP server port (default: 587)")
json_schema_extra={"required": True}, description="SMTP server address"
)
SMTP_PORT: int = Field(default=587, description="SMTP server port (default: 587)")
SMTP_USE_TLS: bool = Field(
default=True, description="Whether to use TLS for SMTP connections"
)
SMTP_AUTH_USERNAME: StrictStr = Field(
required=True, description="SMTP authentication username"
json_schema_extra={"required": True}, description="SMTP authentication username"
)
SMTP_AUTH_PASSWORD: StrictStr = Field(
required=True, description="SMTP authentication password"
json_schema_extra={"required": True}, description="SMTP authentication password"
)
SMTP_FROM_ADDRESS: EmailStr = Field(
required=True, description="SMTP from email address"
json_schema_extra={"required": True}, description="SMTP from email address"
)
ACCESS_TOKEN_LIFETIME_MINUTES: timedelta = Field(
default=timedelta(minutes=240), description="Access token lifetime in minutes"
default=timedelta(minutes=240),
description="Access token lifetime in minutes",
)
REFRESH_TOKEN_LIFETIME_DAYS: timedelta = Field(
default=timedelta(days=3), description="Refresh token lifetime in days"
)
DEBUG_USER_PASSWORD: StrictStr = Field(
required=True, description="Password for test users created during development"
json_schema_extra={"required": True},
description="Password for test users created during development",
)
CACHE_USERNAME: StrictStr = Field(
required=True, description="Cache server authentication username"
json_schema_extra={"required": True},
description="Cache server authentication username",
)
CACHE_PASSWORD: StrictStr = Field(
required=True, description="Cache server authentication password"
json_schema_extra={"required": True},
description="Cache server authentication password",
)
CACHE_HOST: StrictStr = Field(
required=True, description="Server host used for caching"
json_schema_extra={"required": True}, description="Server host used for caching"
)
CACHE_PORT: int = Field(
required=True, description="Server port used for caching"
json_schema_extra={"required": True}, description="Server port used for caching"
)
@field_validator("CORS_ORIGINS", "ALLOWED_HOSTS", mode="before")

View file

@ -194,7 +194,7 @@ DJOSER = {
"username_reset_confirm": ["rest_framework.permissions.IsAdminUser"],
"set_username": ["rest_framework.permissions.IsAdminUser"],
"set_password": ["rest_framework.permissions.IsAdminUser"],
},
}
}
SIMPLE_JWT = {

21
src/tests/settings.py Normal file
View file

@ -0,0 +1,21 @@
"""
Minimal Django settings file for tests
"""
from core.settings import * # noqa: F403
# Override database to SQLite
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "test_db.sqlite3", # noqa: F405
}
}
# Use dummy cache
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.dummy.DummyCache",
}
}

View file

@ -12,36 +12,61 @@ from core.settings import config, TESTS_DIR
logger = logging.getLogger(__name__)
def get_users_json():
"""
Function to read test user data from JSON file
"""
with open(os.path.join(TESTS_DIR, "users", "users.json"), "r") as f:
# Load JSON data
data = json.loads(f.read())
return data
def generate_test_users():
"""
Function to create test users in DEBUG mode.
Function to create test users.
"""
data = get_users_json()
for user in data["users"]:
# Check if user already exists
USER = CustomUser.objects.filter(username=user["username"]).first()
if not USER:
# Create user
if user["is_superuser"]:
USER = CustomUser.objects.create_superuser(
username=user["username"],
email=user["email"],
password=config.DEBUG_USER_PASSWORD,
)
logger.info("Created Superuser:", user["username"])
else:
USER = CustomUser.objects.create_user(
username=user["username"],
email=user["email"],
password=config.DEBUG_USER_PASSWORD,
)
logger.info("Created User:", user["username"])
# Additional user fields not covered by create() methods
USER.first_name = user["first_name"]
USER.last_name = user["last_name"]
USER.is_active = True
USER.save()
def remove_test_users():
"""
Function to remove test users in DEBUG mode.
"""
if config.DEBUG:
with open(os.path.join(TESTS_DIR, "users", "users.json"), "r") as f:
# Load JSON data
data = json.loads(f.read())
for user in data["users"]:
# Check if user already exists
USER = CustomUser.objects.filter(email=user["email"]).first()
if not USER:
# Create user
if user["is_superuser"]:
USER = CustomUser.objects.create_superuser(
username=user["username"],
email=user["email"],
password=config.DEBUG_USER_PASSWORD,
)
print("Created Superuser:", user["email"])
else:
USER = CustomUser.objects.create_user(
username=user["email"],
email=user["email"],
password=config.DEBUG_USER_PASSWORD,
)
print("Created User:", user["email"])
# Additional user fields not covered by create() methods
USER.first_name = user["first_name"]
USER.last_name = user["last_name"]
USER.is_active = True
USER.save()
data = get_users_json()
for user in data["users"]:
# Check if user already exists
USER = CustomUser.objects.filter(username=user["username"]).first()
if USER:
USER.delete()
else:
logger.warning(
f"Skipping user deletion for {user['username']}: Does not exist"
)

View file

@ -0,0 +1,38 @@
import pytest
import users
from accounts.models import CustomUser
def assert_users_created():
data = users.get_users_json()
for user in data["users"]:
USER = CustomUser.objects.filter(username=user["username"]).first()
# Assert user exists
assert USER
if user["is_superuser"]:
# Assert is superuser
assert USER.is_superuser
def assert_users_removed():
data = users.get_users_json()
for user in data["users"]:
USER = CustomUser.objects.filter(username=user["username"]).first()
# Assert user does not exist
assert not USER
@pytest.mark.django_db(transaction=True)
def test_user_creation_deletion():
"""
Test user creation and deletion
"""
users.generate_test_users()
assert_users_created()
users.remove_test_users()
assert_users_removed()

View file

@ -0,0 +1,38 @@
import pytest
from core.settings import config
import users
from rest_framework.test import APIClient
client = APIClient()
@pytest.mark.django_db(transaction=True)
def test_user_login():
"""
Test login
"""
data = users.get_users_json()
# Generate test users
users.generate_test_users()
for user in data["users"]:
login_response = client.post(
"/api/v1/accounts/jwt/create/",
{"username": user["username"], "password": config.DEBUG_USER_PASSWORD},
format="json",
).json()
# Check if login contains JWT data
assert {"access", "refresh"}.issubset(login_response)
access_token = login_response["access"]
client.credentials(HTTP_AUTHORIZATION=f"Bearer {access_token}")
# GET user info
user_response = client.get("/api/v1/accounts/users/me/")
assert user_response.json() # Ensure there's response data

View file

@ -16,7 +16,7 @@
},
{
"username": "testuser2",
"email": "user1@test.com",
"email": "user2@test.com",
"is_superuser": false,
"first_name": "Test",
"last_name": "User 2"