Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3812798
Add comprehensive test coverage for multiple Go packages
claude Nov 16, 2025
34f08f5
Add test artifacts to .gitignore
claude Nov 16, 2025
405e762
Add comprehensive tests for modules, apt, notification, and fileserve…
claude Nov 16, 2025
a2a57e0
Add comprehensive tests for utility functions and internal modules
claude Nov 16, 2025
9ff2ec7
Expand and create tests for auth and share modules
claude Nov 16, 2025
98622db
Add comprehensive tests for cluster and www modules
claude Nov 16, 2025
edc1f38
Add comprehensive tests for updates and network modules
claude Nov 16, 2025
5788907
Expand tests for utils and add scheduler tests
claude Nov 16, 2025
1304304
Add comprehensive tests for filesystem static utilities
claude Nov 16, 2025
e21bcbd
Add tests for share and IoT utility modules
claude Nov 16, 2025
f29d593
Add tests for permission groups and filesystem configuration
claude Nov 16, 2025
5c6e3cf
Add comprehensive tests for filesystem abstraction utilities
claude Nov 16, 2025
6441713
Add tests for auth internal utility functions
claude Nov 16, 2025
1de4228
Add comprehensive tests for AGI static utility functions
claude Nov 16, 2025
3811e56
Add comprehensive tests for FFmpeg utility media type detection
claude Nov 16, 2025
35a1f03
Fix failing tests - path expectations and unused imports
claude Nov 16, 2025
ee20770
Fix test build errors and panic
claude Nov 16, 2025
03fd8db
Fix AGI and utils test failures
claude Nov 16, 2025
54b0bc8
Fix prouter lanCheck test edge case expectations
claude Nov 16, 2025
41d7415
Fix wakeonlan test error handling
claude Nov 16, 2025
6e97774
Fix modules test to use proper UserHandler initialization
claude Nov 16, 2025
3adc887
Fix scheduler test to use correct Job struct fields
claude Nov 16, 2025
3ccfcdf
Fix all failing tests
claude Nov 16, 2025
c22cc8a
Add test coverage for untested modules
claude Nov 16, 2025
b0a0bc9
Fix test failures in hidden and csrf modules
claude Nov 16, 2025
719422b
Add test coverage for 20+ previously untested modules
claude Nov 16, 2025
fb056a5
Add comprehensive test coverage for ALL remaining untested modules
claude Nov 16, 2025
6c2a839
Fix test signatures for emptyfs, fuzzy, ldapreader, fssort, ftpfs, df…
claude Nov 16, 2025
4a92902
Fix all remaining test compilation errors (27 files)
claude Nov 16, 2025
3954639
Fix final 15 test compilation errors
claude Nov 17, 2025
67cafe0
Fix nil pointer panics in 5 test files
claude Nov 17, 2025
1e885e7
Add comprehensive test coverage for RAID module
claude Nov 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ src/system/bridge.json
src/system/cron.json
src/system/smtp_conf.json
/src/web/FFmpeg Factory

# Test artifacts
src/coverage.out
src/test_output.txt
*.test
coverage.out
test_output.txt
106 changes: 106 additions & 0 deletions src/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package main

import (
"testing"
)

