diplomail (Stage F): docs + edge-case tests + LibreTranslate recipe
Closes the documentation gaps from the freshly-audited diplomail implementation. FUNCTIONAL.md gains a §11 "Diplomatic mail" with the full user-facing story across all five stages, mirrored into FUNCTIONAL_ru.md as the project conventions require. A new backend/docs/diplomail-translator-setup.md captures the LibreTranslate operational recipe (Docker image, env wiring, manual smoke test, troubleshooting). The package README gains a "Multi-instance posture" note documenting the deliberate absence of FOR UPDATE in the worker pickup query — single-instance is safe today; multi-instance scaling will revisit the claim mechanism. Two small edge-case tests round things out: malformed LibreTranslate response bodies (single string, short array, empty array, missing field) must surface as errors so the worker falls back instead of crashing; and an empty translation queue must produce zero events on three consecutive Worker.Tick calls. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -139,3 +139,35 @@ func TestLibreTranslateRequiresURL(t *testing.T) {
|
||||
t.Fatalf("expected error for empty URL")
|
||||
}
|
||||
}
|
||||
|
||||
// TestLibreTranslateRejectsMalformedArray defends against a server
|
||||
// that returns a partial / unexpected `translatedText` payload. The
|
||||
// client must surface an error (not panic, not return a half-empty
|
||||
// Result) so the worker can decide between retry and fallback.
|
||||
func TestLibreTranslateRejectsMalformedArray(t *testing.T) {
|
||||
t.Parallel()
|
||||
cases := []struct {
|
||||
name string
|
||||
body string
|
||||
}{
|
||||
{"single string", `{"translatedText": "only one"}`},
|
||||
{"array of one", `{"translatedText": ["only one"]}`},
|
||||
{"empty array", `{"translatedText": []}`},
|
||||
{"missing field", `{"foo":"bar"}`},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
body := tc.body
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
_, _ = w.Write([]byte(body))
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
tr, _ := NewLibreTranslate(LibreTranslateConfig{URL: server.URL})
|
||||
res, err := tr.Translate(context.Background(), "en", "ru", "subject", "body")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error for malformed body %q, got %+v", body, res)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user