Stufe 4c (#764): Kommentare in C#, WebUI-Skripten, CSS und HTML auf Englisch
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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
da4ceac7d5
commit
837a634a22
@@ -3,7 +3,7 @@ using System.Text;
|
||||
|
||||
namespace ClawdDotNet.Core.Tests.Deploymentcenter;
|
||||
|
||||
/// <summary>Fängt die letzte Anfrage ab und antwortet fest, ohne Netzwerkzugriff.</summary>
|
||||
/// <summary>Captures the last request and answers with a fixed response, without network access.</summary>
|
||||
internal sealed class CapturingHandler(
|
||||
HttpStatusCode status = HttpStatusCode.OK,
|
||||
string responseBody = """{"status":"success"}""")
|
||||
|
||||
@@ -33,8 +33,8 @@ public sealed class DeploymentcenterApiTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ein Fehlerumschlag zählt auch dann, wenn der Statuscode 200 lautet — der Server
|
||||
/// antwortet nicht überall mit passendem HTTP-Code.
|
||||
/// An error envelope counts even if the status code is 200 — the server
|
||||
/// does not answer with a matching HTTP code everywhere.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Fehlerumschlag_mit_HTTP_200_zaehlt_trotzdem()
|
||||
@@ -54,15 +54,15 @@ public sealed class DeploymentcenterApiTests
|
||||
[Fact]
|
||||
public void Nicht_HTTPS_wird_abgelehnt()
|
||||
{
|
||||
// Über eine ungesicherte Verbindung ginge das Token im Klartext.
|
||||
// Over an unsecured connection the token would go in plain text.
|
||||
Should.Throw<ArgumentException>(() => new DeploymentcenterApi("http://dc.example", "tok"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Localhost_darf_auch_ohne_TLS()
|
||||
{
|
||||
// Eine lokale Testinstallation hat selten ein Zertifikat, und mithören kann
|
||||
// auf dem eigenen Rechner niemand.
|
||||
// A local test installation rarely has a certificate, and nobody can listen in
|
||||
// on the own machine.
|
||||
using var api = new DeploymentcenterApi("http://localhost:8080", "tok");
|
||||
api.BaseUrl.ShouldBe("http://localhost:8080");
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ public sealed class ErrorReporterTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eine Fehlerschleife darf nicht in tausend Anfragen münden. Derselbe Fehler geht
|
||||
/// höchstens einmal je Zeitfenster raus — der Server drosselt zwar auch, aber erst,
|
||||
/// nachdem die Anfragen schon über die Leitung waren.
|
||||
/// An error loop must not turn into a thousand requests. The same error goes out
|
||||
/// at most once per time window — the server throttles too, but only
|
||||
/// after the requests have already gone over the line.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Derselbe_Fehler_geht_nur_einmal_je_Zeitfenster_raus()
|
||||
@@ -81,8 +81,8 @@ public sealed class ErrorReporterTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ein Meldeweg, der selbst wirft, wäre die schlechteste aller Welten — der
|
||||
/// ursprüngliche Fehler ginge dabei verloren.
|
||||
/// A reporting path that throws itself would be the worst of all worlds — the
|
||||
/// original error would get lost in the process.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Ein_abgelehnter_Aufruf_wirft_nicht_nach_aussen()
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace ClawdDotNet.Core.Tests.Deploymentcenter;
|
||||
|
||||
public sealed class InstanceHealthProviderTests
|
||||
{
|
||||
/// <summary>Liefert einen festen Tagesverbrauch, ohne DB.</summary>
|
||||
/// <summary>Delivers a fixed daily consumption, without a DB.</summary>
|
||||
private sealed class FakeUsage(DailyUsage daily) : IUsageRepository
|
||||
{
|
||||
public Task RecordAsync(RunUsage usage, CancellationToken ct) => Task.CompletedTask;
|
||||
@@ -54,8 +54,8 @@ public sealed class InstanceHealthProviderTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ein Heartbeat beweist nur, dass ein Faden läuft. Steht der Scanner, arbeitet die
|
||||
/// Instanz nichts mehr ab — und genau das soll die Prüfung sichtbar machen.
|
||||
/// A heartbeat only proves that a thread is running. If the scanner stands still, the
|
||||
/// instance no longer works through anything — and exactly that is what the check should make visible.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Stehender_Scanner_meldet_warning()
|
||||
@@ -89,8 +89,8 @@ public sealed class InstanceHealthProviderTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metriken werden serverseitig nur ausgewertet, wenn sie Zahlen sind — alles andere
|
||||
/// verwirft der Verlauf stillschweigend. Beschreibendes gehört in die Meldung.
|
||||
/// Metrics are only evaluated server-side if they are numbers — everything else
|
||||
/// the history silently discards. Descriptive things belong in the message.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Instanzname_steht_in_der_Meldung_nicht_in_den_Metriken()
|
||||
|
||||
@@ -31,8 +31,8 @@ public sealed class TokenProvisionerTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ein Sub-Token darf keine weiteren ausstellen. Das ist der Regelfall beim zweiten
|
||||
/// Start und muss als sauberer Fehler herauskommen, nicht als Absturz.
|
||||
/// A sub-token may not issue further ones. That is the normal case at the second
|
||||
/// start and must come out as a clean error, not as a crash.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Abgelehnte_Provisionierung_wirft_mit_Code()
|
||||
@@ -50,12 +50,12 @@ public sealed class TokenProvisionerTests
|
||||
// ─── whoami (SDK 2.7.1) ───
|
||||
|
||||
/// <summary>
|
||||
/// Die Auskunft, auf die es ankommt: an welches Projekt das Token gebunden ist.
|
||||
/// The information that matters: which project the token is bound to.
|
||||
///
|
||||
/// <para>Seit SDK 2.8.1 erbt ein Watchdog-Monitor das Projekt seines Ping-Tokens.
|
||||
/// Fehlt die Bindung, landen die Befunde im Scheinprojekt „default" — und eine
|
||||
/// Abfrage nach dem eigenen Projekt liefert für eine laufende, meldende Instanz null
|
||||
/// Befunde. Die Aufsicht sähe aus wie „nichts auffällig".</para>
|
||||
/// <para>Since SDK 2.8.1 a watchdog monitor inherits the project of its ping token.
|
||||
/// If the binding is missing, the findings land in the phantom project "default" — and a
|
||||
/// query for the own project returns zero findings for a running, reporting instance.
|
||||
/// Supervision would look like "nothing unusual".</para>
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Whoami_liest_die_Projektbindung()
|
||||
@@ -85,7 +85,7 @@ public sealed class TokenProvisionerTests
|
||||
[Fact]
|
||||
public async Task Ein_Token_ohne_Projekt_faellt_auf()
|
||||
{
|
||||
// project_slug ist JSON-null, nicht abwesend - genau so kommt es vom Server.
|
||||
// project_slug is JSON null, not absent - exactly as it comes from the server.
|
||||
var handler = new CapturingHandler(HttpStatusCode.OK,
|
||||
"""
|
||||
{"status":"success","token_id":"tok_s_9","name":"Instanz","type":"sub",
|
||||
@@ -103,8 +103,8 @@ public sealed class TokenProvisionerTests
|
||||
[Fact]
|
||||
public async Task Eine_Antwort_ohne_Felder_wirft_nicht()
|
||||
{
|
||||
// Ein aelterer Server kennt whoami nicht in dieser Form. Die Auskunft darf
|
||||
// ausfallen; abstuerzen darf sie nicht.
|
||||
// An older server does not know whoami in this form. The information may
|
||||
// be missing; it must not crash.
|
||||
var handler = new CapturingHandler(HttpStatusCode.OK, """{"status":"success"}""");
|
||||
|
||||
using var api = new DeploymentcenterApi("https://dc.example", "t", new HttpClient(handler));
|
||||
|
||||
@@ -37,9 +37,9 @@ public sealed class WatchdogClientTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Der Server legt die Version in <c>watchdog_monitors.app_version</c> ab. Bei
|
||||
/// mehreren Instanzen ist das der Unterschied zwischen „läuft" und „läuft noch auf
|
||||
/// der alten Fassung".
|
||||
/// The server stores the version in <c>watchdog_monitors.app_version</c>. With
|
||||
/// several instances that is the difference between "runs" and "still runs on
|
||||
/// the old version".
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Heartbeat_traegt_die_Anwendungsversion()
|
||||
@@ -52,9 +52,9 @@ public sealed class WatchdogClientTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Der Monitor wird serverseitig über source + instance geführt. Zwei Instanzen
|
||||
/// derselben Anwendung müssen deshalb unterschiedliche instance-Werte melden —
|
||||
/// sonst überschreiben sie sich gegenseitig, und der Ausfall einer bliebe unsichtbar.
|
||||
/// The monitor is tracked server-side via source + instance. Two instances
|
||||
/// of the same application must therefore report different instance values —
|
||||
/// otherwise they overwrite each other, and the failure of one would stay invisible.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Jede_Instanz_meldet_unter_eigenem_Instanznamen()
|
||||
@@ -87,7 +87,7 @@ public sealed class WatchdogClientTests
|
||||
handler.LastBody.ShouldNotBeNull().ShouldContain("\"scheduler\":{\"ok\":false,\"message\":\"Steht.\"}");
|
||||
}
|
||||
|
||||
/// <summary>Leere Angaben bleiben weg, statt als leeres Objekt zu erscheinen.</summary>
|
||||
/// <summary>Empty details are left out instead of appearing as an empty object.</summary>
|
||||
[Fact]
|
||||
public async Task Ohne_Checks_und_Metriken_bleiben_die_Felder_weg()
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace ClawdDotNet.Core.Tests.Deploymentcenter;
|
||||
|
||||
public sealed class WatchdogHeartbeatServiceTests
|
||||
{
|
||||
/// <summary>Merkt sich, was gesendet wurde, ohne Netzwerk.</summary>
|
||||
/// <summary>Remembers what was sent, without a network.</summary>
|
||||
private sealed class RecordingClient : IWatchdogClient
|
||||
{
|
||||
public List<(string Status, string? Message)> Heartbeats { get; } = [];
|
||||
@@ -49,8 +49,8 @@ public sealed class WatchdogHeartbeatServiceTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Beim Update ist die Instanz gleich weg, kommt aber wieder. <c>stopped</c> wäre
|
||||
/// die falsche Auskunft: Der Monitor bliebe liegen, bis jemand ihn anfasst.
|
||||
/// On update the instance is about to go away, but comes back. <c>stopped</c> would be
|
||||
/// the wrong information: the monitor would be left alone until someone touches it.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Angekuendigte_Wartung_meldet_maintenance()
|
||||
@@ -69,7 +69,7 @@ public sealed class WatchdogHeartbeatServiceTests
|
||||
client.Events[^1].Kind.ShouldBe(WatchdogEventKind.MaintenanceStart);
|
||||
}
|
||||
|
||||
/// <summary>Der erste Beat geht sofort raus, nicht erst nach einem vollen Intervall.</summary>
|
||||
/// <summary>The first beat goes out immediately, not only after a full interval.</summary>
|
||||
[Fact]
|
||||
public async Task Erster_Heartbeat_kommt_sofort()
|
||||
{
|
||||
@@ -79,7 +79,7 @@ public sealed class WatchdogHeartbeatServiceTests
|
||||
service.Start();
|
||||
await service.DisposeAsync();
|
||||
|
||||
// Start-Ereignis, mindestens ein Beat, dann die Abmeldung.
|
||||
// Start event, at least one beat, then the deregistration.
|
||||
client.Events[0].Kind.ShouldBe(WatchdogEventKind.Started);
|
||||
client.Heartbeats.Count.ShouldBeGreaterThanOrEqualTo(2);
|
||||
client.Heartbeats[0].Status.ShouldBe(WatchdogStatus.Ok);
|
||||
|
||||
Reference in New Issue
Block a user