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
docs / links (push) Waiting to run
web / web (push) Waiting to run
73 lines
3.1 KiB
Go
73 lines
3.1 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/Autumn-27/artex/db"
|
|
)
|
|
|
|
// TestNotifierDeliveryReasonsLocalized guards F17: every delivery failure/defer
|
|
// reason that notifier.go writes into notification_deliveries.last_error — which
|
|
// notify_api.go echoes back to the "전달 기록" table in delivery-list.tsx — must be
|
|
// Korean (Hangul present, no Chinese Han). Diagnostic log.Printf lines stay in the
|
|
// original language (Z2) and are intentionally not covered here.
|
|
func TestNotifierDeliveryReasonsLocalized(t *testing.T) {
|
|
// Format every constant with ASCII arguments so any leftover Han ideograph is
|
|
// the constant's own, not injected by the test data.
|
|
cases := []struct {
|
|
label string
|
|
msg string
|
|
}{
|
|
{"channelKindUnregistered", fmt.Sprintf(errDeliveryChannelKindUnregistered, "webhook")},
|
|
{"snapshotUnrenderable", errDeliverySnapshotUnrenderable},
|
|
{"channelLengthCapped", fmt.Sprintf(errDeliveryChannelLengthCapped, 3)},
|
|
{"noDeliveredCount", fmt.Sprintf(errDeliveryNoDeliveredCount, 0)},
|
|
{"retryExhausted", fmt.Sprintf(errDeliveryRetryExhausted, db.MaxNotifyAttempts, errors.New("boom"))},
|
|
{"snapshotEmpty", fmt.Sprintf(errDeliverySnapshotEmpty, 7)},
|
|
{"snapshotParse", fmt.Errorf(errDeliverySnapshotParse, 9, errors.New("unexpected end of JSON input")).Error()},
|
|
{"batchAllUnparseable", fmt.Sprintf(errDeliveryBatchAllUnparseable, 2)},
|
|
}
|
|
for _, c := range cases {
|
|
assertChineseError(t, c.label, c.msg)
|
|
}
|
|
}
|
|
|
|
// TestNotifierParseSnapshotErrorsLocalized exercises the real parseSnapshot paths
|
|
// that surface as last_error through renderSingle → FailDeliveries. parseSnapshot is
|
|
// a package-level pure function, so no DB or Server is needed.
|
|
func TestNotifierParseSnapshotErrorsLocalized(t *testing.T) {
|
|
// Empty snapshot.
|
|
if _, err := parseSnapshot(&db.NotificationDelivery{ID: 7}); err == nil {
|
|
t.Fatal("빈 스냅샷이 오류 없이 통과해서는 안 됩니다")
|
|
} else {
|
|
assertChineseError(t, "parseSnapshot.empty", err.Error())
|
|
if !strings.Contains(err.Error(), "7") {
|
|
t.Fatalf("parseSnapshot.empty: 전달 항목 ID 7 이 메시지에 없습니다: %q", err.Error())
|
|
}
|
|
}
|
|
// Malformed JSON snapshot.
|
|
if _, err := parseSnapshot(&db.NotificationDelivery{ID: 9, Snapshot: []byte("{bad")}); err == nil {
|
|
t.Fatal("깨진 JSON 스냅샷이 오류 없이 통과해서는 안 됩니다")
|
|
} else {
|
|
assertChineseError(t, "parseSnapshot.malformed", err.Error())
|
|
}
|
|
}
|
|
|
|
// TestNotifierRenderBatchAllUnparseableLocalized drives the real renderBatch "every
|
|
// snapshot is unparseable" branch. With all snapshots empty, every delivery is
|
|
// skipped before itemFor (and thus before n.pg), so a zero-value Notifier reaches
|
|
// the errDeliveryBatchAllUnparseable return without touching the database.
|
|
func TestNotifierRenderBatchAllUnparseableLocalized(t *testing.T) {
|
|
n := &Notifier{}
|
|
deliveries := []*db.NotificationDelivery{{ID: 1}, {ID: 2}}
|
|
if _, _, err := n.renderBatch(context.Background(), deliveries, "", 30); err == nil {
|
|
t.Fatal("모든 스냅샷이 해석 불가일 때 오류가 나와야 합니다")
|
|
} else {
|
|
assertChineseError(t, "renderBatch.allUnparseable", err.Error())
|
|
}
|
|
}
|