35 lines
1.9 KiB
Python
35 lines
1.9 KiB
Python
|
|
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)
|