- Introduced tests for drift operations UI and backend to ensure proper handling of ignore rules and UI elements. - Added tests for email identity API to validate email linking and identity retrieval without updates. - Implemented tests for email purchase link service to verify correct handling of purchase mail links and conflict scenarios. - Created tests for email reply automation to ensure proper routing and processing of replies based on classification. - Developed tests for email sender creation to validate suggestions and handling of existing contacts and companies. - Added tests for email sender identity to ensure correct matching of contacts and domains. - Implemented tests for work desk functionalities to validate task management, meeting registrations, and timer functionalities.
69 lines
2.9 KiB
Python
69 lines
2.9 KiB
Python
from contextlib import contextmanager
|
|
import json
|
|
import pytest
|
|
from fastapi import HTTPException
|
|
from app.services import email_purchase_link as service
|
|
|
|
|
|
@pytest.fixture
|
|
def db(monkeypatch):
|
|
state = {'writes': [], 'mail': {'id': 7, 'linked_case_id': None},
|
|
'purchase': {'id': 10, 'sag_id': 42, 'description': 'Router', 'case_title': 'Netværk'}, 'previous': None}
|
|
@contextmanager
|
|
def transaction():
|
|
try:
|
|
yield
|
|
state['committed'] = True
|
|
except Exception:
|
|
state['rolled_back'] = True
|
|
raise
|
|
def read(sql, params):
|
|
if 'FROM email_messages' in sql:
|
|
assert 'FOR UPDATE' in sql
|
|
return state['mail']
|
|
if 'FROM sag_salgsvarer' in sql:
|
|
assert "p.type = 'purchase'" in sql and "p.status <> 'cancelled'" in sql
|
|
return state['purchase']
|
|
return state['previous']
|
|
monkeypatch.setattr(service, 'atomic_transaction', transaction)
|
|
monkeypatch.setattr(service, 'execute_query_single', read)
|
|
monkeypatch.setattr(service, 'execute_update', lambda sql, params: state['writes'].append((sql, params)))
|
|
return state
|
|
|
|
|
|
@pytest.mark.parametrize('kind,tracking', [('order_confirmation', None), ('freight_note', 'TRACK-123')])
|
|
def test_purchase_mail_links_and_logs_without_marking_goods_received(db, kind, tracking):
|
|
result = service.link_purchase_mail(7, 10, kind, tracking)
|
|
assert result['sag_id'] == 42
|
|
assert db['committed']
|
|
assert len(db['writes']) == 3
|
|
assert not any('UPDATE sag_salgsvarer' in sql for sql, _ in db['writes'])
|
|
metadata = json.loads(db['writes'][-1][1][2])
|
|
assert metadata == {'purchase_id': 10, 'sag_id': 42, 'kind': kind, 'tracking_number': tracking}
|
|
|
|
|
|
def test_repeated_identical_purchase_link_is_idempotent(db):
|
|
db['previous'] = {'metadata': {'purchase_id': 10, 'sag_id': 42, 'kind': 'freight_note', 'tracking_number': None}}
|
|
assert service.link_purchase_mail(7, 10, 'freight_note')['idempotent']
|
|
assert not db['writes']
|
|
|
|
|
|
@pytest.mark.parametrize('conflict', ['case', 'purchase', 'missing_mail', 'missing_purchase'])
|
|
def test_conflicting_or_missing_target_does_not_write(db, conflict):
|
|
if conflict == 'case': db['mail']['linked_case_id'] = 99
|
|
if conflict == 'purchase': db['previous'] = {'metadata': {'purchase_id': 99}}
|
|
if conflict == 'missing_mail': db['mail'] = None
|
|
if conflict == 'missing_purchase': db['purchase'] = None
|
|
with pytest.raises(HTTPException): service.link_purchase_mail(7, 10, 'order_confirmation')
|
|
assert not db['writes']
|
|
assert db['rolled_back']
|
|
|
|
|
|
def test_failure_between_link_and_audit_rolls_back(monkeypatch, db):
|
|
def fail(sql, params):
|
|
if 'UPDATE email_messages' in sql: raise RuntimeError('DB failed')
|
|
monkeypatch.setattr(service, 'execute_update', fail)
|
|
with pytest.raises(RuntimeError): service.link_purchase_mail(7, 10, 'freight_note')
|
|
assert db['rolled_back']
|
|
assert not db.get('committed')
|