Files
roa2web-service-auto/reports-app/telegram-bot/tests/test_helpers_real_simple.py
Marius Mutu a7a1bef375 Add missing test files and update .gitignore to allow test files
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>
2025-10-25 15:09:43 +03:00

324 lines
11 KiB
Python

"""
SIMPLIFIED REAL Integration Test for FAZA 2
⚠️ MANUAL INTEGRATION TEST - Not run by default in CI/CD
This script:
1. Logs into backend with REAL credentials from environment variables
2. Gets REAL JWT token
3. Tests helper functions with REAL backend data
REQUIREMENTS:
- Backend API running on localhost:8001
- Environment variables: TEST_USERNAME, TEST_PASSWORD
- NO DATABASE DEPENDENCY - Direct API testing
USAGE:
# Set credentials
export TEST_USERNAME="your_username"
export TEST_PASSWORD="your_password"
# Run as script
python tests/test_helpers_real_simple.py
# Run via pytest (requires --run-integration or -m integration)
pytest tests/test_helpers_real_simple.py -m integration
NOTE: This test is marked as @pytest.mark.integration and skipped by default.
"""
import pytest
import asyncio
import logging
import os
import sys
import httpx
# Add parent directory to path
sys.path.insert(0, '/mnt/e/proiecte/roa2web/roa2web/reports-app/telegram-bot')
from app.bot.helpers import (
search_companies_by_name,
create_company_selection_keyboard,
format_company_context_footer
)
from app.api.client import get_backend_client
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
async def get_real_jwt_token() -> str:
"""
Login to backend and get REAL JWT token.
Uses actual backend credentials to authenticate.
Returns JWT access token.
"""
print("\n📝 Logging into backend to get REAL JWT token...")
# REAL credentials for Oracle backend (MUST be set in environment)
username = os.getenv("TEST_USERNAME")
password = os.getenv("TEST_PASSWORD")
if not username or not password:
raise ValueError(
"Integration tests require TEST_USERNAME and TEST_PASSWORD environment variables.\n"
"Set them in your shell or .env file before running integration tests."
)
try:
async with httpx.AsyncClient(base_url="http://localhost:8001") as client:
response = await client.post(
"/api/auth/login",
json={
"username": username,
"password": password
}
)
response.raise_for_status()
data = response.json()
if 'access_token' in data:
token = data['access_token']
print(f"✅ Got REAL JWT token: {token[:30]}...")
return token
else:
print(f"❌ No access_token in response: {data}")
return None
except Exception as e:
print(f"❌ Login failed: {e}")
return None
@pytest.mark.integration
async def test_real_helpers():
"""
Integration test for helper functions with REAL backend data.
Requires:
- Backend API running on localhost:8001
- TEST_USERNAME and TEST_PASSWORD environment variables
This test is skipped by default. Run with: pytest -m integration
"""
print("\n" + "="*80)
print(" FAZA 2 - REAL INTEGRATION TEST (Simplified)")
print(" Testing with ACTUAL backend API at localhost:8001")
print("="*80)
# Step 1: Get JWT token
jwt_token = await get_real_jwt_token()
if not jwt_token:
print("\n❌ FAILED: Could not get JWT token")
print(" Make sure backend is running at localhost:8001")
print(" and credentials are correct")
return False
print(f"\n✅ Prerequisites OK - Backend connected, JWT token obtained")
all_tests_passed = True
# TEST 1: Search companies with REAL data
print("\n" + "="*80)
print("TEST 1: search_companies_by_name() with REAL backend")
print("="*80)
try:
# Get all companies first
client = get_backend_client()
async with client:
all_companies = await client.get_user_companies(jwt_token=jwt_token)
print(f"✅ Got {len(all_companies)} REAL companies from backend")
if all_companies:
print("\nFirst 5 companies:")
for i, comp in enumerate(all_companies[:5], 1):
print(f" {i}. ID:{comp.get('id_firma'):3} | {comp.get('name')} | CUI:{comp.get('fiscal_code', 'N/A')}")
# Test search by partial name
first_name = all_companies[0].get('name', '')
search_term = first_name[:4].upper() if len(first_name) >= 4 else first_name
print(f"\n--- Testing search with term: '{search_term}' ---")
results = await search_companies_by_name(search_term, jwt_token)
print(f"✅ Found {len(results)} matches")
# Test case-insensitive
results_lower = await search_companies_by_name(search_term.lower(), jwt_token)
if len(results) == len(results_lower):
print("✅ Case-insensitive search works!")
else:
print(f"❌ Case-insensitive FAILED: {len(results)} vs {len(results_lower)}")
all_tests_passed = False
print("\n✅ TEST 1 PASSED")
else:
print("⚠️ No companies found - cannot test search")
except Exception as e:
print(f"❌ TEST 1 FAILED: {e}")
import traceback
traceback.print_exc()
all_tests_passed = False
# TEST 2: Create keyboard with REAL data
print("\n" + "="*80)
print("TEST 2: create_company_selection_keyboard() with REAL data")
print("="*80)
try:
if all_companies:
keyboard = create_company_selection_keyboard(all_companies[:10], max_buttons=5)
print(f"✅ Created keyboard with {len(keyboard.inline_keyboard)} buttons")
# Check first few buttons
print("\nFirst 3 buttons:")
for i, row in enumerate(keyboard.inline_keyboard[:3], 1):
button = row[0]
print(f" {i}. {button.text[:50]}")
print(f" Callback: {button.callback_data}")
# Verify callback format
first_callback = keyboard.inline_keyboard[0][0].callback_data
if first_callback.startswith("select_company:"):
print("\n✅ Callback format correct")
else:
print(f"\n❌ Invalid callback: {first_callback}")
all_tests_passed = False
# Test with overflow
if len(all_companies) > 5:
keyboard_overflow = create_company_selection_keyboard(all_companies, max_buttons=5)
if len(keyboard_overflow.inline_keyboard) == 6: # 5 companies + overflow
print("✅ Overflow indicator works correctly")
else:
print(f"❌ Overflow FAILED: expected 6 buttons, got {len(keyboard_overflow.inline_keyboard)}")
all_tests_passed = False
print("\n✅ TEST 2 PASSED")
else:
print("⚠️ No companies - cannot test keyboard")
except Exception as e:
print(f"❌ TEST 2 FAILED: {e}")
import traceback
traceback.print_exc()
all_tests_passed = False
# TEST 3: Format footer with REAL company name
print("\n" + "="*80)
print("TEST 3: format_company_context_footer() with REAL data")
print("="*80)
try:
if all_companies:
company_name = all_companies[0].get('name')
footer = format_company_context_footer(company_name)
print(f"Company: {company_name}")
print(f"\nFormatted footer:")
print(repr(footer))
print("\nRendered:")
print(footer)
# Verify structure
checks = [
("Has separator", "" in footer),
("Has emoji", "📊" in footer),
("Has company name", company_name in footer),
("Has command", "/selectcompany" in footer),
("Starts with newlines", footer.startswith("\n\n")),
("Is discrete", len(footer) < 150)
]
print("\nVerification:")
all_checks_passed = True
for check_name, passed in checks:
status = "" if passed else ""
print(f" {status} {check_name}")
if not passed:
all_checks_passed = False
all_tests_passed = False
if all_checks_passed:
print("\n✅ TEST 3 PASSED")
else:
print("\n❌ TEST 3 FAILED")
else:
print("⚠️ No companies - cannot test footer")
except Exception as e:
print(f"❌ TEST 3 FAILED: {e}")
import traceback
traceback.print_exc()
all_tests_passed = False
# BONUS TEST: Dashboard data
print("\n" + "="*80)
print("BONUS: Get REAL dashboard data (for FAZA 3 preparation)")
print("="*80)
try:
if all_companies:
company_id = all_companies[0].get('id_firma')
company_name = all_companies[0].get('name')
print(f"Company: {company_name} (ID: {company_id})")
async with get_backend_client() as client:
dashboard_data = await client.get_dashboard_data(
company_id=company_id,
jwt_token=jwt_token
)
if dashboard_data:
print(f"✅ Got REAL dashboard data!")
print(f"\nData keys: {list(dashboard_data.keys())[:10]}")
# Sample some values
sample_keys = ['sold_total', 'facturi_emise', 'facturi_platite']
print("\nSample values:")
for key in sample_keys:
if key in dashboard_data:
print(f" {key}: {dashboard_data[key]}")
print("\n✅ BONUS TEST PASSED - Dashboard data accessible!")
else:
print("⚠️ No dashboard data returned")
else:
print("⚠️ No companies - cannot test dashboard")
except Exception as e:
print(f"⚠️ BONUS TEST WARNING: {e}")
# Don't fail on bonus test
# SUMMARY
print("\n" + "="*80)
print(" SUMMARY")
print("="*80)
if all_tests_passed:
print("\n🎉 ALL TESTS PASSED!")
print("✅ FAZA 2 implementation is CORRECT with REAL data!")
print("\nHelper functions work correctly with:")
print(" - REAL backend API (localhost:8001)")
print(" - REAL JWT authentication")
print(" - REAL company data from Oracle database")
return True
else:
print("\n⚠️ SOME TESTS FAILED")
print("Please review the errors above")
return False
if __name__ == "__main__":
success = asyncio.run(test_real_helpers())
sys.exit(0 if success else 1)