Rund 2.600 Kommentarblöcke in 310 C#-Dateien übersetzt, Begründungen vollständig erhalten: blockweise gleiche Anzahl wie vorher, kein Block unter 60 % seiner Länge, der Code außerhalb der Kommentare per Tokenizer byte-identisch geprüft. Zitate deutscher Oberflächentexte und Testdaten bleiben deutsch. WebUI: Kommentare in JS/CSS/HTML übersetzt, JSDoc-@param an die in 4b umbenannten Parameter angeglichen. Dabei behoben: - 4b hatte "tag" (HTML-Tag) als deutsches "Tag" gelesen und zu "dayValue" gemacht (makeElement, svg, Tagesübersicht) - zurück auf tag/day. - Aufgaben "InProgress" bekamen die Plakettenart "laufend", für die es nie eine CSS-Klasse gab - jetzt "success" wie laufende Instanzen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
96 lines
3.3 KiB
C#
96 lines
3.3 KiB
C#
using ClawdDotNet.Tools.DirectAPI;
|
|
using Shouldly;
|
|
|
|
namespace ClawdDotNet.Tools.Tests.DirectAPI;
|
|
|
|
/// <summary>
|
|
/// S3 from the inventory: the fetched URL went to the model as "source" —
|
|
/// including apikey= in the query string. The key thus ended up in the context, was
|
|
/// sent again at every following step and written into ChatContext.json.
|
|
/// </summary>
|
|
public sealed class UrlSanitizerTests
|
|
{
|
|
private const string Secret = "GEHEIM-abc123XYZ";
|
|
|
|
[Theory]
|
|
[InlineData("https://api.twelvedata.com/quote?symbol=NVDA&apikey=GEHEIM-abc123XYZ")]
|
|
[InlineData("https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=X&apikey=GEHEIM-abc123XYZ")]
|
|
[InlineData("https://api.example.com/v1?api_key=GEHEIM-abc123XYZ&x=1")]
|
|
[InlineData("https://api.example.com/v1?token=GEHEIM-abc123XYZ")]
|
|
[InlineData("https://api.example.com/v1?access_token=GEHEIM-abc123XYZ")]
|
|
[InlineData("https://api.example.com/v1?KEY=GEHEIM-abc123XYZ")]
|
|
[InlineData("https://api.example.com/v1?ApiKey=GEHEIM-abc123XYZ&other=2")]
|
|
[InlineData("https://api.example.com/v1?secret=GEHEIM-abc123XYZ")]
|
|
[InlineData("https://api.example.com/v1?a=1&apikey=GEHEIM-abc123XYZ#fragment")]
|
|
public void Sensible_Parameter_werden_maskiert(string url)
|
|
{
|
|
var sanitized = UrlSanitizer.Sanitize(url);
|
|
|
|
sanitized.ShouldNotContain(Secret);
|
|
sanitized.ShouldContain("***");
|
|
}
|
|
|
|
[Fact]
|
|
public void Harmlose_Parameter_bleiben_lesbar()
|
|
{
|
|
var sanitized = UrlSanitizer.Sanitize(
|
|
"https://api.twelvedata.com/quote?symbol=NVDA&interval=1day&apikey=GEHEIM-abc123XYZ");
|
|
|
|
sanitized.ShouldContain("symbol=NVDA");
|
|
sanitized.ShouldContain("interval=1day");
|
|
sanitized.ShouldContain("apikey=***");
|
|
}
|
|
|
|
[Fact]
|
|
public void Der_Pfad_bleibt_erhalten()
|
|
{
|
|
var sanitized = UrlSanitizer.Sanitize("https://api.massive.com/v2/aggs/ticker/NVDA?apikey=x");
|
|
|
|
sanitized.ShouldStartWith("https://api.massive.com/v2/aggs/ticker/NVDA?");
|
|
}
|
|
|
|
[Fact]
|
|
public void Ein_Fragment_bleibt_erhalten()
|
|
{
|
|
var sanitized = UrlSanitizer.Sanitize("https://x.de/a?apikey=geheim#abschnitt");
|
|
|
|
sanitized.ShouldEndWith("#abschnitt");
|
|
sanitized.ShouldNotContain("geheim");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("https://api.example.com/v1")]
|
|
[InlineData("https://api.example.com/v1?symbol=NVDA")]
|
|
public void URLs_ohne_sensible_Parameter_bleiben_unveraendert(string url)
|
|
{
|
|
UrlSanitizer.Sanitize(url).ShouldBe(url);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(null)]
|
|
[InlineData("")]
|
|
[InlineData(" ")]
|
|
public void Leere_Eingaben_fuehren_nicht_zu_einem_Fehler(string? url)
|
|
{
|
|
Should.NotThrow(() => UrlSanitizer.Sanitize(url));
|
|
}
|
|
|
|
[Fact]
|
|
public void Ein_Parameter_ohne_Wert_stoert_nicht()
|
|
{
|
|
var sanitized = UrlSanitizer.Sanitize("https://x.de/a?flag&apikey=geheim");
|
|
|
|
sanitized.ShouldContain("flag");
|
|
sanitized.ShouldNotContain("geheim");
|
|
}
|
|
|
|
[Fact]
|
|
public void Ein_Schluessel_als_Teil_eines_anderen_Namens_wird_nicht_faelschlich_maskiert()
|
|
{
|
|
// "monkey" contains "key", but is not a sensitive parameter.
|
|
var sanitized = UrlSanitizer.Sanitize("https://x.de/a?monkey=banane");
|
|
|
|
sanitized.ShouldBe("https://x.de/a?monkey=banane");
|
|
}
|
|
}
|