Files
artex/server/assets_localized_test.go
dela 0335d572de
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
detections / detections (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
First Commit
2026-10-09 08:38:16 +08:00

82 lines
3.5 KiB
Go

package server
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
)
// TestAssetErrorConstantsLocalized pins that every user-facing writeErr literal
// in task_assets.go and assets.go is Korean (Hangul present, no Chinese Han). If
// anyone reverts one to Chinese, this fails.
func TestAssetErrorConstantsLocalized(t *testing.T) {
cases := map[string]string{
"errTaskAssetRequestTooLarge": errTaskAssetRequestTooLarge,
"errTaskAssetScopeConflict": errTaskAssetScopeConflict,
"errCompanyRequestTooLarge": errCompanyRequestTooLarge,
"errCompanyNameConflict": errCompanyNameConflict,
}
for label, msg := range cases {
assertKoreanError(t, label, msg)
}
}
// TestTaskAssetProvenanceLocalized pins the asset-provenance summary labels that
// get stored in task_asset_links.source_summary and rendered verbatim on the task
// detail sessions/assets tabs. Reverting either to Chinese fails here. The manual
// variant lives in the db package (db.manualTaskScopeSummary) and is pinned there.
func TestTaskAssetProvenanceLocalized(t *testing.T) {
cases := map[string]string{
"taskAssetSourceAPISummary": taskAssetSourceAPISummary,
"taskAssetSourceTaskSummary": taskAssetSourceTaskSummary,
}
for label, msg := range cases {
assertKoreanError(t, label, msg)
}
}
// TestAssetResponsesLocalized drives the request validators that return before
// any database access and confirms the Korean message actually lands in the HTTP
// body. The scope/asset_ids conflict guard returns before s.m.Assets() is read,
// MaxBytesReader trips mid-decode, and decodeCompanyMutationRequest works on the
// body alone, so a Manager holding only the task map reaches every path.
func TestAssetResponsesLocalized(t *testing.T) {
s := &Server{m: &Manager{tasks: map[string]*Task{"1": {ID: "1"}}}}
// attachTaskAssets — scope and asset_ids may not be submitted together.
conflictReq := httptest.NewRequest(http.MethodPost, "/api/tasks/1/assets",
strings.NewReader(`{"scope":["example.com"],"asset_ids":[1]}`))
conflictReq.SetPathValue("id", "1")
rec := httptest.NewRecorder()
s.attachTaskAssets(rec, conflictReq)
if rec.Code != http.StatusBadRequest {
t.Fatalf("scope+asset_ids status=%d, want 400 (body %s)", rec.Code, rec.Body.String())
}
assertKoreanError(t, "scope-conflict", decodeErrorField(t, rec.Body.Bytes()))
// attachTaskAssets — an oversized body trips MaxBytesReader during decode.
bigReq := httptest.NewRequest(http.MethodPost, "/api/tasks/1/assets",
strings.NewReader(`{"source_summary":"`+strings.Repeat("a", maxTaskAssetRequestBytes+1)+`"}`))
bigReq.SetPathValue("id", "1")
rec = httptest.NewRecorder()
s.attachTaskAssets(rec, bigReq)
if rec.Code != http.StatusRequestEntityTooLarge {
t.Fatalf("task asset too-large status=%d, want 413 (body %s)", rec.Code, rec.Body.String())
}
assertKoreanError(t, "task-asset-too-large", decodeErrorField(t, rec.Body.Bytes()))
// decodeCompanyMutationRequest — a body-only helper, no DB or Server state.
compReq := httptest.NewRequest(http.MethodPost, "/api/companies",
strings.NewReader(`{"name":"`+strings.Repeat("a", maxCompanyMutationBodyBytes+1)+`"}`))
rec = httptest.NewRecorder()
var dst map[string]any
if ok := decodeCompanyMutationRequest(rec, compReq, &dst); ok {
t.Fatalf("company too-large body should not decode (status=%d)", rec.Code)
}
if rec.Code != http.StatusRequestEntityTooLarge {
t.Fatalf("company too-large status=%d, want 413 (body %s)", rec.Code, rec.Body.String())
}
assertKoreanError(t, "company-too-large", decodeErrorField(t, rec.Body.Bytes()))
}