mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 08:54:55 +08:00
+123
-1
@@ -588,7 +588,8 @@ func (f *fakeBackend) ResourceManifest(ctx context.Context, offset int, limit in
|
||||
|
||||
type controlBackend struct {
|
||||
*fakeBackend
|
||||
calls []string
|
||||
calls []string
|
||||
translationTaskListParams []backendrpc.TranslationTaskListParams
|
||||
}
|
||||
|
||||
func (b *controlBackend) DaemonReload(ctx context.Context) (*backendrpc.Ack, error) {
|
||||
@@ -631,6 +632,38 @@ func (b *controlBackend) TranslationTaskUpdate(ctx context.Context, params backe
|
||||
return json.RawMessage(`{"task_status":"` + params.Status + `"}`), nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) TranslationTasks(ctx context.Context, params backendrpc.TranslationTaskListParams) (json.RawMessage, error) {
|
||||
b.calls = append(b.calls, "translation.tasks")
|
||||
b.translationTaskListParams = append(b.translationTaskListParams, params)
|
||||
return json.RawMessage(`{"tasks":[{"task_id":"textunit/v-current/Scenario","worker_status":"failed","failure_reason":"provider rejected payload"}]}`), nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) TranslationHandoff(ctx context.Context) (json.RawMessage, error) {
|
||||
b.calls = append(b.calls, "translation.handoff")
|
||||
return json.RawMessage(`{"jobs":[],"provider_runs":[]}`), nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) TranslationWorkerRun(ctx context.Context, params backendrpc.TranslationWorkerRunParams) (*backendrpc.TranslationWorkerRunResult, error) {
|
||||
b.calls = append(b.calls, "translation.worker.run")
|
||||
concurrency := uint64(8)
|
||||
if params.Concurrency != nil {
|
||||
concurrency = *params.Concurrency
|
||||
}
|
||||
return &backendrpc.TranslationWorkerRunResult{
|
||||
TaskID: "task-translation-worker-1",
|
||||
Kind: "translation.worker.run",
|
||||
Worker: backendrpc.TranslationWorkerConfig{
|
||||
Provider: params.Provider,
|
||||
FixturePath: params.FixturePath,
|
||||
Concurrency: concurrency,
|
||||
MaxAttempts: 3,
|
||||
LeaseSeconds: 300,
|
||||
RetryBackoffSeconds: 5,
|
||||
WorkerID: params.WorkerID,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *controlBackend) TranslationProofread(ctx context.Context) (json.RawMessage, error) {
|
||||
b.calls = append(b.calls, "translation.proofread")
|
||||
return json.RawMessage(`{"translation_workflow_status":"manual_proofreading"}`), nil
|
||||
@@ -743,6 +776,81 @@ func TestAdminScheduleEndpointsProxyAuthenticatedRequests(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminTranslationQueryEndpointsProxyAuthenticatedRequests(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
cfg.AuthToken = "translation-token"
|
||||
if err := cfg.Normalize(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
backend := &controlBackend{fakeBackend: &fakeBackend{}}
|
||||
s := NewServer(cfg, backend, nil)
|
||||
|
||||
request := httptest.NewRequest(
|
||||
http.MethodGet,
|
||||
"/admin/translation/tasks?offset=10&limit=25&task_id=textunit%2Fv-current%2FScenario&release_id=v-current&destination=MediaResources%2FGameData%2FScenario.zip&path_pattern=Scenario&archive_entry=ScenarioExcelTable.json&status=queued_offline&worker_status=failed&parse_status=ok&format=json&has_reason=true&has_failure_reason=false",
|
||||
nil,
|
||||
)
|
||||
request.Header.Set("Authorization", "Bearer translation-token")
|
||||
recorder := httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("tasks status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if !json.Valid(recorder.Body.Bytes()) || !strings.Contains(recorder.Body.String(), "failure_reason") {
|
||||
t.Fatalf("tasks body=%s", recorder.Body.String())
|
||||
}
|
||||
if len(backend.translationTaskListParams) != 1 {
|
||||
t.Fatalf("translation task query params=%#v", backend.translationTaskListParams)
|
||||
}
|
||||
params := backend.translationTaskListParams[0]
|
||||
if params.Offset == nil || *params.Offset != 10 ||
|
||||
params.Limit == nil || *params.Limit != 25 ||
|
||||
params.TaskID != "textunit/v-current/Scenario" ||
|
||||
params.ReleaseID != "v-current" ||
|
||||
params.Destination != "MediaResources/GameData/Scenario.zip" ||
|
||||
params.PathPattern != "Scenario" ||
|
||||
params.ArchiveEntry != "ScenarioExcelTable.json" ||
|
||||
params.Status != "queued_offline" ||
|
||||
params.WorkerStatus != "failed" ||
|
||||
params.ParseStatus != "ok" ||
|
||||
params.Format != "json" ||
|
||||
params.HasReason == nil || !*params.HasReason ||
|
||||
params.HasFailureReason == nil || *params.HasFailureReason {
|
||||
t.Fatalf("params=%#v", params)
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodGet, "/admin/translation/handoff", nil)
|
||||
request.Header.Set("Authorization", "Bearer translation-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("handoff status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if !strings.Contains(recorder.Body.String(), "provider_runs") {
|
||||
t.Fatalf("handoff body=%s", recorder.Body.String())
|
||||
}
|
||||
if len(backend.calls) < 2 ||
|
||||
backend.calls[len(backend.calls)-2] != "translation.tasks" ||
|
||||
backend.calls[len(backend.calls)-1] != "translation.handoff" {
|
||||
t.Fatalf("calls=%v", backend.calls)
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodGet, "/admin/translation/tasks?limit=0", nil)
|
||||
request.Header.Set("Authorization", "Bearer translation-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Fatalf("invalid task query status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodGet, "/admin/translation/tasks", nil)
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusUnauthorized {
|
||||
t.Fatalf("unauthenticated tasks status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiscoverCallsStatusBeforeDoctor(t *testing.T) {
|
||||
root := fixtureRoot(t)
|
||||
bytes := uint64(20)
|
||||
@@ -1281,6 +1389,11 @@ func TestOpenAPIAndAdminReservedEndpoints(t *testing.T) {
|
||||
if len(admin.Controls) == 0 || admin.Controls[0] != "/admin/control/reload" {
|
||||
t.Fatalf("admin controls=%v", admin.Controls)
|
||||
}
|
||||
links := strings.Join(admin.Links, "\n")
|
||||
if !strings.Contains(links, "/admin/translation/tasks") ||
|
||||
!strings.Contains(links, "/admin/translation/handoff") {
|
||||
t.Fatalf("admin links=%v", admin.Links)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
|
||||
@@ -1305,6 +1418,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: "translation task update", action: "translation-task-update", body: `{"task_id":"textunit/v-current/Scenario","status":"failed","failure_reason":"provider rejected payload","provider_run_id":"provider-run-1"}`, 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"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
@@ -1336,6 +1450,14 @@ func TestAdminControlForwardsAllowlistedActions(t *testing.T) {
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Fatalf("invalid translation update status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
|
||||
request = httptest.NewRequest(http.MethodPost, "/admin/control/translation-worker-run", strings.NewReader(`{"concurrency":0}`))
|
||||
request.Header.Set("Authorization", "Bearer control-token")
|
||||
recorder = httptest.NewRecorder()
|
||||
s.Handler().ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusBadRequest {
|
||||
t.Fatalf("invalid translation worker status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdminControlRejectsUnauthenticatedDangerousAndUnsupportedActions(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user