# tests/unit/models/schema/test_auth.py """Unit tests for auth Pydantic schemas.""" import pytest from pydantic import ValidationError from app.modules.tenancy.schemas.auth import ( UserCreate, UserLogin, UserResponse, UserUpdate, ) @pytest.mark.unit @pytest.mark.schema class TestUserLoginSchema: """Test UserLogin schema validation.""" def test_valid_login(self): """Test valid login data.""" login = UserLogin( email_or_username="testuser", password="password123", # noqa: SEC001 ) assert login.email_or_username == "testuser" assert login.password == "password123" # noqa: SEC001 def test_login_with_email(self): """Test login with email.""" login = UserLogin( email_or_username="test@example.com", password="password123", # noqa: SEC001 ) assert login.email_or_username == "test@example.com" def test_login_with_store_code(self): """Test login with optional store code.""" login = UserLogin( email_or_username="testuser", password="password123", # noqa: SEC001 store_code="STORE001", ) assert login.store_code == "STORE001" def test_email_or_username_stripped(self): """Test email_or_username is stripped of whitespace.""" login = UserLogin( email_or_username=" testuser ", password="password123", # noqa: SEC001 ) assert login.email_or_username == "testuser" @pytest.mark.unit @pytest.mark.schema class TestUserCreateSchema: """Test UserCreate schema validation.""" def test_valid_user_create(self): """Test valid user creation data.""" user = UserCreate( email="admin@example.com", username="adminuser", password="securepass", # noqa: SEC001 first_name="Admin", last_name="User", role="super_admin", ) assert user.email == "admin@example.com" assert user.role == "super_admin" def test_default_role_is_store_member(self): """Test default role is store_member.""" user = UserCreate( email="store@example.com", username="storeuser", password="securepass", # noqa: SEC001 ) assert user.role == "store_member" def test_invalid_role(self): """Test invalid role raises ValidationError.""" with pytest.raises(ValidationError) as exc_info: UserCreate( email="test@example.com", username="testuser", password="securepass", # noqa: SEC001 role="superadmin", ) assert "role" in str(exc_info.value).lower() def test_username_too_short(self): """Test username shorter than 3 characters raises ValidationError.""" with pytest.raises(ValidationError) as exc_info: UserCreate( email="test@example.com", username="ab", password="securepass", # noqa: SEC001 ) assert "username" in str(exc_info.value).lower() def test_password_min_length(self): """Test password minimum length validation.""" with pytest.raises(ValidationError) as exc_info: UserCreate( email="test@example.com", username="testuser", password="12345", # noqa: SEC001 ) assert "password" in str(exc_info.value).lower() @pytest.mark.unit @pytest.mark.schema class TestUserUpdateSchema: """Test UserUpdate schema validation.""" def test_partial_update(self): """Test partial update with only some fields.""" update = UserUpdate(first_name="NewName") assert update.first_name == "NewName" assert update.username is None assert update.email is None def test_username_update_normalized(self): """Test username in update is normalized.""" update = UserUpdate(username="NewUser") assert update.username == "newuser" def test_invalid_role_update(self): """Test invalid role in update raises ValidationError.""" with pytest.raises(ValidationError): UserUpdate(role="superadmin") def test_valid_role_update(self): """Test valid role values.""" admin_update = UserUpdate(role="super_admin") store_update = UserUpdate(role="merchant_owner") assert admin_update.role == "super_admin" assert store_update.role == "merchant_owner" def test_empty_update(self): """Test empty update is valid (all fields optional).""" update = UserUpdate() assert update.model_dump(exclude_unset=True) == {} @pytest.mark.unit @pytest.mark.schema class TestUserResponseSchema: """Test UserResponse schema.""" def test_from_dict(self): """Test creating response from dict.""" from datetime import datetime data = { "id": 1, "email": "test@example.com", "username": "testuser", "role": "merchant_owner", "is_active": True, "created_at": datetime.now(), "updated_at": datetime.now(), } response = UserResponse(**data) assert response.id == 1 assert response.email == "test@example.com" assert response.is_active is True def test_optional_last_login(self): """Test last_login is optional.""" from datetime import datetime data = { "id": 1, "email": "test@example.com", "username": "testuser", "role": "merchant_owner", "is_active": True, "created_at": datetime.now(), "updated_at": datetime.now(), } response = UserResponse(**data) assert response.last_login is None