366 lines
9.7 KiB
Go
366 lines
9.7 KiB
Go
package repo
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
gitea_errors "gitea.com/gitea/gitea-mcp/pkg/errors"
|
|
)
|
|
|
|
// mockClientError is a mock error that simulates SDK errors
|
|
type mockClientError struct {
|
|
message string
|
|
}
|
|
|
|
func (e *mockClientError) Error() string {
|
|
return e.message
|
|
}
|
|
|
|
func TestErrorTranslation_GetFile(t *testing.T) {
|
|
// Test that GetContentsOrList errors are translated properly
|
|
err := errors.New("GetContentsOrList: 404 Not Found")
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "GetFile",
|
|
"owner": "karti-ai",
|
|
"repo": "docs",
|
|
"path": "README.md",
|
|
"ref": "main",
|
|
})
|
|
|
|
// Should return an EnhancedError
|
|
var enhanced *gitea_errors.EnhancedError
|
|
if !errors.As(translated, &enhanced) {
|
|
t.Fatal("expected translated error to be EnhancedError")
|
|
}
|
|
|
|
// Check operation
|
|
if enhanced.Operation != "GetFile" {
|
|
t.Errorf("expected operation GetFile, got %s", enhanced.Operation)
|
|
}
|
|
|
|
// Check context
|
|
if enhanced.Context["owner"] != "karti-ai" {
|
|
t.Errorf("expected owner karti-ai, got %s", enhanced.Context["owner"])
|
|
}
|
|
if enhanced.Context["path"] != "README.md" {
|
|
t.Errorf("expected path README.md, got %s", enhanced.Context["path"])
|
|
}
|
|
|
|
// Should be a file-related error
|
|
if enhanced.Category != gitea_errors.CategoryFile {
|
|
t.Errorf("expected CategoryFile, got %s", enhanced.Category)
|
|
}
|
|
|
|
// Should be identified as NotFound
|
|
if !gitea_errors.IsNotFound(translated) {
|
|
t.Error("expected error to be identified as NotFound")
|
|
}
|
|
|
|
t.Logf("Translated error message: %s", enhanced.Error())
|
|
}
|
|
|
|
func TestErrorTranslation_GetDir(t *testing.T) {
|
|
// Test that ListContents errors are translated properly
|
|
err := errors.New("ListContents: 404 Not Found")
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "GetDir",
|
|
"owner": "karti-ai",
|
|
"repo": "public_website",
|
|
"path": ".gitea/workflows",
|
|
"ref": "main",
|
|
})
|
|
|
|
var enhanced *gitea_errors.EnhancedError
|
|
if !errors.As(translated, &enhanced) {
|
|
t.Fatal("expected translated error to be EnhancedError")
|
|
}
|
|
|
|
if enhanced.Operation != "GetDir" {
|
|
t.Errorf("expected operation GetDir, got %s", enhanced.Operation)
|
|
}
|
|
|
|
if enhanced.Category != gitea_errors.CategoryFile {
|
|
t.Errorf("expected CategoryFile, got %s", enhanced.Category)
|
|
}
|
|
|
|
t.Logf("Translated error message: %s", enhanced.Error())
|
|
}
|
|
|
|
func TestErrorTranslation_CreateFile(t *testing.T) {
|
|
// Test that CreateFile errors are translated properly
|
|
err := errors.New("CreateFile: 422 Unprocessable Entity")
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "CreateFile",
|
|
"owner": "karti-ai",
|
|
"repo": "docs",
|
|
"path": "newfile.md",
|
|
"branch": "main",
|
|
})
|
|
|
|
var enhanced *gitea_errors.EnhancedError
|
|
if !errors.As(translated, &enhanced) {
|
|
t.Fatal("expected translated error to be EnhancedError")
|
|
}
|
|
|
|
if enhanced.Operation != "CreateFile" {
|
|
t.Errorf("expected operation CreateFile, got %s", enhanced.Operation)
|
|
}
|
|
|
|
if enhanced.Context["path"] != "newfile.md" {
|
|
t.Errorf("expected path newfile.md, got %s", enhanced.Context["path"])
|
|
}
|
|
|
|
t.Logf("Translated error message: %s", enhanced.Error())
|
|
}
|
|
|
|
func TestErrorTranslation_UpdateFile(t *testing.T) {
|
|
// Test that UpdateFile errors are translated properly
|
|
err := errors.New("UpdateFile: 409 Conflict")
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "UpdateFile",
|
|
"owner": "karti-ai",
|
|
"repo": "docs",
|
|
"path": "README.md",
|
|
"branch": "main",
|
|
})
|
|
|
|
var enhanced *gitea_errors.EnhancedError
|
|
if !errors.As(translated, &enhanced) {
|
|
t.Fatal("expected translated error to be EnhancedError")
|
|
}
|
|
|
|
if enhanced.Operation != "UpdateFile" {
|
|
t.Errorf("expected operation UpdateFile, got %s", enhanced.Operation)
|
|
}
|
|
|
|
t.Logf("Translated error message: %s", enhanced.Error())
|
|
}
|
|
|
|
func TestErrorTranslation_DeleteFile(t *testing.T) {
|
|
// Test that DeleteFile errors are translated properly
|
|
err := errors.New("DeleteFile: 404 Not Found")
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "DeleteFile",
|
|
"owner": "karti-ai",
|
|
"repo": "docs",
|
|
"path": "oldfile.md",
|
|
"branch": "main",
|
|
})
|
|
|
|
var enhanced *gitea_errors.EnhancedError
|
|
if !errors.As(translated, &enhanced) {
|
|
t.Fatal("expected translated error to be EnhancedError")
|
|
}
|
|
|
|
if enhanced.Operation != "DeleteFile" {
|
|
t.Errorf("expected operation DeleteFile, got %s", enhanced.Operation)
|
|
}
|
|
|
|
t.Logf("Translated error message: %s", enhanced.Error())
|
|
t.Logf("Error category: %s", enhanced.Category)
|
|
}
|
|
|
|
func TestErrorTranslation_Unwrap(t *testing.T) {
|
|
original := errors.New("GetContentsOrList: 404 Not Found")
|
|
translated := gitea_errors.TranslateError(original, map[string]string{
|
|
"operation": "GetFile",
|
|
"owner": "karti-ai",
|
|
"repo": "docs",
|
|
"path": "README.md",
|
|
})
|
|
|
|
// Should be able to unwrap to get original error
|
|
var enhanced *gitea_errors.EnhancedError
|
|
if errors.As(translated, &enhanced) {
|
|
unwrapped := enhanced.Unwrap()
|
|
if unwrapped == nil {
|
|
t.Error("expected to be able to unwrap error")
|
|
}
|
|
if unwrapped.Error() != original.Error() {
|
|
t.Errorf("expected unwrapped error to match original: got %s, want %s", unwrapped.Error(), original.Error())
|
|
}
|
|
} else {
|
|
t.Error("expected translated error to be EnhancedError")
|
|
}
|
|
}
|
|
|
|
func TestErrorTranslation_AuthErrors(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
errMsg string
|
|
isAuth bool
|
|
}{
|
|
{
|
|
name: "401 Unauthorized",
|
|
errMsg: "GetContentsOrList: 401 Unauthorized",
|
|
isAuth: true,
|
|
},
|
|
{
|
|
name: "403 Forbidden",
|
|
errMsg: "GetContentsOrList: 403 Forbidden",
|
|
isAuth: true,
|
|
},
|
|
{
|
|
name: "404 Not Found (not auth)",
|
|
errMsg: "GetContentsOrList: 404 Not Found",
|
|
isAuth: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := errors.New(tt.errMsg)
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "GetFile",
|
|
})
|
|
|
|
isAuth := gitea_errors.IsAuthError(translated)
|
|
if isAuth != tt.isAuth {
|
|
t.Errorf("IsAuthError() = %v, want %v", isAuth, tt.isAuth)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestErrorTranslation_PreservesExistingEnhancedError(t *testing.T) {
|
|
// If we translate an already-enhanced error, it should add context, not replace
|
|
original := errors.New("GetContentsOrList: 404 Not Found")
|
|
enhanced1 := gitea_errors.TranslateError(original, map[string]string{
|
|
"operation": "GetFile",
|
|
"owner": "karti-ai",
|
|
})
|
|
|
|
// Translate again with more context
|
|
enhanced2 := gitea_errors.TranslateError(enhanced1, map[string]string{
|
|
"repo": "docs",
|
|
"path": "README.md",
|
|
})
|
|
|
|
var e *gitea_errors.EnhancedError
|
|
if errors.As(enhanced2, &e) {
|
|
// Should have both sets of context
|
|
if e.Context["operation"] != "GetFile" {
|
|
t.Errorf("expected operation context to be preserved, got %s", e.Context["operation"])
|
|
}
|
|
if e.Context["owner"] != "karti-ai" {
|
|
t.Errorf("expected owner context to be preserved, got %s", e.Context["owner"])
|
|
}
|
|
if e.Context["repo"] != "docs" {
|
|
t.Errorf("expected repo context to be added, got %s", e.Context["repo"])
|
|
}
|
|
if e.Context["path"] != "README.md" {
|
|
t.Errorf("expected path context to be added, got %s", e.Context["path"])
|
|
}
|
|
} else {
|
|
t.Error("expected error to be EnhancedError")
|
|
}
|
|
}
|
|
|
|
func TestErrorTranslation_NetworkErrors(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
errMsg string
|
|
isNetwork bool
|
|
isTimeout bool
|
|
}{
|
|
{
|
|
name: "Connection refused",
|
|
errMsg: "GetContentsOrList: connection refused",
|
|
isNetwork: true,
|
|
isTimeout: false,
|
|
},
|
|
{
|
|
name: "Timeout",
|
|
errMsg: "GetContentsOrList: timeout",
|
|
isNetwork: true,
|
|
isTimeout: true,
|
|
},
|
|
{
|
|
name: "No such host",
|
|
errMsg: "GetContentsOrList: no such host",
|
|
isNetwork: true,
|
|
isTimeout: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := errors.New(tt.errMsg)
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "GetFile",
|
|
})
|
|
|
|
isNetwork := gitea_errors.IsNetworkError(translated)
|
|
isTimeout := gitea_errors.IsTimeout(translated)
|
|
|
|
t.Logf("Error: %s, IsNetwork: %v, IsTimeout: %v", tt.errMsg, isNetwork, isTimeout)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestErrorTranslation_ServerErrors(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
errMsg string
|
|
isServer bool
|
|
}{
|
|
{
|
|
name: "500 Internal Server Error",
|
|
errMsg: "GetContentsOrList: 500 Internal Server Error",
|
|
isServer: true,
|
|
},
|
|
{
|
|
name: "502 Bad Gateway",
|
|
errMsg: "GetContentsOrList: 502 Bad Gateway",
|
|
isServer: true,
|
|
},
|
|
{
|
|
name: "503 Service Unavailable",
|
|
errMsg: "GetContentsOrList: 503 Service Unavailable",
|
|
isServer: true,
|
|
},
|
|
{
|
|
name: "404 Not Found (not server)",
|
|
errMsg: "GetContentsOrList: 404 Not Found",
|
|
isServer: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := errors.New(tt.errMsg)
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "GetFile",
|
|
})
|
|
|
|
isServer := gitea_errors.IsServerError(translated)
|
|
t.Logf("Error: %s, IsServer: %v", tt.errMsg, isServer)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestErrorTranslation_Format(t *testing.T) {
|
|
err := errors.New("GetContentsOrList: 404 Not Found")
|
|
translated := gitea_errors.TranslateError(err, map[string]string{
|
|
"operation": "GetFile",
|
|
"owner": "karti-ai",
|
|
"repo": "docs",
|
|
"path": "README.md",
|
|
"ref": "main",
|
|
})
|
|
|
|
var enhanced *gitea_errors.EnhancedError
|
|
if errors.As(translated, &enhanced) {
|
|
formatted := enhanced.Format()
|
|
|
|
// Format should include operation
|
|
if formatted == "" {
|
|
t.Error("expected non-empty formatted error")
|
|
}
|
|
|
|
t.Logf("Formatted error: %s", formatted)
|
|
} else {
|
|
t.Error("expected translated error to be EnhancedError")
|
|
}
|
|
}
|