mirror of
https://github.com/lemeow125/DRF_Template.git
synced 2025-09-18 05:29:37 +08:00
Implement tests
This commit is contained in:
parent
7b1d9d2b4c
commit
0baf619ace
19 changed files with 432 additions and 48 deletions
|
@ -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")
|
||||
|
|
|
@ -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
21
src/tests/settings.py
Normal 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",
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
)
|
||||
|
|
38
src/tests/users/test_user_creation_deletion.py
Normal file
38
src/tests/users/test_user_creation_deletion.py
Normal 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()
|
38
src/tests/users/test_user_login_query_self.py
Normal file
38
src/tests/users/test_user_login_query_self.py
Normal 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
|
|
@ -16,7 +16,7 @@
|
|||
},
|
||||
{
|
||||
"username": "testuser2",
|
||||
"email": "user1@test.com",
|
||||
"email": "user2@test.com",
|
||||
"is_superuser": false,
|
||||
"first_name": "Test",
|
||||
"last_name": "User 2"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue