Files
agent_contas/tests/migration/test_contestation_business_rules_full.py

108 lines
4.9 KiB
Python

from __future__ import annotations
from datetime import datetime, timedelta
from types import SimpleNamespace
from app.domain.contas.contestation_rules import (
complete_invoices_context, resolve_refund_option, billing_cutoff_reference,
next_cutoff_from_cut_date, due_day, manual_conta_certa_from_evidence,
)
from app.domain.contas.workflow_actions import build_contas_workflow_actions
def _complete(status='Em aberto', payment_type=2, cut_date=None):
row={'invoiceId':'I1','invoiceStatus':status,'dueDate':'2026-08-25'}
if cut_date is not None: row['cutDate']=cut_date
return {'billingProfile':{'paymentTypeId':payment_type},'paymentItems':[row]}
def test_refund_boleto_para_fatura_em_aberto_com_fatura_normal():
c=complete_invoices_context(_complete('Em aberto',2),'I1')
r=resolve_refund_option(payment_method=c['payment_method'],has_open_bill=c['has_open_bill'],invoice_statuses=c['invoice_statuses'])
assert r['refund_option']=='1' and r['format_text']=='sms'
def test_refund_credito_para_dacc_cartao_ou_parcelamento():
for method in ('DACC|Cartão|Parcelamento','debito_automatico','cartao_credito'):
r=resolve_refund_option(payment_method=method,has_open_bill=True,invoice_statuses=['Em aberto'])
assert r['refund_option']=='0'
def test_refund_credito_para_fatura_paga_ou_ja_contestada():
for status in ('Pago','Contestada'):
r=resolve_refund_option(payment_method='fatura',has_open_bill=False,invoice_statuses=[status])
assert r['refund_option']=='0'
def test_cutoff_referencia_corrige_bug_mes_seguinte():
ref=datetime(2026,8,18,12)
passed, cutoff=billing_cutoff_reference(10,reference_datetime=ref)
assert passed is True and cutoff.date().isoformat()=='2026-08-10'
passed2, cutoff2=billing_cutoff_reference(25,reference_datetime=ref)
assert passed2 is True and cutoff2.date().isoformat()=='2026-07-25'
def test_cutdate_regra_um_mes():
ref=datetime(2026,8,18)
assert next_cutoff_from_cut_date(datetime(2026,6,1),reference_datetime=ref)[0] is True
assert next_cutoff_from_cut_date(datetime(2026,8,1),reference_datetime=ref)[0] is False
def test_due_day_iso_e_br():
assert due_day('2026-08-25')==25
assert due_day('25/08/2026')==25
def test_dependente_forca_conta_certa_manual():
assert manual_conta_certa_from_evidence(dependent_invoice_item=True) is True
def test_cutdate_da_fatura_define_manual():
ref=datetime(2026,8,18)
assert manual_conta_certa_from_evidence(invoice_item={'cutDate':'2026-06-01'},reference_datetime=ref) is True
assert manual_conta_certa_from_evidence(invoice_item={'cutDate':'2026-08-01'},reference_datetime=ref) is False
def test_check_invoice_status_enriquece_prefetch_sem_nova_api():
class Client:
def consultar_faturas(self,*a,**k): raise AssertionError('não deve chamar API')
class Service: client=Client()
a=build_contas_workflow_actions(Service()).get('check_invoice_status')
out=a({'complete_invoices_payload':_complete('Em aberto',3),'invoice_id':'I1'}, {'input':{},'vars':{}})
assert out['success'] is True
assert out['invoice_status']=='Em aberto'
assert out['has_open_bill'] is True
assert out['payment_type_id']==3
assert out['requires_sms'] is True
def test_check_invoice_status_falha_sem_prefetch():
class Service: pass
a=build_contas_workflow_actions(Service()).get('check_invoice_status')
try:
a({'invoice_id':'I1'},{'input':{},'vars':{}})
except RuntimeError as exc:
assert 'prefetch' in str(exc)
else:
raise AssertionError('deveria falhar sem prefetch')
def test_abrir_contestacao_deriva_refund_manual_e_normaliza_barcode_zero():
captured={}
class Client:
def billing_analysis(self,msisdn): return {'119':{'SVA Detalhe Total':[{'desc':'VAS Musica','value':29.90}]}}
def contrato(self,msisdn): return {'billing_profile':{'date':{'cutoffDay':1}}}
def contestar(self,payload):
captured.update(payload)
return {'itemsResponse':[{'status':'CRIAR','itemName':'VAS Musica','correctAccountStatus':'CRIAR'}],'barcode':'0'*44}
class Service: client=Client()
a=build_contas_workflow_actions(Service()).get('abrir_contestacao_cliente')
complete=_complete('Em aberto',2)
state={'input':{},'vars':{'check_invoice_status':{'complete_invoices_payload':complete,**complete_invoices_context(complete,'I1')}}}
out=a({'msisdn':'119','social_sec_no':'123','customer_id':'C1','invoice_id':'I1','items':[{'itemName':'VAS Musica','claimedAmount':'29,90','validatedAmount':'29,90'}],'protocolo_id':'P1','skip_invoice_item_validation':True},state)
assert captured['refundOption']=='1'
assert captured['manualContaCertaIndicator'] is True
assert captured['contestationType']=='0'
assert captured['adjustReason']=='SERVICO_NAO_SOLICITADO'
assert out['barcode']==''
assert out['conta_certa_status']=='CRIAR'