diff --git a/app/backend/schemas/payment.py b/app/backend/schemas/payment.py index af34e7ae0cc4c64a2a1cce5aafd1e667c5df02a2..b0853481a69dcbda71eecdfc9ca617b596906ba3 100644 --- a/app/backend/schemas/payment.py +++ b/app/backend/schemas/payment.py @@ -30,18 +30,19 @@ class PaymentCreate(BaseModel): """Validate expiry date format (MM/YY) and ensure it's in the future.""" try: expiry_obj = datetime.strptime(value, "%m/%y") - current_date = datetime.now() - - if expiry_obj.year < current_date.year or ( - expiry_obj.year == current_date.year - and expiry_obj.month < current_date.month - ): - raise ValueError("Card expiry date must be in the future") - - return value except ValueError: raise ValueError("Invalid expiry date format. Use MM/YY") + current_date = datetime.now() + + if expiry_obj.year < current_date.year or ( + expiry_obj.year == current_date.year + and expiry_obj.month < current_date.month + ): + raise ValueError("Card expiry date must be in the future") + + return value + class PaymentRead(BaseModel): id: int diff --git a/app/tests/test_payment.py b/app/tests/test_payment.py new file mode 100644 index 0000000000000000000000000000000000000000..4c28c4a12d2f5f19720375a9439cb739b8d01dad --- /dev/null +++ b/app/tests/test_payment.py @@ -0,0 +1,103 @@ +import pytest +from datetime import datetime +from fastapi import HTTPException +from app.backend.schemas.payment import PaymentCreate, PaymentRead +from app.backend.models.models import Payment +from app.backend.utils.security import encrypt_card_number, decrypt_card_number + + +def test_payment_create_validation(): + # Valid payment data + valid_data = { + "payment_method": "Credit Card", + "card_number": "4111111111111111", + "cvv": "123", + "expiry_date": f"{(datetime.now().month):02d}/{str(datetime.now().year + 1)[2:]}", + } + payment = PaymentCreate(**valid_data) + assert payment.payment_method == valid_data["payment_method"] + assert decrypt_card_number(payment.card_number) == valid_data["card_number"] + assert payment.expiry_date == valid_data["expiry_date"] + + # Invalid card number + with pytest.raises(ValueError): + PaymentCreate( + payment_method="Credit Card", + card_number="123", # Too short + cvv="123", + expiry_date="12/25", + ) + + # Invalid CVV + with pytest.raises(ValueError): + PaymentCreate( + payment_method="Credit Card", + card_number="4111111111111111", + cvv="12", # Too short + expiry_date="12/25", + ) + + # Invalid expiry date format + with pytest.raises(ValueError): + PaymentCreate( + payment_method="Credit Card", + card_number="4111111111111111", + cvv="123", + expiry_date="13/25", # Invalid month + ) + + +def test_payment_read(): + # Create mock payment object + payment_obj = Payment( + id=1, + user_id=1, + payment_method="Credit Card", + card_number=encrypt_card_number("4111111111111111"), + expiry_date="12/25", + created_at=datetime.now(), + ) + + # Test PaymentRead model + payment_read = PaymentRead.from_orm(payment_obj) + assert payment_read.id == 1 + assert payment_read.user_id == 1 + assert payment_read.payment_method == "Credit Card" + assert payment_read.card_number == "4111111111111111" + assert payment_read.expiry_date == "12/25" + + +def test_expiry_date_validation(): + # Test past date + past_date = f"{(datetime.now().month - 1):02d}/{str(datetime.now().year)[2:]}" + with pytest.raises(ValueError, match="Card expiry date must be in the future"): + PaymentCreate( + payment_method="Credit Card", + card_number="4111111111111111", + cvv="123", + expiry_date=past_date, + ) + + # Test future date + future_date = f"{datetime.now().month:02d}/{str(datetime.now().year + 1)[2:]}" + payment = PaymentCreate( + payment_method="Credit Card", + card_number="4111111111111111", + cvv="123", + expiry_date=future_date, + ) + assert payment.expiry_date == future_date + + +def test_card_encryption(): + card_number = "4111111111111111" + payment = PaymentCreate( + payment_method="Credit Card", + card_number=card_number, + cvv="123", + expiry_date=f"{datetime.now().month:02d}/{str(datetime.now().year + 1)[2:]}", + ) + + # Verify encryption + assert payment.card_number != card_number + assert decrypt_card_number(payment.card_number) == card_number diff --git a/app/tests/test_product.py b/app/tests/test_product.py new file mode 100644 index 0000000000000000000000000000000000000000..46668d042556ad137e01e80401b943f8d6fa4de9 --- /dev/null +++ b/app/tests/test_product.py @@ -0,0 +1,73 @@ +import pytest +from datetime import datetime + +from app.backend.schemas.product import ( + ProductCreate, + ProductRead, + ProductUpdate, + ProductImageCreate, + ProductImageRead, + CategoryBase, +) + + +def test_product_create_schema(): + # Test valid product creation + product_data = { + "shop_id": 1, + "category_id": 2, + "name": "Test Product", + "description": "Test Description", + "price": 9.99, + "stock": 10, + } + product = ProductCreate(**product_data) + assert product.shop_id == 1 + assert product.name == "Test Product" + assert product.price == 9.99 + + # Test optional fields + product_minimal = {"shop_id": 1, "name": "Test Product", "price": 9.99, "stock": 10} + product = ProductCreate(**product_minimal) + assert product.category_id is None + assert product.description is None + + +def test_product_read_schema(): + product_data = { + "id": 1, + "shop_id": 1, + "category_id": 2, + "name": "Test Product", + "description": "Test Description", + "price": 9.99, + "stock": 10, + "created_at": datetime.now(), + "images": [], + "category": {"id": 2, "name": "Test Category"}, + } + product = ProductRead(**product_data) + assert product.id == 1 + assert isinstance(product.created_at, datetime) + assert isinstance(product.category, CategoryBase) + + +def test_product_update_schema(): + # Test partial updates + update_data = {"name": "Updated Name", "price": 19.99} + update = ProductUpdate(**update_data) + assert update.name == "Updated Name" + assert update.price == 19.99 + assert update.description is None + + +def test_product_image_schemas(): + # Test image create + image_data = {"product_id": 1, "image_url": "http://example.com/image.jpg"} + image = ProductImageCreate(**image_data) + assert image.product_id == 1 + + # Test image read + read_data = {"id": 1, "product_id": 1, "image_url": "http://example.com/image.jpg"} + image = ProductImageRead(**read_data) + assert image.id == 1