import pytest import pytest_asyncio from decimal import Decimal from datetime import date, datetime from tortoise.contrib.test import initializer, finalizer from mywebdav.models import User from mywebdav.billing.models import ( SubscriptionPlan, UserSubscription, UsageRecord, UsageAggregate, Invoice, InvoiceLineItem, PricingConfig, PaymentMethod, BillingEvent ) @pytest.fixture(scope="module") def event_loop(): import asyncio loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() @pytest_asyncio.fixture(scope="module", autouse=True) async def initialize_tests(): initializer(["mywebdav.models", "mywebdav.billing.models"], db_url="sqlite://:memory:") yield await finalizer() @pytest_asyncio.fixture async def test_user(): user = await User.create( username="testuser", email="test@example.com", hashed_password="hashed_password_here", is_active=True ) yield user await user.delete() @pytest.mark.asyncio async def test_subscription_plan_creation(): plan = await SubscriptionPlan.create( name="starter", display_name="Starter Plan", description="Basic storage plan", storage_gb=100, bandwidth_gb=100, price_monthly=Decimal("5.00"), price_yearly=Decimal("50.00") ) assert plan.name == "starter" assert plan.storage_gb == 100 assert plan.price_monthly == Decimal("5.00") await plan.delete() @pytest.mark.asyncio async def test_user_subscription_creation(test_user): subscription = await UserSubscription.create( user=test_user, billing_type="pay_as_you_go", status="active" ) assert subscription.user_id == test_user.id assert subscription.billing_type == "pay_as_you_go" assert subscription.status == "active" await subscription.delete() @pytest.mark.asyncio async def test_usage_record_creation(test_user): usage = await UsageRecord.create( user=test_user, record_type="storage", amount_bytes=1024 * 1024 * 100, resource_type="file", resource_id=1, idempotency_key="test_key_123" ) assert usage.user_id == test_user.id assert usage.record_type == "storage" assert usage.amount_bytes == 1024 * 1024 * 100 await usage.delete() @pytest.mark.asyncio async def test_usage_aggregate_creation(test_user): aggregate = await UsageAggregate.create( user=test_user, date=date.today(), storage_bytes_avg=1024 * 1024 * 500, storage_bytes_peak=1024 * 1024 * 600, bandwidth_up_bytes=1024 * 1024 * 50, bandwidth_down_bytes=1024 * 1024 * 100 ) assert aggregate.user_id == test_user.id assert aggregate.storage_bytes_avg == 1024 * 1024 * 500 await aggregate.delete() @pytest.mark.asyncio async def test_invoice_creation(test_user): invoice = await Invoice.create( user=test_user, invoice_number="INV-000001-202311", period_start=date(2023, 11, 1), period_end=date(2023, 11, 30), subtotal=Decimal("10.00"), tax=Decimal("0.00"), total=Decimal("10.00"), status="draft" ) assert invoice.user_id == test_user.id assert invoice.invoice_number == "INV-000001-202311" assert invoice.total == Decimal("10.00") await invoice.delete() @pytest.mark.asyncio async def test_invoice_line_item_creation(test_user): invoice = await Invoice.create( user=test_user, invoice_number="INV-000002-202311", period_start=date(2023, 11, 1), period_end=date(2023, 11, 30), subtotal=Decimal("10.00"), tax=Decimal("0.00"), total=Decimal("10.00"), status="draft" ) line_item = await InvoiceLineItem.create( invoice=invoice, description="Storage usage", quantity=Decimal("100.000000"), unit_price=Decimal("0.100000"), amount=Decimal("10.0000"), item_type="storage" ) assert line_item.invoice_id == invoice.id assert line_item.description == "Storage usage" assert line_item.amount == Decimal("10.0000") await line_item.delete() await invoice.delete() @pytest.mark.asyncio async def test_pricing_config_creation(test_user): config = await PricingConfig.create( config_key="storage_per_gb_month", config_value=Decimal("0.0045"), description="Storage cost per GB per month", unit="per_gb_month", updated_by=test_user ) assert config.config_key == "storage_per_gb_month" assert config.config_value == Decimal("0.0045") await config.delete() @pytest.mark.asyncio async def test_payment_method_creation(test_user): payment_method = await PaymentMethod.create( user=test_user, stripe_payment_method_id="pm_test_123", type="card", is_default=True, last4="4242", brand="visa", exp_month=12, exp_year=2025 ) assert payment_method.user_id == test_user.id assert payment_method.last4 == "4242" assert payment_method.is_default is True await payment_method.delete() @pytest.mark.asyncio async def test_billing_event_creation(test_user): event = await BillingEvent.create( user=test_user, event_type="invoice_created", stripe_event_id="evt_test_123", data={"invoice_id": 1}, processed=False ) assert event.user_id == test_user.id assert event.event_type == "invoice_created" assert event.processed is False await event.delete()