fix(glossary): 补齐术语删除和审核门禁
bat-rust / Build and test Rust (push) Canceled after 0s
bat-rust / Build and test Go API (push) Canceled after 0s

This commit is contained in:
2026-09-08 20:59:27 +08:00
parent 94483ff14d
commit 0275a890bc
19 changed files with 589 additions and 32 deletions
+17 -4
View File
@@ -642,6 +642,7 @@ type controlBackend struct {
glossaryDiagnoseParams []backendrpc.GlossaryDiagnoseParams
glossaryMutationParams []backendrpc.GlossaryTermMutationParams
glossaryReviewParams []backendrpc.GlossaryReviewParams
glossaryDeleteParams []backendrpc.GlossaryDeleteParams
localizedPublishParams []backendrpc.LocalizedPublishParams
localizedRollbackParams []backendrpc.LocalizedRollbackParams
}
@@ -905,6 +906,12 @@ func (b *controlBackend) GlossaryDeprecate(ctx context.Context, params backendrp
return &backendrpc.GlossaryMutationReport{Available: true, Path: params.GlossaryPath}, nil
}
func (b *controlBackend) GlossaryDelete(ctx context.Context, params backendrpc.GlossaryDeleteParams) (*backendrpc.GlossaryMutationReport, error) {
b.calls = append(b.calls, "translation.glossary.delete")
b.glossaryDeleteParams = append(b.glossaryDeleteParams, params)
return &backendrpc.GlossaryMutationReport{Available: true, Path: params.GlossaryPath}, 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
@@ -1708,6 +1715,7 @@ 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(), "glossary_override") ||
!strings.Contains(rr.Body.String(), "task-cancel") ||
!strings.Contains(rr.Body.String(), "/admin/translation/memory/query") ||
!strings.Contains(rr.Body.String(), "translation-memory-confirm") {
@@ -1936,7 +1944,7 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
{name: "repair", action: "repair", rpcMethod: "resource.repair", call: "resource.repair"},
{name: "catalog refresh", action: "catalog-refresh", rpcMethod: "catalog.refresh", call: "catalog.refresh"},
{name: "task cancel", action: "task-cancel", body: `{"task_id":"task-sync-1"}`, rpcMethod: "task.cancel", call: "task.cancel"},
{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 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":"译文","glossary_override":{"reviewer":"reviewer","reason":"approved deviation","provenance":"manual-review","confirmed_unix_seconds":100}}]}`, 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"},
@@ -1944,6 +1952,7 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
{name: "translation glossary update", action: "translation-glossary-update", body: `{"term_id":"term-sensei","source_term":"Sensei","recommended_translation":"老师","review_status":"draft","reviewer":"reviewer","source":{"source_kind":"manual","observed_unix_seconds":100}}`, rpcMethod: "translation.glossary.update", call: "translation.glossary.update"},
{name: "translation glossary approve", action: "translation-glossary-approve", body: `{"term_id":"term-sensei","reviewer":"reviewer","reason":"approved"}`, rpcMethod: "translation.glossary.approve", call: "translation.glossary.approve"},
{name: "translation glossary deprecate", action: "translation-glossary-deprecate", body: `{"term_id":"term-sensei","reviewer":"reviewer","reason":"retired"}`, rpcMethod: "translation.glossary.deprecate", call: "translation.glossary.deprecate"},
{name: "translation glossary delete", action: "translation-glossary-delete", body: `{"term_id":"term-sensei","reviewer":"reviewer","reason":"duplicate"}`, rpcMethod: "translation.glossary.delete", call: "translation.glossary.delete"},
{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"},
}
@@ -1972,7 +1981,9 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
if len(backend.translationTaskUpdates) != 1 ||
backend.translationTaskUpdates[0].Provider != "manual" ||
len(backend.translationTaskUpdates[0].TranslationResults) != 1 ||
backend.translationTaskUpdates[0].TranslationResults[0].TranslatedText != "译文" {
backend.translationTaskUpdates[0].TranslationResults[0].TranslatedText != "译文" ||
backend.translationTaskUpdates[0].TranslationResults[0].GlossaryOverride == nil ||
backend.translationTaskUpdates[0].TranslationResults[0].GlossaryOverride.Reviewer != "reviewer" {
t.Fatalf("translation task updates=%#v", backend.translationTaskUpdates)
}
if len(backend.translationMemoryConfirmParams) != 1 ||
@@ -1984,8 +1995,10 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
backend.glossaryMutationParams[0].TermID != "term-sensei" ||
backend.glossaryMutationParams[1].Reviewer != "reviewer" ||
len(backend.glossaryReviewParams) != 2 ||
backend.glossaryReviewParams[0].TermID != "term-sensei" {
t.Fatalf("Glossary params mutation=%#v review=%#v", backend.glossaryMutationParams, backend.glossaryReviewParams)
backend.glossaryReviewParams[0].TermID != "term-sensei" ||
len(backend.glossaryDeleteParams) != 1 ||
backend.glossaryDeleteParams[0].Reason != "duplicate" {
t.Fatalf("Glossary params mutation=%#v review=%#v delete=%#v", backend.glossaryMutationParams, backend.glossaryReviewParams, backend.glossaryDeleteParams)
}
request := httptest.NewRequest(http.MethodPost, "/admin/control/translation-task-update", strings.NewReader(`{"task_id":""}`))