Files
motia/bitbylaw/scripts/adressen_sync/test_adressen_gueltigbis_modify.py
bitbylaw 7856dd1d68 Add tests for Kommunikation Sync implementation and verification scripts
- Implemented comprehensive tests for the Kommunikation Sync functionality, covering base64 encoding, marker parsing, creation, type detection, and integration scenarios.
- Added a verification script to check for unique IDs in Advoware communications, ensuring stability and integrity of the IDs.
- Created utility scripts for code validation, notification testing, and PUT response detail analysis to enhance development and testing processes.
- Updated README with details on new tools and their usage.
2026-02-08 23:05:56 +00:00

469 lines
17 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Test: gueltigBis nachträglich setzen und entfernen (Soft-Delete)
==================================================================
Ziele:
1. Teste ob gueltigBis via PUT gesetzt werden kann (Deaktivierung)
2. Teste ob gueltigBis via PUT entfernt werden kann (Reaktivierung)
3. Teste ob gueltigBis auf null/None gesetzt werden kann
"""
import asyncio
import sys
import os
from datetime import datetime
# Add parent directory to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from services.advoware import AdvowareAPI
# Test-Konfiguration
TEST_BETNR = 104860
# ANSI Color codes
BOLD = '\033[1m'
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
RESET = '\033[0m'
def print_header(text):
print(f"\n{BOLD}{'='*80}{RESET}")
print(f"{BOLD}{text}{RESET}")
print(f"{BOLD}{'='*80}{RESET}\n")
def print_success(text):
print(f"{GREEN}{text}{RESET}")
def print_error(text):
print(f"{RED}{text}{RESET}")
def print_warning(text):
print(f"{YELLOW}{text}{RESET}")
def print_info(text):
print(f"{BLUE} {text}{RESET}")
class SimpleLogger:
def info(self, msg): pass
def error(self, msg): print_error(msg)
def debug(self, msg): pass
def warning(self, msg): pass
class SimpleContext:
def __init__(self):
self.logger = SimpleLogger()
def log_info(self, msg): pass
def log_error(self, msg): print_error(msg)
def log_debug(self, msg): pass
async def test_1_create_active_address():
"""Test 1: Erstelle aktive Adresse (ohne gueltigBis)"""
print_header("TEST 1: Erstelle aktive Adresse (OHNE gueltigBis)")
context = SimpleContext()
advo = AdvowareAPI(context=context)
address_data = {
"strasse": "Soft-Delete Test Straße",
"plz": "66666",
"ort": "Teststadt",
"land": "DE",
"bemerkung": "TEST-SOFTDELETE: Für gueltigBis Modifikation",
"gueltigVon": "2026-01-01T00:00:00"
# KEIN gueltigBis → unbegrenzt gültig
}
print_info("Erstelle Adresse OHNE gueltigBis (unbegrenzt aktiv)...")
try:
result = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='POST',
json_data=address_data
)
if result and len(result) > 0:
addr = result[0]
print_success(f"✓ Adresse erstellt")
print_info(f" rowId: {addr.get('rowId')}")
print_info(f" gueltigVon: {addr.get('gueltigVon')}")
print_info(f" gueltigBis: {addr.get('gueltigBis')} (sollte None sein)")
# Hole echten Index via GET
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
for a in all_addresses:
if (a.get('bemerkung') or '').startswith('TEST-SOFTDELETE'):
print_info(f" reihenfolgeIndex: {a.get('reihenfolgeIndex')}")
return a.get('reihenfolgeIndex')
return None
else:
print_error("POST fehlgeschlagen")
return None
except Exception as e:
print_error(f"Fehler: {e}")
import traceback
traceback.print_exc()
return None
async def test_2_deactivate_via_gueltigbis(index):
"""Test 2: Deaktiviere Adresse durch Setzen von gueltigBis"""
print_header("TEST 2: Deaktivierung - gueltigBis nachträglich setzen")
context = SimpleContext()
advo = AdvowareAPI(context=context)
try:
# Hole aktuelle Adresse
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
test_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
if not test_addr:
print_error(f"Adresse mit Index {index} nicht gefunden")
return False
print_info("Status VORHER:")
print(f" gueltigVon: {test_addr.get('gueltigVon')}")
print(f" gueltigBis: {test_addr.get('gueltigBis')}")
# Setze gueltigBis auf gestern (= deaktiviert)
print_info("\nSetze gueltigBis auf 2024-12-31 (Vergangenheit = deaktiviert)...")
update_data = {
"strasse": test_addr.get('strasse'),
"plz": test_addr.get('plz'),
"ort": test_addr.get('ort'),
"land": test_addr.get('land'),
"gueltigVon": test_addr.get('gueltigVon'),
"gueltigBis": "2024-12-31T23:59:59" # ← Vergangenheit
}
result = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen/{index}',
method='PUT',
json_data=update_data
)
print_success("✓ PUT erfolgreich")
# Prüfe Ergebnis
print_info("\nHole Adresse erneut und prüfe gueltigBis...")
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
updated_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
if updated_addr:
print_info("Status NACHHER:")
print(f" gueltigVon: {updated_addr.get('gueltigVon')}")
print(f" gueltigBis: {updated_addr.get('gueltigBis')}")
if updated_addr.get('gueltigBis') == "2024-12-31T00:00:00":
print_success("\n✓✓✓ PERFEKT: gueltigBis wurde nachträglich gesetzt!")
print_success("✓ Adresse kann via PUT deaktiviert werden!")
return True
else:
print_error(f"\n❌ gueltigBis nicht korrekt: {updated_addr.get('gueltigBis')}")
return False
else:
print_error("Adresse nach PUT nicht gefunden")
return False
except Exception as e:
print_error(f"Fehler: {e}")
import traceback
traceback.print_exc()
return False
async def test_3_reactivate_set_far_future(index):
"""Test 3: Reaktivierung durch Setzen auf weit in Zukunft"""
print_header("TEST 3: Reaktivierung - gueltigBis auf fernes Datum setzen")
context = SimpleContext()
advo = AdvowareAPI(context=context)
try:
# Hole aktuelle Adresse
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
test_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
if not test_addr:
print_error(f"Adresse mit Index {index} nicht gefunden")
return False
print_info("Status VORHER (deaktiviert):")
print(f" gueltigBis: {test_addr.get('gueltigBis')}")
# Setze gueltigBis auf weit in Zukunft
print_info("\nSetze gueltigBis auf 2099-12-31 (weit in Zukunft = aktiv)...")
update_data = {
"strasse": test_addr.get('strasse'),
"plz": test_addr.get('plz'),
"ort": test_addr.get('ort'),
"land": test_addr.get('land'),
"gueltigVon": test_addr.get('gueltigVon'),
"gueltigBis": "2099-12-31T23:59:59" # ← Weit in Zukunft
}
await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen/{index}',
method='PUT',
json_data=update_data
)
print_success("✓ PUT erfolgreich")
# Prüfe Ergebnis
print_info("\nHole Adresse erneut...")
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
updated_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
if updated_addr:
print_info("Status NACHHER (reaktiviert):")
print(f" gueltigBis: {updated_addr.get('gueltigBis')}")
if updated_addr.get('gueltigBis') == "2099-12-31T00:00:00":
print_success("\n✓✓✓ PERFEKT: gueltigBis wurde auf Zukunft gesetzt!")
print_success("✓ Adresse ist jetzt wieder aktiv!")
return True
else:
print_error(f"\n❌ gueltigBis nicht korrekt: {updated_addr.get('gueltigBis')}")
return False
else:
print_error("Adresse nach PUT nicht gefunden")
return False
except Exception as e:
print_error(f"Fehler: {e}")
import traceback
traceback.print_exc()
return False
async def test_4_remove_gueltigbis_completely(index):
"""Test 4: Entferne gueltigBis komplett (null/None)"""
print_header("TEST 4: gueltigBis komplett entfernen (null/None)")
context = SimpleContext()
advo = AdvowareAPI(context=context)
try:
# Hole aktuelle Adresse
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
test_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
if not test_addr:
print_error(f"Adresse mit Index {index} nicht gefunden")
return None
print_info("Status VORHER:")
print(f" gueltigBis: {test_addr.get('gueltigBis')}")
# Versuche 1: gueltigBis weglassen
print_info("\n=== Versuch 1: gueltigBis komplett weglassen ===")
update_data = {
"strasse": test_addr.get('strasse'),
"plz": test_addr.get('plz'),
"ort": test_addr.get('ort'),
"land": test_addr.get('land'),
"gueltigVon": test_addr.get('gueltigVon')
# gueltigBis absichtlich weggelassen
}
await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen/{index}',
method='PUT',
json_data=update_data
)
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
updated_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
result_1 = updated_addr.get('gueltigBis') if updated_addr else "ERROR"
print_info(f"Ergebnis: gueltigBis = {result_1}")
if result_1 is None:
print_success("✓ Weglassen entfernt gueltigBis!")
return "omit"
# Versuche 2: gueltigBis = None/null
print_info("\n=== Versuch 2: gueltigBis explizit auf None setzen ===")
update_data['gueltigBis'] = None
await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen/{index}',
method='PUT',
json_data=update_data
)
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
updated_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
result_2 = updated_addr.get('gueltigBis') if updated_addr else "ERROR"
print_info(f"Ergebnis: gueltigBis = {result_2}")
if result_2 is None:
print_success("✓ None entfernt gueltigBis!")
return "none"
# Versuche 3: gueltigBis = ""
print_info("\n=== Versuch 3: gueltigBis auf leeren String setzen ===")
update_data['gueltigBis'] = ""
try:
await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen/{index}',
method='PUT',
json_data=update_data
)
all_addresses = await advo.api_call(
f'/api/v1/advonet/Beteiligte/{TEST_BETNR}/Adressen',
method='GET'
)
updated_addr = next((a for a in all_addresses if a.get('reihenfolgeIndex') == index), None)
result_3 = updated_addr.get('gueltigBis') if updated_addr else "ERROR"
print_info(f"Ergebnis: gueltigBis = {result_3}")
if result_3 is None:
print_success("✓ Leerer String entfernt gueltigBis!")
return "empty"
except Exception as e:
print_warning(f"⚠ Leerer String wird abgelehnt: {e}")
print_warning("\n⚠ gueltigBis kann nicht komplett entfernt werden")
print_info("💡 Lösung: Setze auf weit in Zukunft (2099-12-31) für 'unbegrenzt aktiv'")
return "not_possible"
except Exception as e:
print_error(f"Fehler: {e}")
import traceback
traceback.print_exc()
return None
async def main():
print(f"\n{BOLD}╔══════════════════════════════════════════════════════════════╗{RESET}")
print(f"{BOLD}║ gueltigBis nachträglich ändern (Soft-Delete Tests) ║{RESET}")
print(f"{BOLD}╚══════════════════════════════════════════════════════════════╝{RESET}\n")
print(f"Test-Konfiguration:")
print(f" BetNr: {TEST_BETNR}")
print(f" Datum: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
# Test 1: Erstelle aktive Adresse
index = await test_1_create_active_address()
if not index:
print_error("\nTest abgebrochen: Konnte Adresse nicht erstellen")
return
# Test 2: Deaktiviere via gueltigBis
can_deactivate = await test_2_deactivate_via_gueltigbis(index)
# Test 3: Reaktiviere via gueltigBis auf Zukunft
can_reactivate = await test_3_reactivate_set_far_future(index)
# Test 4: Versuche gueltigBis zu entfernen
remove_method = await test_4_remove_gueltigbis_completely(index)
# Finale Zusammenfassung
print(f"\n{BOLD}╔══════════════════════════════════════════════════════════════╗{RESET}")
print(f"{BOLD}║ FINALE ERKENNTNISSE ║{RESET}")
print(f"{BOLD}╚══════════════════════════════════════════════════════════════╝{RESET}\n")
print(f"{BOLD}Soft-Delete Funktionalität:{RESET}\n")
if can_deactivate:
print_success("✓✓✓ DEAKTIVIERUNG funktioniert:")
print_success(" • gueltigBis kann via PUT auf Vergangenheit gesetzt werden")
print_success(" • Beispiel: gueltigBis = '2024-12-31T23:59:59'")
print_success(" • Adresse bleibt in GET sichtbar (Client-Filter nötig)")
else:
print_error("✗ DEAKTIVIERUNG funktioniert NICHT")
print()
if can_reactivate:
print_success("✓✓✓ REAKTIVIERUNG funktioniert:")
print_success(" • gueltigBis kann via PUT auf Zukunft gesetzt werden")
print_success(" • Beispiel: gueltigBis = '2099-12-31T23:59:59'")
print_success(" • Adresse ist damit wieder aktiv")
else:
print_error("✗ REAKTIVIERUNG funktioniert NICHT")
print()
if remove_method:
if remove_method in ["omit", "none", "empty"]:
print_success(f"✓ gueltigBis entfernen funktioniert (Methode: {remove_method})")
if remove_method == "omit":
print_success(" • Weglassen des Feldes entfernt gueltigBis")
elif remove_method == "none":
print_success(" • Setzen auf None/null entfernt gueltigBis")
elif remove_method == "empty":
print_success(" • Setzen auf '' entfernt gueltigBis")
else:
print_warning("⚠ gueltigBis kann NICHT komplett entfernt werden")
print_info(" • Lösung: Setze auf 2099-12-31 für 'unbegrenzt aktiv'")
print(f"\n{BOLD}Empfohlener Workflow:{RESET}\n")
print_info("1. AKTIV (Standard):")
print_info(" → gueltigBis = '2099-12-31T23:59:59' oder None")
print_info(" → In EspoCRM: isActive = True")
print()
print_info("2. DEAKTIVIEREN (Soft-Delete):")
print_info(" → PUT mit gueltigBis = '2024-01-01T00:00:00' (Vergangenheit)")
print_info(" → In EspoCRM: isActive = False")
print()
print_info("3. REAKTIVIEREN:")
print_info(" → PUT mit gueltigBis = '2099-12-31T23:59:59' (Zukunft)")
print_info(" → In EspoCRM: isActive = True")
print()
print_info("4. SYNC LOGIC:")
print_info(" → GET /Adressen → filter wo gueltigBis > heute")
print_info(" → Sync nur aktive Adressen nach EspoCRM")
print_info(" → Update isActive basierend auf gueltigBis")
print(f"\n{YELLOW}⚠️ ACHTUNG: Test-Adresse 'TEST-SOFTDELETE' sollte bereinigt werden.{RESET}\n")
if __name__ == "__main__":
asyncio.run(main())