77 lines
2.9 KiB
Go
77 lines
2.9 KiB
Go
package handler
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"errors"
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/Tencent/WeKnora/internal/application/service"
|
||
|
|
apperrors "github.com/Tencent/WeKnora/internal/errors"
|
||
|
|
"github.com/Tencent/WeKnora/internal/middleware"
|
||
|
|
"github.com/gin-gonic/gin"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestEmbedManagementErrorMapping(t *testing.T) {
|
||
|
|
gin.SetMode(gin.TestMode)
|
||
|
|
tests := []struct {
|
||
|
|
name string
|
||
|
|
err error
|
||
|
|
status int
|
||
|
|
message string
|
||
|
|
}{
|
||
|
|
{"forbidden", apperrors.NewForbiddenError("owner or admin required"), http.StatusForbidden, "owner or admin required"},
|
||
|
|
{"wrapped forbidden", fmt.Errorf("list: %w", apperrors.NewForbiddenError("owner or admin required")), http.StatusForbidden, "owner or admin required"},
|
||
|
|
{"agent missing", service.ErrAgentNotFound, http.StatusNotFound, "agent not found"},
|
||
|
|
{"wrapped agent missing", fmt.Errorf("list: %w", service.ErrAgentNotFound), http.StatusNotFound, "agent not found"},
|
||
|
|
{"channel missing", service.ErrEmbedChannelNotFound, http.StatusNotFound, "embed channel not found"},
|
||
|
|
{"typed missing", apperrors.NewNotFoundError("agent not found"), http.StatusNotFound, "agent not found"},
|
||
|
|
{"validation", apperrors.NewBadRequestError("agent_id is required"), http.StatusBadRequest, "agent_id is required"},
|
||
|
|
{"unexpected failure", errors.New("database credentials must stay private"), http.StatusInternalServerError, "operation failed"},
|
||
|
|
{"internal app failure", apperrors.NewInternalServerError("private failure details"), http.StatusInternalServerError, "operation failed"},
|
||
|
|
}
|
||
|
|
for _, tt := range tests {
|
||
|
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
|
router := gin.New()
|
||
|
|
router.Use(middleware.ErrorHandler())
|
||
|
|
var observedStatus int
|
||
|
|
var recorded error
|
||
|
|
router.Use(func(c *gin.Context) {
|
||
|
|
c.Next()
|
||
|
|
observedStatus = c.Writer.Status()
|
||
|
|
if c.Errors.Last() != nil {
|
||
|
|
recorded = c.Errors.Last().Err
|
||
|
|
}
|
||
|
|
})
|
||
|
|
router.GET("/agents/agent-1/embed-channels", func(c *gin.Context) {
|
||
|
|
writeEmbedMgmtError(c, tt.err)
|
||
|
|
})
|
||
|
|
writer := httptest.NewRecorder()
|
||
|
|
router.ServeHTTP(writer, httptest.NewRequest(http.MethodGet, "/agents/agent-1/embed-channels", nil))
|
||
|
|
if writer.Code != tt.status || observedStatus != tt.status {
|
||
|
|
t.Fatalf("response status %d, audit status %d, want %d", writer.Code, observedStatus, tt.status)
|
||
|
|
}
|
||
|
|
var appErr *apperrors.AppError
|
||
|
|
if !errors.As(recorded, &appErr) || appErr.Message != tt.message {
|
||
|
|
t.Fatalf("unexpected audit error: %v", recorded)
|
||
|
|
}
|
||
|
|
var body struct {
|
||
|
|
Error struct {
|
||
|
|
Message string `json:"message"`
|
||
|
|
} `json:"error"`
|
||
|
|
}
|
||
|
|
decoder := json.NewDecoder(writer.Body)
|
||
|
|
if err := decoder.Decode(&body); err != nil || body.Error.Message != tt.message {
|
||
|
|
t.Fatalf("invalid response: %v, %#v", err, body)
|
||
|
|
}
|
||
|
|
var extra any
|
||
|
|
if err := decoder.Decode(&extra); err != io.EOF {
|
||
|
|
t.Fatalf("error middleware wrote more than one response: %v", err)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|