bmc_hub/tests/test_case_v5_automatic_billing.py

82 lines
4.6 KiB
Python
Raw Permalink Normal View History

import asyncio
from importlib import import_module
from unittest.mock import MagicMock
import pytest
from app.modules.sag.backend import commands
from app.core.config import settings
router = import_module('app.timetracking.backend.router')
@pytest.mark.parametrize('choice', ['invoice', 'card_7', 'fpa_9'])
def test_automatic_capture_ignores_manual_billing_and_saves_draft(monkeypatch, choice):
monkeypatch.setattr(router, '_resolve_case_customer_id', lambda *args: 77)
captured = {}
def choose(case, value):
assert value == 'draft'
return {'method': 'draft', 'status': 'kladde', 'card_id': None, 'agreement_id': None}
monkeypatch.setattr(router, '_case_billing_choice', choose)
def insert(sql, params):
captured['params'] = params
return [{'id': 3}]
monkeypatch.setattr(router, 'execute_query', insert)
asyncio.run(router.create_manual_time_v1({'sag_id': 186, 'faktisk_tid_min': 15,
'billing_mode': 'automatic', 'settlement_choice': choice, 'billing_method': 'invoice'},
{'id': 12, 'username': 'test'}))
assert captured['params'][9] == 'draft'
assert captured['params'][16] == 'kladde'
assert captured['params'][-4:-2] == (None, None)
def test_explicit_time_tab_choice_retains_existing_validation(monkeypatch):
choose = MagicMock(return_value={'method': 'invoice'})
monkeypatch.setattr(router, '_case_billing_choice', choose)
assert router._case_registration_billing(186, {'billing_mode': 'manual', 'settlement_choice': 'invoice'}) == {'method': 'invoice'}
choose.assert_called_once_with(186, 'invoice')
def test_automatic_live_timer_is_draft_even_when_invoice_is_submitted(monkeypatch):
monkeypatch.setattr(router, '_resolve_case_customer_id', lambda *args: 77)
monkeypatch.setattr(router, '_resolve_target_user_id', lambda *args: 12)
monkeypatch.setattr(router, 'execute_query_single', lambda *args: None)
monkeypatch.setattr(router, '_case_billing_choice', lambda case, choice: {
'method': choice, 'status': 'kladde', 'card_id': None, 'agreement_id': None})
def insert(sql, params):
assert params[-4:-1] == ('draft', None, None)
return [{'id': 3}]
monkeypatch.setattr(router, 'execute_query', insert)
asyncio.run(router.start_live_timer_v1({'sag_id': 186, 'billing_mode': 'automatic',
'settlement_choice': 'invoice'}, {'id': 12, 'username': 'test'}))
def test_v5_command_cannot_select_card_in_automatic_mode(monkeypatch):
choose = MagicMock(return_value={'method': 'draft', 'status': 'kladde', 'card_id': None, 'agreement_id': None})
monkeypatch.setattr(router, '_case_billing_choice', choose)
result = commands.normalize(MagicMock(), {'id': 186}, {'billing_mode': 'automatic',
'commands': [{'type': 'time', 'minutes': 15, 'description': 'Test', 'settlement_choice': 'card_7'}]}, {'id': 12})
choose.assert_called_once_with(186, 'draft')
assert result[0]['settlement_choice'] == 'draft'
def test_display_uses_workflow_choice_without_mutating_stored_draft(monkeypatch):
monkeypatch.setattr(settings, 'WORKFLOWS_ENABLED', True)
from app.workflows import integration
monkeypatch.setattr(integration, 'active_for_customer', lambda _: True)
monkeypatch.setattr(router, 'execute_query_single', lambda sql, params=None: {'customer_id': 24} if 'sag_sager' in sql else {'name': 'bmc_billing_decisions'})
monkeypatch.setattr(router, 'execute_query', lambda *args: [{'time_id': 3, 'revision': 2, 'status': 'decided', 'method': 'subscription'}])
result = router._case_time_billing_display([{'id': 3, 'workflow_revision': 2, 'billing_method': 'draft'}], 186,
{'permissions': ['workflows.override', 'workflows.decisions.view']})[0]
assert result['billing_method'] == 'draft'
assert result['selected_billing_method'] == 'subscription'
assert result['workflow_can_override'] is True
def test_stale_workflow_choice_displays_draft_until_recalculated(monkeypatch):
monkeypatch.setattr(settings, 'WORKFLOWS_ENABLED', True)
from app.workflows import integration
monkeypatch.setattr(integration, 'active_for_customer', lambda _: True)
monkeypatch.setattr(router, 'execute_query_single', lambda sql, params=None: {'customer_id': 24} if 'sag_sager' in sql else {'name': 'bmc_billing_decisions'})
monkeypatch.setattr(router, 'execute_query', lambda *args: [{'time_id': 3, 'revision': 1, 'status': 'decided', 'method': 'prepaid'}])
result = router._case_time_billing_display([{'id': 3, 'workflow_revision': 2, 'billing_method': 'draft'}], 186, {})[0]
assert result['selected_billing_method'] == 'draft' and result['workflow_stale'] is True