func TestGetRootEscapeFromCurrentPath(t *testing.T) {
// Test case 1: Simple single level path
result := getRootEscapeFromCurrentPath("/test")
expected := "../"
if result != expected {
t.Errorf("Test case 1 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 2: Two level path
result = getRootEscapeFromCurrentPath("/test/path")
expected = "../../"
if result != expected {
t.Errorf("Test case 2 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 3: Three level path
result = getRootEscapeFromCurrentPath("/test/path/deep")
expected = "../../../"
if result != expected {
t.Errorf("Test case 3 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 4: Root path
result = getRootEscapeFromCurrentPath("/")
expected = ""
if result != expected {
t.Errorf("Test case 4 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 5: No slash (empty result)
result = getRootEscapeFromCurrentPath("nopath")
expected = ""
if result != expected {
t.Errorf("Test case 5 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 6: Path with trailing slash
result = getRootEscapeFromCurrentPath("/test/path/")
expected = "../../"
if result != expected {
t.Errorf("Test case 6 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 7: Deep nested path
result = getRootEscapeFromCurrentPath("/level1/level2/level3/level4/level5")
expected = "../../../../../"
if result != expected {
t.Errorf("Test case 7 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 8: Path with file
result = getRootEscapeFromCurrentPath("/folder/file.html")
expected = "../../"
if result != expected {
t.Errorf("Test case 8 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 9: Path with query parameters
result = getRootEscapeFromCurrentPath("/api/endpoint?param=value")
expected = "../../"
if result != expected {
t.Errorf("Test case 9 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 10: Empty string
result = getRootEscapeFromCurrentPath("")
expected = ""
if result != expected {
t.Errorf("Test case 10 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 11: Path with special characters
result = getRootEscapeFromCurrentPath("/test-path/with_special.chars")
expected = "../../"
if result != expected {
t.Errorf("Test case 11 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 12: Very deep path (10 levels)
result = getRootEscapeFromCurrentPath("/a/b/c/d/e/f/g/h/i/j")
expected = "../../../../../../../../../../"
if result != expected {
t.Errorf("Test case 12 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 13: Path with double slashes
result = getRootEscapeFromCurrentPath("/test//double")
// Double slashes create empty segments in split, but the function just counts splits
expected = "../../../"
if result != expected {
t.Errorf("Test case 13 failed. Expected '%s', got '%s'", expected, result)
}

// Test case 14: Path starting without slash
result = getRootEscapeFromCurrentPath("relative/path")
expected = "../"
if result != expected {
t.Errorf("Test case 14 failed. Expected '%s', got '%s'", expected, result)
}
}
220 changes: 220 additions & 0 deletions src/mod/agi/error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
package agi

import (
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)

func TestRenderErrorTemplate(t *testing.T) {
// Setup: Create a temporary error.html template file
tempDir, err := os.MkdirTemp("", "agi_test")
if err != nil {
t.Fatalf("Failed to create temp directory: %v", err)
}
defer os.RemoveAll(tempDir)

// Create system/agi directory structure
agiDir := filepath.Join(tempDir, "system", "agi")
err = os.MkdirAll(agiDir, 0755)
if err != nil {
t.Fatalf("Failed to create agi directory: %v", err)
}

// Create a test error.html template
templateContent := `<!DOCTYPE html>
<html>
<head><title>Error</title></head>
<body>
<h1>AGI Error</h1>
<p>Error: {{.error_msg}}</p>
<p>Script: {{.script_filepath}}</p>
<p>Timestamp: {{.timestamp}}</p>
<p>Version: {{.major_version}}.{{.minor_version}}</p>
<p>AGI Version: {{.agi_version}}</p>
</body>
</html>`

errorTemplatePath := filepath.Join(agiDir, "error.html")
err = os.WriteFile(errorTemplatePath, []byte(templateContent), 0644)
if err != nil {
t.Fatalf("Failed to write error template: %v", err)
}

// Change to temp directory for testing
originalWd, err := os.Getwd()
if err != nil {
t.Fatalf("Failed to get current directory: %v", err)
}
defer os.Chdir(originalWd)

err = os.Chdir(tempDir)
if err != nil {
t.Fatalf("Failed to change directory: %v", err)
}

// Test case 1: Successful error template rendering
gateway := &Gateway{
Option: &AgiSysInfo{
BuildVersion: "2.0",
InternalVersion: "24",
},
}

w := httptest.NewRecorder()
gateway.RenderErrorTemplate(w, "Test error message", "/test/script.agi")

body := w.Body.String()
if !strings.Contains(body, "Test error message") {
t.Error("Test case 1 failed. Error message not found in rendered template")
}
if !strings.Contains(body, "/test/script.agi") {
t.Error("Test case 1 failed. Script path not found in rendered template")
}
if !strings.Contains(body, "2.0") {
t.Error("Test case 1 failed. Build version not found in rendered template")
}
if !strings.Contains(body, "24") {
t.Error("Test case 1 failed. Internal version not found in rendered template")
}

// Test case 2: Error message with special characters
w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, "Error with <special> & \"characters\"", "/path/to/script.js")

body = w.Body.String()
// Template should escape HTML special characters
if !strings.Contains(body, "Error with") {
t.Error("Test case 2 failed. Error message with special chars not rendered")
}

// Test case 3: Empty error message
w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, "", "/empty/error/script.agi")

if w.Body.Len() == 0 {
t.Error("Test case 3 failed. Should render template even with empty error message")
}

// Test case 4: Long error message
longError := strings.Repeat("This is a very long error message. ", 100)
w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, longError, "/script.agi")

body = w.Body.String()
if !strings.Contains(body, "very long error message") {
t.Error("Test case 4 failed. Long error message not rendered")
}

// Test case 5: Unicode characters in error message
w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, "错误信息 🚨 エラー", "/unicode/script.agi")

body = w.Body.String()
if !strings.Contains(body, "错误信息") && !strings.Contains(body, "エラー") {
t.Error("Test case 5 failed. Unicode characters not rendered correctly")
}

// Test case 6: Script path with special characters
w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, "Error occurred", "/path/with spaces/and-dashes/script.agi")

body = w.Body.String()
if !strings.Contains(body, "/path/with spaces/and-dashes/script.agi") {
t.Error("Test case 6 failed. Script path with spaces not rendered")
}

// Test case 7: Different version numbers
gateway2 := &Gateway{
Option: &AgiSysInfo{
BuildVersion: "3.1.4",
InternalVersion: "159",
},
}

w = httptest.NewRecorder()
gateway2.RenderErrorTemplate(w, "Version test", "/script.agi")

body = w.Body.String()
if !strings.Contains(body, "3.1.4") {
t.Error("Test case 7 failed. Different build version not rendered")
}
if !strings.Contains(body, "159") {
t.Error("Test case 7 failed. Different internal version not rendered")
}

// Test case 8: Multiple line error message
multilineError := "Line 1 error\nLine 2 error\nLine 3 error"
w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, multilineError, "/multiline/script.agi")

body = w.Body.String()
if !strings.Contains(body, "Line 1 error") {
t.Error("Test case 8 failed. Multiline error message not rendered")
}

// Restore working directory
os.Chdir(originalWd)

// Test case 9: Template file does not exist
// Create a new temp directory without error.html
tempDir2, err := os.MkdirTemp("", "agi_test_notemplate")
if err != nil {
t.Fatalf("Failed to create second temp directory: %v", err)
}
defer os.RemoveAll(tempDir2)

err = os.Chdir(tempDir2)
if err != nil {
t.Fatalf("Failed to change to second temp directory: %v", err)
}

w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, "Error", "/script.agi")

// Should return Internal Server Error
body = w.Body.String()
if !strings.Contains(body, "Internal Server Error") {
t.Error("Test case 9 failed. Should return Internal Server Error when template missing")
}

os.Chdir(originalWd)

// Test case 10: Invalid template syntax
tempDir3, err := os.MkdirTemp("", "agi_test_invalid")
if err != nil {
t.Fatalf("Failed to create third temp directory: %v", err)
}
defer os.RemoveAll(tempDir3)

agiDir3 := filepath.Join(tempDir3, "system", "agi")
err = os.MkdirAll(agiDir3, 0755)
if err != nil {
t.Fatalf("Failed to create third agi directory: %v", err)
}

invalidTemplate := `{{.error_msg} {{end}}`
errorTemplatePath3 := filepath.Join(agiDir3, "error.html")
err = os.WriteFile(errorTemplatePath3, []byte(invalidTemplate), 0644)
if err != nil {
t.Fatalf("Failed to write invalid template: %v", err)
}

err = os.Chdir(tempDir3)
if err != nil {
t.Fatalf("Failed to change to third temp directory: %v", err)
}

w = httptest.NewRecorder()
gateway.RenderErrorTemplate(w, "Error", "/script.agi")

// Should return Internal Server Error for invalid template
body = w.Body.String()
if !strings.Contains(body, "Internal Server Error") {
t.Error("Test case 10 failed. Should return Internal Server Error for invalid template")
}

os.Chdir(originalWd)
}
Loading
Loading