bmc_hub/tests/test_anydesk_session_history.py

82 lines
3.5 KiB
Python
Raw Normal View History

"""Session history keeps its string timestamp API while accepting DB datetimes."""
import asyncio
from datetime import datetime, timezone
import pytest
from app.models.schemas import AnyDeskSessionDetail
from app.routers import anydesk
from app.services import anydesk as service
@pytest.mark.parametrize('ended', [None, datetime(2026, 10, 7, 8, 0, tzinfo=timezone.utc)])
def test_contact_history_serializes_database_timestamps(monkeypatch, ended):
timestamp = datetime(2026, 10, 7, 7, 29, tzinfo=timezone.utc)
row = dict(id=1, anydesk_session_id='history-test', customer_id=18, contact_id=1565,
status='completed' if ended else 'active', started_at=timestamp, ended_at=ended,
created_at=timestamp, updated_at=timestamp, duration_minutes=26)
def query(sql, params):
assert params[0] == 1565
return [{'total': 1}] if 'COUNT(*)' in sql else [row]
monkeypatch.setattr(service, 'execute_query', query)
result = asyncio.run(anydesk.get_session_history(contact_id=1565))
payload = result.model_dump(mode='json')
assert payload['total'] == 1
actual = payload['sessions'][0]
for key in ('started_at', 'created_at', 'updated_at'):
assert actual[key] == timestamp.isoformat()
assert actual['ended_at'] == (ended.isoformat() if ended else None)
assert actual['contact_id'] == 1565
def test_existing_string_timestamps_are_preserved():
row = AnyDeskSessionDetail(id=1, anydesk_session_id='legacy', customer_id=18,
status='completed', started_at='2026-10-07T07:29:00Z',
created_at='2026-10-07T07:29:00Z')
assert row.started_at == '2026-10-07T07:29:00Z'
def test_link_case_from_contact_table_changes_only_selected_session(monkeypatch):
from contextlib import nullcontext
import json
updates = []
def query(sql, params):
if 'FROM sag_sager' in sql:
return [{'id': 123, 'customer_id': 21}]
if 'SELECT customer_id FROM anydesk_sessions' in sql:
return [{'customer_id': 21}]
updates.append((sql, params))
return []
monkeypatch.setattr(anydesk, 'execute_query', query)
monkeypatch.setattr(anydesk, 'atomic_transaction', nullcontext)
response = asyncio.run(anydesk.link_session(551, sag_id=123, require_same_customer=True))
assert json.loads(response.body)['ok']
assert len(updates) == 1
sql, params = updates[0]
assert 'sag_id = %s' in sql
assert 'WHERE id = %s' in sql
assert params == (123, 551)
assert 'customer_id =' not in sql
assert 'contact_id =' not in sql
@pytest.mark.parametrize('case_rows,session_rows,status', [
([], [{'customer_id':21}], 404),
([{'id':123,'customer_id':99}], [{'customer_id':21}], 409),
([{'id':123,'customer_id':21}], [], 404),
])
def test_case_picker_rejects_missing_or_other_customer_cases(monkeypatch, case_rows, session_rows, status):
from contextlib import nullcontext
from fastapi import HTTPException
def query(sql, params):
if 'FROM sag_sager' in sql:
return case_rows
if 'SELECT customer_id FROM anydesk_sessions' in sql:
return session_rows
raise AssertionError('Must not change session on rejected case selection')
monkeypatch.setattr(anydesk, 'execute_query', query)
monkeypatch.setattr(anydesk, 'atomic_transaction', nullcontext)
with pytest.raises(HTTPException) as error:
asyncio.run(anydesk.link_session(551, sag_id=123, require_same_customer=True))
assert error.value.status_code == status