Files
RichardandClaude Opus 4.8 f4045f08e1 Engine-Testabdeckung (Guards) + K3-Korrektur am echten Bug-Ort
Testabdeckung fuer den geldkritischen Engine-Pfad (bisher 0 Tests), da die
Fable-Guards zwischen Services entstehen und Unit-Tests sie nicht fangen:
- Engine._clob -> IClobClient (verhaltensneutral, DI registriert IClobClient bereits);
  ProcessAccountOrderAsync internal. FakeMarketRepository/FakeAccountRepository ergaenzt.
- 7 Integrationstests (CopyTradingEngineTests) ueber gemockten CLOB: H3 BUY-Skip bei
  ExitPending, Doppel-SELL-Guard, K3 System-Close (TraderId==0) schliesst Fremd-Position,
  Fremd-Trader-SELL bleibt abgewiesen, H2 Cleanup schont Leiter (+ Kontrast ohne Leiter).

DABEI ECHTEN BUG GEFANGEN: Der K3-Fix aus Slice 3 sass an der falschen Stelle
(IsAuthorizedSell nach dem Position-Remove, Zeile ~643) – der eigentliche Ownership-Check
ist der fruehe inPortfolio-Lookup (Zeile 437, p.SourceTraderId == signal.TraderId), der
System-Signale schon vorher mit early return abwies. Fix jetzt am richtigen Ort; der
downstream-Check bleibt als Defense-in-depth. Ohne den Engine-Test waere das unentdeckt geblieben.

Build 0 Fehler, 242 Tests gruen, --smoke-ui ok.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 19:38:11 +02:00

28 lines
1.1 KiB
C#

using System.Collections.Generic;
using PolyTrader.Core.Persistence;
using PolyTraderSharp.Models;
namespace PolyTrader.Tests.Fakes
{
/// <summary>No-op-Stub für <see cref="IMarketRepository"/> (Engine-Tests nutzen den MarketCache).</summary>
public sealed class FakeMarketRepository : IMarketRepository
{
public MarketData? GetById(string id) => null;
public MarketData? FindByTokenId(string tokenId) => null;
public List<MarketData> GetActive() => new();
public void Upsert(MarketData market) { }
public void Insert(MarketData market) { }
public void Update(MarketData market) { }
public void EnsureIndexes() { }
}
/// <summary>In-Memory-Stub für <see cref="IAccountRepository"/>.</summary>
public sealed class FakeAccountRepository : IAccountRepository
{
public List<(int AccountId, decimal Balance)> Upserts { get; } = new();
public List<AccountState> GetAll() => new();
public void Upsert(AccountState account) => Upserts.Add((account.AccountId, account.AvailableBalance));
public void Delete(int accountId) { }
}
}