Files
Fulfillment-Backend/tests/test_time_tracking.py

127 lines
4.7 KiB
Python

from datetime import datetime
from typing import Optional
import pytest
from freezegun import freeze_time
from httpx import AsyncClient, Response
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.sql.functions import count
from models import WorkShift, PaymentRecord
from tests.conftest import db_session
@pytest.mark.asyncio
async def test_start_shift(admin_client: AsyncClient, db_session: AsyncSession):
now = datetime.now()
user_id = 2
response: Response = await admin_client.post(f"/work-shifts/start-shift/{user_id}")
# Assert response
assert response.status_code == 200
assert response.json().get("ok") is True
get_workshift = select(WorkShift).where(WorkShift.user_id == user_id, func.date(WorkShift.started_at) == now.date())
work_shift: Optional[WorkShift] = (await db_session.execute(get_workshift)).scalars().one_or_none()
# Assert database
assert work_shift is not None
assert work_shift.finished_at is None
assert work_shift.started_at.hour == now.hour
assert work_shift.started_at.minute == now.minute
@pytest.mark.asyncio
async def test_forbidden_starting_second_shift_per_day(admin_client: AsyncClient, db_session: AsyncSession):
now = datetime.now()
user_id = 2
response: Response = await admin_client.post(f"/work-shifts/start-shift/{user_id}")
# Assert first response
assert response.status_code == 200
assert response.json().get("ok") is True
response: Response = await admin_client.post(f"/work-shifts/start-shift/{user_id}")
# Assert second response
assert response.status_code == 200
assert response.json().get("ok") is False
get_count = (
select(count(WorkShift.id))
.where(WorkShift.user_id == user_id, func.date(WorkShift.started_at) == now.date())
)
work_shift_count: int = (await db_session.execute(get_count)).scalar()
# Assert database
assert work_shift_count == 1
@pytest.mark.asyncio
@freeze_time("2024-11-21 22:25:00")
async def test_finish_one_day_shift(admin_client: AsyncClient, db_session: AsyncSession):
fixed_now = datetime(2024, 11, 21, 22, 25, 0)
user_id = 2
response: Response = await admin_client.post(f"/work-shifts/finish-shift/{user_id}")
# Assert response
assert response.status_code == 200
assert response.json().get("ok") is True
# Assert database
get_workshift = select(WorkShift).where(WorkShift.id == 100)
work_shift: Optional[WorkShift] = (await db_session.execute(get_workshift)).scalars().one_or_none()
assert work_shift is not None
assert work_shift.finished_at == fixed_now
assert work_shift.user_id == user_id
get_payments = select(PaymentRecord).where(PaymentRecord.user_id == user_id,
PaymentRecord.start_date == fixed_now.date())
payment: Optional[PaymentRecord] = (await db_session.execute(get_payments)).scalars().one_or_none()
assert payment is not None
assert payment.created_by_user_id == 1
# работа: 8 * 350;
# переработка: 2.5 * 450;
# из них был перерыв: 0.5 * 450;
assert abs(payment.amount - 3700) < 0.01
@pytest.mark.asyncio
@freeze_time("2024-11-13 10:00:00")
async def test_finish_three_days_shift(admin_client: AsyncClient, db_session: AsyncSession):
fixed_now = datetime(2024, 11, 13, 10, 00, 0)
user_id = 1
response: Response = await admin_client.post(f"/work-shifts/finish-shift/{user_id}")
# Assert response
assert response.status_code == 200
assert response.json().get("ok") is True
# Assert database
get_workshift = select(WorkShift).where(WorkShift.id == 101)
work_shift: Optional[WorkShift] = (await db_session.execute(get_workshift)).scalars().one_or_none()
assert work_shift is not None
assert work_shift.finished_at == fixed_now
get_payments = select(PaymentRecord).where(
PaymentRecord.user_id == user_id,
PaymentRecord.start_date.between(
datetime(2024, 11, 11, 00, 00),
datetime(2024, 11, 14, 00, 00, 00)
)
)
payments = (await db_session.execute(get_payments)).scalars().all()
assert len(payments) == 3
# работа: 8 * 450;
# переработка: 4 * 550;
# из них был перерыв: 0.5 * 550;
assert abs(payments[0].amount - 5525) < 0.01
# работа: 8 * 450;
# переработка: 16 * 550;
# из них был перерыв: 0.5 * 550;
assert abs(payments[1].amount - 12125) < 0.01
# работа: 8 * 450;
# переработка: 2 * 550;
# из них был перерыв: 0.5 * 550;
assert abs(payments[2].amount - 4425) < 0.01