This commit addresses the overly restrictive .gitignore pattern that was excluding all test files (test_*.py), including legitimate pytest and unittest test suites essential for code quality and CI/CD. Changes to .gitignore: - Added negation patterns !**/tests/test_*.py and !**/test_*.py to allow proper test files while still blocking temporary scripts - This enables pytest test suites to be tracked by git Added test files (17 files): Telegram Bot Tests (15 files): - reports-app/telegram-bot/tests/test_auth.py Tests for authentication and account linking flow - reports-app/telegram-bot/tests/test_callbacks.py Tests for callback query handlers - reports-app/telegram-bot/tests/test_formatters.py Tests for message formatting utilities - reports-app/telegram-bot/tests/test_formatters_extended.py Extended formatter tests - reports-app/telegram-bot/tests/test_handlers_menu.py Tests for menu handlers - reports-app/telegram-bot/tests/test_helpers.py Tests for helper functions - reports-app/telegram-bot/tests/test_helpers_extended.py Extended helper tests - reports-app/telegram-bot/tests/test_helpers_real.py Real integration tests for helpers - reports-app/telegram-bot/tests/test_helpers_real_simple.py Simplified integration tests - reports-app/telegram-bot/tests/test_login_flow.py Complete login flow integration tests - reports-app/telegram-bot/tests/test_menus.py Menu system tests - reports-app/telegram-bot/tests/test_session_company.py Session and company management tests - reports-app/telegram-bot/test_claude_integration.py Manual integration test (Claude AI) - reports-app/telegram-bot/test_claude_response.py Response formatting test - reports-app/telegram-bot/test_db.py Database operations manual test Shared Module Tests (2 files): - shared/auth/test_auth.py Authentication system tests - shared/database/test_pool.py Oracle connection pool tests Security verification: ✅ All test files use mock objects, fixtures, and environment variables ✅ No hardcoded credentials or secrets found ✅ Safe for version control 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
280 lines
8.4 KiB
Python
280 lines
8.4 KiB
Python
"""
|
|
Tests for FAZA 2 extended formatter functions.
|
|
Tests new formatters for treasury breakdown, clients/suppliers balance, and cash flow evolution.
|
|
"""
|
|
|
|
import pytest
|
|
from app.bot.formatters import (
|
|
format_treasury_casa_response,
|
|
format_treasury_banca_response,
|
|
format_clients_balance_response,
|
|
format_suppliers_balance_response,
|
|
format_cashflow_evolution_response,
|
|
format_client_detail_response,
|
|
format_supplier_detail_response
|
|
)
|
|
|
|
|
|
def test_format_treasury_casa_response():
|
|
"""Test formatare trezorerie casa"""
|
|
data = {
|
|
'accounts': [
|
|
{'name': 'Casa Ron', 'type': 'Casa', 'balance': 5000},
|
|
{'name': 'Casa Valuta', 'type': 'Casa', 'balance': 2000}
|
|
],
|
|
'total': 7000
|
|
}
|
|
result = format_treasury_casa_response(data, "Test Co")
|
|
|
|
assert "Casa" in result
|
|
assert "7,000" in result or "7000" in result # Total: 5000 + 2000
|
|
assert "Casa Ron" in result
|
|
assert "Test Co" in result # Footer
|
|
|
|
|
|
def test_format_treasury_casa_no_accounts():
|
|
"""Test formatare trezorerie casa fără conturi"""
|
|
data = {
|
|
'accounts': [],
|
|
'total': 0
|
|
}
|
|
result = format_treasury_casa_response(data, "Test Co")
|
|
|
|
assert "Casa" in result
|
|
assert "Nu există conturi" in result
|
|
|
|
|
|
def test_format_treasury_banca_response():
|
|
"""Test formatare trezorerie banca"""
|
|
data = {
|
|
'accounts': [
|
|
{'name': 'BCR', 'type': 'Banca', 'balance': 10000},
|
|
{'name': 'BRD', 'type': 'Banca', 'balance': 5000}
|
|
],
|
|
'total': 15000
|
|
}
|
|
result = format_treasury_banca_response(data, "Test Co")
|
|
|
|
assert "Banc" in result # "Bancă" or "Banca"
|
|
assert "15,000" in result or "15000" in result
|
|
assert "BCR" in result
|
|
assert "Test Co" in result
|
|
|
|
|
|
def test_format_treasury_banca_no_accounts():
|
|
"""Test formatare trezorerie banca fără conturi"""
|
|
data = {
|
|
'accounts': [],
|
|
'total': 0
|
|
}
|
|
result = format_treasury_banca_response(data, "Test Co")
|
|
|
|
assert "Banc" in result
|
|
assert "Nu există conturi" in result
|
|
|
|
|
|
def test_format_clients_balance_with_maturity():
|
|
"""Test formatare sold clienți cu scadențe"""
|
|
clients = [
|
|
{'id': 1, 'name': 'Client A', 'balance': 15000},
|
|
{'id': 2, 'name': 'Client B', 'balance': 8500}
|
|
]
|
|
maturity_data = {
|
|
'in_term': 18000,
|
|
'overdue': 5500,
|
|
'total': 23500
|
|
}
|
|
|
|
result = format_clients_balance_response(clients, maturity_data, "Test Co")
|
|
|
|
assert "Client" in result
|
|
assert "23,500" in result or "23500" in result # Total
|
|
assert "18,000" in result or "18000" in result # În termen
|
|
assert "5,500" in result or "5500" in result # Restant
|
|
assert "Client A" in result
|
|
assert "Test Co" in result
|
|
|
|
|
|
def test_format_clients_balance_empty():
|
|
"""Test formatare sold clienți listă goală"""
|
|
clients = []
|
|
maturity_data = {
|
|
'in_term': 0,
|
|
'overdue': 0,
|
|
'total': 0
|
|
}
|
|
|
|
result = format_clients_balance_response(clients, maturity_data, "Test Co")
|
|
|
|
assert "Clien" in result # Matches "Clienți"
|
|
assert "Nu exist" in result # Matches "Nu există clienți"
|
|
|
|
|
|
def test_format_clients_balance_sorting():
|
|
"""Test sortare clienți după sold"""
|
|
clients = [
|
|
{'id': 1, 'name': 'Client A', 'balance': 5000},
|
|
{'id': 2, 'name': 'Client B', 'balance': 15000},
|
|
{'id': 3, 'name': 'Client C', 'balance': 10000}
|
|
]
|
|
maturity_data = {'in_term': 30000, 'overdue': 0, 'total': 30000}
|
|
|
|
result = format_clients_balance_response(clients, maturity_data, "Test Co")
|
|
|
|
# Client B ar trebui să fie primul (cea mai mare sumă)
|
|
lines = result.split('\n')
|
|
client_b_line = [l for l in lines if 'Client B' in l][0]
|
|
assert '1.' in client_b_line # Primul în listă
|
|
|
|
|
|
def test_format_suppliers_balance():
|
|
"""Test formatare sold furnizori"""
|
|
suppliers = [
|
|
{'id': 1, 'name': 'Supplier A', 'balance': 5000}
|
|
]
|
|
maturity_data = {
|
|
'in_term': 4000,
|
|
'overdue': 1000,
|
|
'total': 5000
|
|
}
|
|
|
|
result = format_suppliers_balance_response(suppliers, maturity_data, "Test Co")
|
|
|
|
assert "Furniz" in result
|
|
assert "5,000" in result or "5000" in result
|
|
assert "Supplier A" in result
|
|
assert "Test Co" in result
|
|
|
|
|
|
def test_format_suppliers_balance_empty():
|
|
"""Test formatare sold furnizori listă goală"""
|
|
suppliers = []
|
|
maturity_data = {'in_term': 0, 'overdue': 0, 'total': 0}
|
|
|
|
result = format_suppliers_balance_response(suppliers, maturity_data, "Test Co")
|
|
|
|
assert "Furniz" in result
|
|
assert "Nu există furnizori" in result
|
|
|
|
|
|
def test_format_cashflow_evolution():
|
|
"""Test formatare evoluție cash flow"""
|
|
performance = {
|
|
'incasari_total': 100000,
|
|
'plati_total': 80000,
|
|
'net': 20000
|
|
}
|
|
monthly = {
|
|
'months': ['Ian', 'Feb', 'Mar'],
|
|
'incasari': [30000, 35000, 35000],
|
|
'plati': [25000, 27000, 28000]
|
|
}
|
|
|
|
result = format_cashflow_evolution_response(performance, monthly, "Test Co")
|
|
|
|
assert "Evolu" in result # "Evoluție"
|
|
assert "100,000" in result or "100000" in result
|
|
assert "Ian" in result or "Feb" in result # Cel puțin o lună
|
|
assert "Test Co" in result
|
|
|
|
|
|
def test_format_cashflow_evolution_no_monthly_data():
|
|
"""Test formatare evoluție fără date lunare"""
|
|
performance = {
|
|
'incasari_total': 100000,
|
|
'plati_total': 80000,
|
|
'net': 20000
|
|
}
|
|
monthly = {
|
|
'months': [],
|
|
'incasari': [],
|
|
'plati': []
|
|
}
|
|
|
|
result = format_cashflow_evolution_response(performance, monthly, "Test Co")
|
|
|
|
assert "Evolu" in result
|
|
assert "Nu există date lunare" in result
|
|
|
|
|
|
def test_format_client_detail_response():
|
|
"""Test formatare detalii client"""
|
|
client = {'id': 1, 'name': 'Client A', 'balance': 15000}
|
|
invoices = [
|
|
{'id': 1, 'number': 'FV001', 'amount': 5000, 'status': 'unpaid'},
|
|
{'id': 2, 'number': 'FV002', 'amount': 3500, 'status': 'paid'}
|
|
]
|
|
|
|
result = format_client_detail_response(client, invoices, "Test Co")
|
|
|
|
assert "Client A" in result
|
|
assert "15,000" in result or "15000" in result
|
|
assert "FV001" in result
|
|
assert "FV002" in result
|
|
assert "Test Co" in result
|
|
|
|
|
|
def test_format_client_detail_no_invoices():
|
|
"""Test formatare detalii client fără facturi"""
|
|
client = {'id': 1, 'name': 'Client A', 'balance': 15000}
|
|
invoices = []
|
|
|
|
result = format_client_detail_response(client, invoices, "Test Co")
|
|
|
|
assert "Client A" in result
|
|
assert "Nu există facturi" in result
|
|
|
|
|
|
def test_format_supplier_detail_response():
|
|
"""Test formatare detalii furnizor"""
|
|
supplier = {'id': 1, 'name': 'Supplier A', 'balance': 5000}
|
|
invoices = [
|
|
{'id': 1, 'number': 'FC001', 'amount': 2000, 'status': 'unpaid'}
|
|
]
|
|
|
|
result = format_supplier_detail_response(supplier, invoices, "Test Co")
|
|
|
|
assert "Supplier A" in result
|
|
assert "5,000" in result or "5000" in result
|
|
assert "FC001" in result
|
|
assert "Test Co" in result
|
|
|
|
|
|
def test_format_supplier_detail_no_invoices():
|
|
"""Test formatare detalii furnizor fără facturi"""
|
|
supplier = {'id': 1, 'name': 'Supplier A', 'balance': 5000}
|
|
invoices = []
|
|
|
|
result = format_supplier_detail_response(supplier, invoices, "Test Co")
|
|
|
|
assert "Supplier A" in result
|
|
assert "Nu există facturi" in result
|
|
|
|
|
|
def test_format_client_detail_many_invoices():
|
|
"""Test limitare număr facturi afișate (max 10)"""
|
|
client = {'id': 1, 'name': 'Client A', 'balance': 50000}
|
|
invoices = [
|
|
{'id': i, 'number': f'FV{i:03d}', 'amount': 1000, 'status': 'unpaid'}
|
|
for i in range(1, 16) # 15 facturi
|
|
]
|
|
|
|
result = format_client_detail_response(client, invoices, "Test Co")
|
|
|
|
assert "FV001" in result # Prima factură
|
|
assert "FV010" in result # A 10-a factură
|
|
assert "FV011" not in result # A 11-a nu ar trebui să apară
|
|
assert "încă 5 facturi" in result # Indicator overflow
|
|
|
|
|
|
def test_formatters_handle_missing_keys():
|
|
"""Test că formatterii nu crapă dacă lipsesc chei"""
|
|
# Test cu dict-uri goale/incomplete
|
|
assert format_treasury_casa_response({}, "Test") != ""
|
|
assert format_treasury_banca_response({}, "Test") != ""
|
|
assert format_clients_balance_response([], {}, "Test") != ""
|
|
assert format_suppliers_balance_response([], {}, "Test") != ""
|
|
assert format_cashflow_evolution_response({}, {}, "Test") != ""
|
|
assert format_client_detail_response({}, [], "Test") != ""
|
|
assert format_supplier_detail_response({}, [], "Test") != ""
|