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
76 lines
2.9 KiB
Go
76 lines
2.9 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// 인증 응답 문구의 한국어화(백로그 F3b)를 지키는 회귀 방어 테스트다. DB 가 없어도
|
|
// 도는 두 경로로 확인한다: ① requireAuth 미들웨어는 pg 를 거치지 않으므로 실제 HTTP
|
|
// 응답 본문까지 검사하고, ② 나머지 핸들러 문구는 명명 상수라 상수 자체를 검사한다.
|
|
// 한국어 판정은 F3a 가 만든 assertChineseError 헬퍼(한글 포함·중국어 한자 0)를 재사용한다.
|
|
|
|
// TestRequireAuthMessagesLocalized 는 토큰이 없거나 잘못됐을 때 requireAuth 가 돌려주는
|
|
// 401 응답 본문이 한국어이고 중국어 한자가 없음을 실제 HTTP 핸들러로 확인한다. 이
|
|
// 미들웨어는 데이터베이스를 쓰지 않아 DB 없는 환경에서도 끝까지 실행된다.
|
|
func TestRequireAuthMessagesLocalized(t *testing.T) {
|
|
s := &Server{jwtKey: []byte(strings.Repeat("k", 32))}
|
|
next := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
})
|
|
h := s.requireAuth(next)
|
|
|
|
cases := []struct {
|
|
name string
|
|
bearer string
|
|
want string
|
|
}{
|
|
{"토큰 없음", "", authErrUnauthorized},
|
|
{"토큰 무효", "Bearer not-a-valid-token", authErrTokenInvalid},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
r := httptest.NewRequest(http.MethodGet, "/api/tasks", nil)
|
|
if c.bearer != "" {
|
|
r.Header.Set("Authorization", c.bearer)
|
|
}
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, r)
|
|
|
|
if rec.Code != http.StatusUnauthorized {
|
|
t.Fatalf("상태 코드 = %d, 기대 401", rec.Code)
|
|
}
|
|
body := rec.Body.String()
|
|
if !strings.Contains(body, c.want) {
|
|
t.Errorf("응답 본문에 %q 가 없습니다: %s", c.want, body)
|
|
}
|
|
assertChineseError(t, c.name, body)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestAuthErrorConstantsLocalized 는 인증 핸들러가 쓰는 사용자 노출 문구 상수가 모두
|
|
// 한글을 포함하고 중국어 한자를 포함하지 않음을 단언한다. requireAuth 로 직접 칠 수
|
|
// 없는(= pg 를 거치는) 핸들러의 문구까지 DB 없이 회귀를 잡는다.
|
|
func TestAuthErrorConstantsLocalized(t *testing.T) {
|
|
consts := map[string]string{
|
|
"authErrUnauthorized": authErrUnauthorized,
|
|
"authErrTokenInvalid": authErrTokenInvalid,
|
|
"authErrPasswordAlreadySet": authErrPasswordAlreadySet,
|
|
"authErrPasswordEmpty": authErrPasswordEmpty,
|
|
"authErrNewPasswordEmpty": authErrNewPasswordEmpty,
|
|
"authErrPasswordHash": authErrPasswordHash,
|
|
"authErrSaveFailedPrefix": authErrSaveFailedPrefix,
|
|
"authErrTokenGen": authErrTokenGen,
|
|
"authErrBadRequest": authErrBadRequest,
|
|
"authErrPasswordNotInit": authErrPasswordNotInit,
|
|
"authErrCurrentPasswordWrong": authErrCurrentPasswordWrong,
|
|
"authErrBadCredential": authErrBadCredential,
|
|
}
|
|
for name, msg := range consts {
|
|
assertChineseError(t, name, msg)
|
|
}
|
|
}
|