bmc_hub/tests/test_quick_time.py

35 lines
1.9 KiB
Python
Raw Permalink Normal View History

from datetime import datetime,timezone
from unittest.mock import MagicMock
import pytest
from fastapi import HTTPException
from pydantic import ValidationError
from app.timetracking.backend import quick_time as q
BASE=dict(request_id='10000000-0000-4000-8000-000000000001',mode='registered',description='Internt møde',minutes=30,starts_at=datetime(2026,10,7,10,tzinfo=timezone.utc),user_ids=[1])
@pytest.mark.parametrize('changes',[{'minutes':0},{'description':' '},{'starts_at':datetime(2026,10,7)},{'user_ids':[]},{'priority':'invalid'}])
def test_input_validation(changes):
with pytest.raises(ValidationError):q.QuickTimeInput(**(BASE|changes))
def test_no_customer_or_case_required():
payload=q.QuickTimeInput(**BASE)
assert payload.customer_id is None and payload.contact_id is None
assert 'sag_id' not in payload.model_dump()
def test_foreign_employee_permission_rejected(monkeypatch):
monkeypatch.setattr(q,'can_register',lambda *a:False)
with pytest.raises(HTTPException) as error:q.save(q.QuickTimeInput(**BASE),{'id':2})
assert error.value.status_code==403
def test_convert_requires_plan(monkeypatch):
monkeypatch.setattr(q,'can_register',lambda *a:True);monkeypatch.setattr(q,'can_plan',lambda *a:True)
with pytest.raises(HTTPException):q.save(q.QuickTimeInput(**(BASE|{'mode':'convert'})),{'id':1})
def test_idempotent_replay_returns_result(monkeypatch):
payload=q.QuickTimeInput(**BASE);conn=MagicMock();cur=conn.cursor.return_value.__enter__.return_value
cur.fetchone.return_value={'actor_id':1,'payload':payload.model_dump(mode='json'),'result':{'ids':[12]}}
monkeypatch.setattr(q,'can_register',lambda *a:True);monkeypatch.setattr(q,'get_db_connection',lambda:conn);monkeypatch.setattr(q,'release_db_connection',lambda c:None)
assert q.save(payload,{'id':1})=={'ids':[12]}
conn.commit.assert_not_called()
assert all('INSERT' not in call.args[0] for call in cur.execute.call_args_list)