Files
artex/server/task_templates_localized_test.go
T
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

62 lines
2.7 KiB
Go

package server
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/Autumn-27/artex/db"
)
// TestTaskTemplateErrorConstantsLocalized guards the F3b task-template bundle:
// every user-facing string the task-template API returns must be Korean with no
// leftover Chinese Han characters. The format constant is checked after
// formatting so the %s/%d verbs resolve to a concrete message.
func TestTaskTemplateErrorConstantsLocalized(t *testing.T) {
assertKoreanError(t, "request-too-large", errTaskTemplateRequestTooLarge)
assertKoreanError(t, "name-conflict", errTaskTemplateNameConflict)
assertKoreanError(t, "rule-invalid", errTaskTemplateRuleInvalid)
assertKoreanError(t, "no-fields", errTaskTemplateNoFields)
assertKoreanError(t, "field-too-long",
fmt.Sprintf(errTaskTemplateFieldTooLongFmt, "name", db.MaxTaskTemplateNameRunes))
}
// TestTaskTemplateResponsesLocalized drives the real response paths that do not
// touch the database: the body decoder rejects an oversized request, the field
// validator rejects an over-length name, and writeTaskTemplateErr maps the
// name-conflict sentinel to the Korean 409 body.
func TestTaskTemplateResponsesLocalized(t *testing.T) {
// decodeTaskTemplateRequest — MaxBytesReader errors on an oversized body
// before any DB access, so the 413 message is produced on its own.
body := `{"name":"` + strings.Repeat("a", maxTaskTemplateRequestBytes+1) + `"}`
req := httptest.NewRequest(http.MethodPost, "/api/task-templates", strings.NewReader(body))
rec := httptest.NewRecorder()
var decoded taskTemplateRequest
if _, ok := decodeTaskTemplateRequest(rec, req, &decoded); ok {
t.Fatalf("too-large: 디코딩이 통과해서는 안 됩니다 (status=%d)", rec.Code)
}
if rec.Code != http.StatusRequestEntityTooLarge {
t.Fatalf("too-large status=%d, want 413", rec.Code)
}
assertKoreanError(t, "too-large", decodeErrorField(t, rec.Body.Bytes()))
// validateTaskTemplateRequest — a name past the rune limit returns the
// Korean field-too-long error (surfaced via writeErr in the handlers).
longName := strings.Repeat("가", db.MaxTaskTemplateNameRunes+1)
err := validateTaskTemplateRequest(taskTemplateRequest{Name: &longName})
if err == nil {
t.Fatal("name-too-long: 검증이 통과해서는 안 됩니다")
}
assertKoreanError(t, "name-too-long", err.Error())
// writeTaskTemplateErr — the name-conflict sentinel maps to the Korean 409.
rec = httptest.NewRecorder()
writeTaskTemplateErr(rec, db.ErrTaskTemplateNameConflict)
if rec.Code != http.StatusConflict {
t.Fatalf("name-conflict status=%d, want 409", rec.Code)
}
assertKoreanError(t, "name-conflict-response", decodeErrorField(t, rec.Body.Bytes()))
}