mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 08:54:55 +08:00
feat(api): proxy Translation Memory over bat.sock
This commit is contained in:
+110
-8
@@ -629,13 +629,16 @@ func (f *fakeBackend) TaskCancel(ctx context.Context, taskID string) (*backendrp
|
||||
|
||||
type controlBackend struct {
|
||||
*fakeBackend
|
||||
calls []string
|
||||
parseTextUnitQueries []backendrpc.TextUnitQueryParams
|
||||
parseErrorQueries []backendrpc.TextUnitQueryParams
|
||||
translationTaskUpdates []backendrpc.TranslationTaskUpdateParams
|
||||
translationTaskListParams []backendrpc.TranslationTaskListParams
|
||||
localizedPublishParams []backendrpc.LocalizedPublishParams
|
||||
localizedRollbackParams []backendrpc.LocalizedRollbackParams
|
||||
calls []string
|
||||
parseTextUnitQueries []backendrpc.TextUnitQueryParams
|
||||
parseErrorQueries []backendrpc.TextUnitQueryParams
|
||||
translationTaskUpdates []backendrpc.TranslationTaskUpdateParams
|
||||
translationTaskListParams []backendrpc.TranslationTaskListParams
|
||||
translationMemorySummaryParams []backendrpc.TranslationMemorySummaryParams
|
||||
translationMemoryQueryParams []backendrpc.TranslationMemoryQueryParams
|
||||
translationMemoryConfirmParams []backendrpc.TranslationMemoryConfirmParams
|
||||
localizedPublishParams []backendrpc.LocalizedPublishParams
|
||||
localizedRollbackParams []backendrpc.LocalizedRollbackParams
|
||||
}
|
||||
|
||||
func (b *controlBackend) DaemonReload(ctx context.Context) (*backendrpc.Ack, error) {
|
||||
@@ -777,6 +780,51 @@ func (b *controlBackend) TranslationProofread(ctx context.Context) (json.RawMess
|
||||
return json.RawMessage(`{"translation_workflow_status":"manual_proofreading"}`), nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) TranslationMemorySummary(ctx context.Context, params backendrpc.TranslationMemorySummaryParams) (*backendrpc.TranslationMemorySummaryReport, error) {
|
||||
b.calls = append(b.calls, "translation.memory.summary")
|
||||
b.translationMemorySummaryParams = append(b.translationMemorySummaryParams, params)
|
||||
schemaVersion := uint64(1)
|
||||
return &backendrpc.TranslationMemorySummaryReport{
|
||||
Available: true,
|
||||
Path: params.TranslationMemoryPath,
|
||||
SchemaVersion: &schemaVersion,
|
||||
Summary: &backendrpc.TranslationMemorySummary{
|
||||
SchemaVersion: schemaVersion,
|
||||
RecordCount: 2,
|
||||
TrustedCount: 1,
|
||||
CandidateCount: 1,
|
||||
SupersededCount: 0,
|
||||
RejectedCount: 0,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) TranslationMemoryQuery(ctx context.Context, params backendrpc.TranslationMemoryQueryParams) (*backendrpc.TranslationMemoryQueryReport, error) {
|
||||
b.calls = append(b.calls, "translation.memory.query")
|
||||
b.translationMemoryQueryParams = append(b.translationMemoryQueryParams, params)
|
||||
return &backendrpc.TranslationMemoryQueryReport{
|
||||
Available: true,
|
||||
Path: params.TranslationMemoryPath,
|
||||
SourceText: params.SourceText,
|
||||
SourceContext: params.SourceContext,
|
||||
Matches: []backendrpc.TranslationMemoryMatch{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) TranslationMemoryConfirm(ctx context.Context, params backendrpc.TranslationMemoryConfirmParams) (*backendrpc.TranslationMemoryConfirmReport, error) {
|
||||
b.calls = append(b.calls, "translation.memory.confirm")
|
||||
b.translationMemoryConfirmParams = append(b.translationMemoryConfirmParams, params)
|
||||
return &backendrpc.TranslationMemoryConfirmReport{
|
||||
Available: true,
|
||||
Path: params.TranslationMemoryPath,
|
||||
Entry: backendrpc.TranslationMemoryEntry{
|
||||
RecordID: params.RecordID,
|
||||
TranslationSourceKind: "provider",
|
||||
TrustStatus: "trusted",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) LocalizedStatus(ctx context.Context) (json.RawMessage, error) {
|
||||
b.calls = append(b.calls, "localized.status")
|
||||
return json.RawMessage(`{"localized_release_status":"localized","status_code":"localized.published"}`), nil
|
||||
@@ -960,6 +1008,42 @@ func TestAdminTranslationQueryEndpointsProxyAuthenticatedRequests(t *testing.T)
|
||||
t.Fatalf("calls=%v", backend.calls)
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodGet, "/admin/translation/memory/summary?translation_memory_path=%2Fvar%2Flib%2Fbat%2Ftranslation-memory.sqlite", nil)
|
||||
request.Header.Set("Authorization", "Bearer translation-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("TM summary status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if !strings.Contains(recorder.Body.String(), `"trusted_count":1`) ||
|
||||
len(backend.translationMemorySummaryParams) != 1 ||
|
||||
backend.translationMemorySummaryParams[0].TranslationMemoryPath != "/var/lib/bat/translation-memory.sqlite" {
|
||||
t.Fatalf("TM summary body=%s params=%#v", recorder.Body.String(), backend.translationMemorySummaryParams)
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodGet, "/admin/translation/memory/query?source_text=Hello&source_context=%7B%22destination%22%3A%22Bundle%2Fdialogue.bundle%22%7D&limit=25", nil)
|
||||
request.Header.Set("Authorization", "Bearer translation-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("TM query status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if len(backend.translationMemoryQueryParams) != 1 ||
|
||||
backend.translationMemoryQueryParams[0].SourceText != "Hello" ||
|
||||
backend.translationMemoryQueryParams[0].SourceContext["destination"] != "Bundle/dialogue.bundle" ||
|
||||
backend.translationMemoryQueryParams[0].Limit == nil ||
|
||||
*backend.translationMemoryQueryParams[0].Limit != 25 {
|
||||
t.Fatalf("TM query body=%s params=%#v", recorder.Body.String(), backend.translationMemoryQueryParams)
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodGet, "/admin/translation/memory/query", nil)
|
||||
request.Header.Set("Authorization", "Bearer translation-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Fatalf("missing TM query source status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodGet, "/admin/translation/tasks?limit=0", nil)
|
||||
request.Header.Set("Authorization", "Bearer translation-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
@@ -1502,7 +1586,9 @@ func TestOpenAPIAndAdminReservedEndpoints(t *testing.T) {
|
||||
!strings.Contains(rr.Body.String(), "/admin/tasks") ||
|
||||
!strings.Contains(rr.Body.String(), "/admin/parse/text-units") ||
|
||||
!strings.Contains(rr.Body.String(), "translation_results") ||
|
||||
!strings.Contains(rr.Body.String(), "task-cancel") {
|
||||
!strings.Contains(rr.Body.String(), "task-cancel") ||
|
||||
!strings.Contains(rr.Body.String(), "/admin/translation/memory/query") ||
|
||||
!strings.Contains(rr.Body.String(), "translation-memory-confirm") {
|
||||
t.Fatalf("openapi missing dashboard/task admin routes")
|
||||
}
|
||||
|
||||
@@ -1524,6 +1610,8 @@ func TestOpenAPIAndAdminReservedEndpoints(t *testing.T) {
|
||||
links := strings.Join(admin.Links, "\n")
|
||||
if !strings.Contains(links, "/admin/translation/tasks") ||
|
||||
!strings.Contains(links, "/admin/translation/handoff") ||
|
||||
!strings.Contains(links, "/admin/translation/memory/summary") ||
|
||||
!strings.Contains(links, "/admin/translation/memory/query") ||
|
||||
!strings.Contains(links, "/admin/dashboard/") ||
|
||||
!strings.Contains(links, "/admin/parse/text-units") ||
|
||||
!strings.Contains(links, "/admin/tasks/logs") {
|
||||
@@ -1729,6 +1817,7 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
|
||||
{name: "translation task update", action: "translation-task-update", body: `{"task_id":"textunit/v-current/Scenario","status":"completed","provider":"manual","provider_run_id":"manual-run-1","translation_results":[{"unit_id":"direct:a#unit:0","source_text":"source","translated_text":"译文"}]}`, rpcMethod: "translation.task.update", call: "translation.task.update"},
|
||||
{name: "translation worker run", action: "translation-worker-run", body: `{"provider":"mock","concurrency":8,"max_tasks":2,"retry_backoff_seconds":0,"worker_id":"dashboard-worker"}`, rpcMethod: "translation.worker.run", call: "translation.worker.run"},
|
||||
{name: "translation proofread", action: "translation-proofread", rpcMethod: "translation.proofread", call: "translation.proofread"},
|
||||
{name: "translation memory confirm", action: "translation-memory-confirm", body: `{"record_id":"tm-record-1","reviewer":"reviewer","reason":"reviewed"}`, rpcMethod: "translation.memory.confirm", call: "translation.memory.confirm"},
|
||||
{name: "localized publish", action: "localized-publish", body: `{"from_worker":true,"localized_release_id":"localized-1","force":true}`, rpcMethod: "localized.publish", call: "localized.publish"},
|
||||
{name: "localized rollback", action: "localized-rollback", body: `{"localized_release_id":"localized-1"}`, rpcMethod: "localized.rollback", call: "localized.rollback"},
|
||||
}
|
||||
@@ -1760,6 +1849,11 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
|
||||
backend.translationTaskUpdates[0].TranslationResults[0].TranslatedText != "译文" {
|
||||
t.Fatalf("translation task updates=%#v", backend.translationTaskUpdates)
|
||||
}
|
||||
if len(backend.translationMemoryConfirmParams) != 1 ||
|
||||
backend.translationMemoryConfirmParams[0].RecordID != "tm-record-1" ||
|
||||
backend.translationMemoryConfirmParams[0].Reviewer != "reviewer" {
|
||||
t.Fatalf("TM confirm params=%#v", backend.translationMemoryConfirmParams)
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodPost, "/admin/control/translation-task-update", strings.NewReader(`{"task_id":""}`))
|
||||
request.Header.Set("Authorization", "Bearer control-token")
|
||||
@@ -1785,6 +1879,14 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
|
||||
t.Fatalf("invalid translation worker status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodPost, "/admin/control/translation-memory-confirm", strings.NewReader(`{"record_id":""}`))
|
||||
request.Header.Set("Authorization", "Bearer control-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Fatalf("invalid TM confirm status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodPost, "/admin/control/localized-publish", strings.NewReader(`{"from_worker":true,"translation_file":"/tmp/workbench.json"}`))
|
||||
request.Header.Set("Authorization", "Bearer control-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
|
||||
Reference in New Issue
Block a user