2025-11-10 15:46:40 +01:00
|
|
|
import pytest
|
2025-11-13 22:53:40 +01:00
|
|
|
import pytest_asyncio
|
2025-11-10 15:46:40 +01:00
|
|
|
from decimal import Decimal
|
|
|
|
|
from datetime import date, datetime, timedelta
|
2025-11-13 20:42:43 +01:00
|
|
|
from mywebdav.models import User, File, Folder
|
|
|
|
|
from mywebdav.billing.models import UsageRecord, UsageAggregate
|
|
|
|
|
from mywebdav.billing.usage_tracker import UsageTracker
|
2025-11-10 15:46:40 +01:00
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-13 22:53:40 +01:00
|
|
|
@pytest_asyncio.fixture
|
2025-11-10 15:46:40 +01:00
|
|
|
async def test_user():
|
|
|
|
|
user = await User.create(
|
|
|
|
|
username="testuser",
|
|
|
|
|
email="test@example.com",
|
|
|
|
|
hashed_password="hashed_password_here",
|
2025-11-13 23:22:05 +01:00
|
|
|
is_active=True,
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
yield user
|
|
|
|
|
await user.delete()
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-10 15:46:40 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_track_storage(test_user):
|
|
|
|
|
await UsageTracker.track_storage(
|
|
|
|
|
user=test_user,
|
|
|
|
|
amount_bytes=1024 * 1024 * 100,
|
|
|
|
|
resource_type="file",
|
2025-11-13 23:22:05 +01:00
|
|
|
resource_id=1,
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
records = await UsageRecord.filter(user=test_user, record_type="storage").all()
|
|
|
|
|
assert len(records) == 1
|
|
|
|
|
assert records[0].amount_bytes == 1024 * 1024 * 100
|
|
|
|
|
|
|
|
|
|
await records[0].delete()
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-10 15:46:40 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_track_bandwidth_upload(test_user):
|
|
|
|
|
await UsageTracker.track_bandwidth(
|
|
|
|
|
user=test_user,
|
|
|
|
|
amount_bytes=1024 * 1024 * 50,
|
|
|
|
|
direction="up",
|
|
|
|
|
resource_type="file",
|
2025-11-13 23:22:05 +01:00
|
|
|
resource_id=1,
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
records = await UsageRecord.filter(user=test_user, record_type="bandwidth_up").all()
|
|
|
|
|
assert len(records) == 1
|
|
|
|
|
assert records[0].amount_bytes == 1024 * 1024 * 50
|
|
|
|
|
|
|
|
|
|
await records[0].delete()
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-10 15:46:40 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_track_bandwidth_download(test_user):
|
|
|
|
|
await UsageTracker.track_bandwidth(
|
|
|
|
|
user=test_user,
|
|
|
|
|
amount_bytes=1024 * 1024 * 75,
|
|
|
|
|
direction="down",
|
|
|
|
|
resource_type="file",
|
2025-11-13 23:22:05 +01:00
|
|
|
resource_id=1,
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
records = await UsageRecord.filter(
|
|
|
|
|
user=test_user, record_type="bandwidth_down"
|
|
|
|
|
).all()
|
2025-11-10 15:46:40 +01:00
|
|
|
assert len(records) == 1
|
|
|
|
|
assert records[0].amount_bytes == 1024 * 1024 * 75
|
|
|
|
|
|
|
|
|
|
await records[0].delete()
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-10 15:46:40 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_aggregate_daily_usage(test_user):
|
2025-11-13 23:22:05 +01:00
|
|
|
await UsageTracker.track_storage(user=test_user, amount_bytes=1024 * 1024 * 100)
|
2025-11-10 15:46:40 +01:00
|
|
|
|
|
|
|
|
await UsageTracker.track_bandwidth(
|
2025-11-13 23:22:05 +01:00
|
|
|
user=test_user, amount_bytes=1024 * 1024 * 50, direction="up"
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
await UsageTracker.track_bandwidth(
|
2025-11-13 23:22:05 +01:00
|
|
|
user=test_user, amount_bytes=1024 * 1024 * 75, direction="down"
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
aggregate = await UsageTracker.aggregate_daily_usage(test_user, date.today())
|
|
|
|
|
|
|
|
|
|
assert aggregate is not None
|
|
|
|
|
assert aggregate.storage_bytes_avg > 0
|
|
|
|
|
assert aggregate.bandwidth_up_bytes == 1024 * 1024 * 50
|
|
|
|
|
assert aggregate.bandwidth_down_bytes == 1024 * 1024 * 75
|
|
|
|
|
|
|
|
|
|
await aggregate.delete()
|
|
|
|
|
await UsageRecord.filter(user=test_user).delete()
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-10 15:46:40 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_get_current_storage(test_user):
|
2025-11-13 23:22:05 +01:00
|
|
|
folder = await Folder.create(name="Test Folder", owner=test_user)
|
2025-11-10 15:46:40 +01:00
|
|
|
|
|
|
|
|
file1 = await File.create(
|
|
|
|
|
name="test1.txt",
|
|
|
|
|
path="/storage/test1.txt",
|
|
|
|
|
size=1024 * 1024 * 10,
|
|
|
|
|
mime_type="text/plain",
|
|
|
|
|
owner=test_user,
|
|
|
|
|
parent=folder,
|
2025-11-13 23:22:05 +01:00
|
|
|
is_deleted=False,
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
file2 = await File.create(
|
|
|
|
|
name="test2.txt",
|
|
|
|
|
path="/storage/test2.txt",
|
|
|
|
|
size=1024 * 1024 * 20,
|
|
|
|
|
mime_type="text/plain",
|
|
|
|
|
owner=test_user,
|
|
|
|
|
parent=folder,
|
2025-11-13 23:22:05 +01:00
|
|
|
is_deleted=False,
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
storage = await UsageTracker.get_current_storage(test_user)
|
|
|
|
|
|
|
|
|
|
assert storage == 1024 * 1024 * 30
|
|
|
|
|
|
|
|
|
|
await file1.delete()
|
|
|
|
|
await file2.delete()
|
|
|
|
|
await folder.delete()
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-10 15:46:40 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_get_monthly_usage(test_user):
|
|
|
|
|
today = date.today()
|
|
|
|
|
|
|
|
|
|
aggregate = await UsageAggregate.create(
|
|
|
|
|
user=test_user,
|
|
|
|
|
date=today,
|
|
|
|
|
storage_bytes_avg=1024 * 1024 * 1024 * 10,
|
|
|
|
|
storage_bytes_peak=1024 * 1024 * 1024 * 12,
|
|
|
|
|
bandwidth_up_bytes=1024 * 1024 * 1024 * 2,
|
2025-11-13 23:22:05 +01:00
|
|
|
bandwidth_down_bytes=1024 * 1024 * 1024 * 5,
|
2025-11-10 15:46:40 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
usage = await UsageTracker.get_monthly_usage(test_user, today.year, today.month)
|
|
|
|
|
|
|
|
|
|
assert usage["storage_gb_avg"] == pytest.approx(10.0, rel=0.01)
|
|
|
|
|
assert usage["storage_gb_peak"] == pytest.approx(12.0, rel=0.01)
|
|
|
|
|
assert usage["bandwidth_up_gb"] == pytest.approx(2.0, rel=0.01)
|
|
|
|
|
assert usage["bandwidth_down_gb"] == pytest.approx(5.0, rel=0.01)
|
|
|
|
|
|
|
|
|
|
await aggregate.delete()
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
|
2025-11-10 15:46:40 +01:00
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_get_monthly_usage_empty(test_user):
|
|
|
|
|
future_date = date.today() + timedelta(days=365)
|
|
|
|
|
|
2025-11-13 23:22:05 +01:00
|
|
|
usage = await UsageTracker.get_monthly_usage(
|
|
|
|
|
test_user, future_date.year, future_date.month
|
|
|
|
|
)
|
2025-11-10 15:46:40 +01:00
|
|
|
|
|
|
|
|
assert usage["storage_gb_avg"] == 0
|
|
|
|
|
assert usage["storage_gb_peak"] == 0
|
|
|
|
|
assert usage["bandwidth_up_gb"] == 0
|
|
|
|
|
assert usage["bandwidth_down_gb"] == 0
|