====== kassensichv.mock ====== → [[lyx_-_programmiersprache:units:kassensichv|Zurück zur KassenSichV-Übersicht]] Vollständiger TSE-Mock-Provider ohne physische Hardware. Für Unit-Tests, CI/CD-Pipelines und Bondrucktests. Erzeugt deterministische SHA-256-basierte Testsignaturen (kein echtes ECDSA). Keine externen Abhängigkeiten. ===== Import ===== import kassensichv.types; import kassensichv.mock; import kassensichv.manager; ===== Erzeugen ===== pub fn TseMockNew(): int64; // Gibt TseManager-Handle zurück (allokiert) // Kein Konfigurationsparameter nötig — Mock akzeptiert alles // Mit TseManagerFree() freigeben var mgr: int64 := TseMockNew(); // Direkt verwendbar — keine Initialize()-Konfiguration nötig ===== Fehlersimulation ===== Der Mock kann verschiedene Fehlersituationen simulieren, um die Fehlerbehandlung der Kassensoftware zu testen: // Verbindungsfehler simulieren (TseProcessBeleg gibt success=0, code=503) pub fn TseMockSetSimulateError(mgr: int64, on: int64): void; // Timeout simulieren (TseProcessBeleg gibt success=0, code=408) pub fn TseMockSetSimulateTimeout(mgr: int64, on: int64): void; fn TestVerbindungsfehler(): void { var mgr: int64 := TseMockNew(); TseMockSetSimulateError(mgr, 1); // Fehler einschalten var beleg: BelegDaten; beleg.prozessTyp := PROZESSTYP_KASSENBELEG; var sig: int64 := TseProcessBeleg(mgr, addr beleg); var s: SigErgebnis := (sig as *SigErgebnis)^; // s.success = 0, s.errorMsg = "Simulierter Verbindungsfehler..." SigErgebnisFree(sig); TseMockSetSimulateError(mgr, 0); // Fehler ausschalten TseManagerFree(mgr); } ===== Testzustandsabfrage ===== // Aktueller Transaktionszähler (monoton steigend ab 0) pub fn TseMockGetZaehler(mgr: int64): int64; // TSE-Seriennummer des Mocks pub fn TseMockGetSerial(mgr: int64): int64; // pchar, allokiert Der Mock-Zähler startet bei 0 und steigt mit jedem erfolgreichen ''TseProcessBeleg'' / ''TseCloseBeleg'' um 1. Er kann in Tests für Assertions verwendet werden: fn TestZaehlerMonoton(): void { var mgr: int64 := TseMockNew(); // Erster Bon: Zähler wird 1 var b1: BelegDaten; b1.prozessTyp := PROZESSTYP_KASSENBELEG; var sig1: int64 := TseProcessBeleg(mgr, addr b1); SigErgebnisFree(sig1); // Zweiter Bon: Zähler wird 2 var b2: BelegDaten; b2.prozessTyp := PROZESSTYP_KASSENBELEG; var sig2: int64 := TseProcessBeleg(mgr, addr b2); var s2: SigErgebnis := (sig2 as *SigErgebnis)^; // s2.sigZaehler == 2 (immer höher als vorheriger) SigErgebnisFree(sig2); TseManagerFree(mgr); } ===== Signaturwert-Erzeugung ===== Der Mock erzeugt Signaturen als SHA-256-Hash über ''(TransId + Zeitstempel-Millisekunden)'', Base64-kodiert. Das Ergebnis ist deterministisch für gleiche Eingaben, aber **kryptografisch unsicher** — nur für Tests geeignet. Echte TSEs verwenden ECDSA/SHA-256 mit einem hardwaregeschützten Schlüssel (nicht aus dem Gerät extrahierbar). ===== Mock-Seriennummer ===== Der Mock verwendet immer die feste Seriennummer: MOCK-TSE-0000000000000001 In Tests, die die TSE-Seriennummer auf dem Bon prüfen, diesen Wert als Referenz verwenden. ===== ExportAuditData ===== ''TseExportAuditData'' mit dem Mock erstellt eine leere ''mock_audit.tar'' im Zielverzeichnis. Die Datei existiert, hat aber keinen Inhalt (Mock-Daten). Nützlich, um den Export-Workflow (Verzeichnis schreibbar, ''index.json'' vorhanden) ohne echte TSE zu testen. ===== Vollständiges Test-Beispiel ===== import kassensichv.types; import kassensichv.mock; import kassensichv.manager; fn TestKomplettprozess(): void { var mgr: int64 := TseMockNew(); // --- Einfacher Bon --- var beleg: BelegDaten; beleg.prozessTyp := PROZESSTYP_KASSENBELEG; beleg.kassenNr := "KASSE-001"c; beleg.prozessDaten := "Kaffee;2.50_0.00_0.00_0.00_0.00"c; beleg.umsatz := 250; var sig: int64 := TseProcessBeleg(mgr, addr beleg); var s: SigErgebnis := (sig as *SigErgebnis)^; // Prüfungen // s.success == 1 // s.sigZaehler == 1 // s.qrCode beginnt mit "V0;MOCK-TSE-" SigErgebnisFree(sig); // --- Fehlersimulation --- TseMockSetSimulateTimeout(mgr, 1); var beleg2: BelegDaten; beleg2.prozessTyp := PROZESSTYP_KASSENBELEG; var sig2: int64 := TseProcessBeleg(mgr, addr beleg2); var s2: SigErgebnis := (sig2 as *SigErgebnis)^; // s2.success == 0 // s2.errorMsg enthält "Timeout" SigErgebnisFree(sig2); TseMockSetSimulateTimeout(mgr, 0); TseManagerFree(mgr); } ----- Letzte Aktualisierung: 2026-06-12