Skip to main content
Glama
script_test.go9.56 kB
package repl import ( "os" "path/filepath" "strings" "testing" ) func TestValidateScriptName(t *testing.T) { tests := []struct { name string input string wantErr bool errMsg string }{ {"valid alphanumeric", "validScript123", false, ""}, {"valid with underscore", "my_script", false, ""}, {"valid with hyphen", "my-script", false, ""}, {"empty name", "", true, "must be between"}, {"too long", strings.Repeat("a", 65), true, "must be between"}, {"with spaces", "my script", true, "only alphanumeric"}, {"with dots", "my.script", true, "only alphanumeric"}, {"with path traversal", "../evil", true, "invalid path characters"}, {"with forward slash", "my/script", true, "invalid path characters"}, {"with backslash", "my\\script", true, "invalid path characters"}, {"with double dots", "my..script", true, "invalid path characters"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := validateScriptName(tt.input) if (err != nil) != tt.wantErr { t.Errorf("validateScriptName(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr) } if err != nil && tt.errMsg != "" && !strings.Contains(err.Error(), tt.errMsg) { t.Errorf("validateScriptName(%q) error = %v, want error containing %q", tt.input, err, tt.errMsg) } }) } } func TestSecureFilePath(t *testing.T) { // Create a temporary directory for testing tempDir := t.TempDir() tests := []struct { name string scriptsDir string filename string wantErr bool errMsg string }{ {"valid filename", tempDir, "script.ts", false, ""}, {"path traversal attempt", tempDir, "../../../etc/passwd", true, "path traversal"}, {"absolute path", tempDir, "/etc/passwd", true, "path traversal"}, {"with subdirectory", tempDir, "subdir/script.ts", true, "path traversal"}, {"double dots in middle", tempDir, "sc..ript.ts", false, ""}, // This is actually valid as a filename {"backslash", tempDir, "script\\bad.ts", true, "path traversal"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := secureFilePath(tt.scriptsDir, tt.filename) if (err != nil) != tt.wantErr { t.Errorf("secureFilePath(%q, %q) error = %v, wantErr %v", tt.scriptsDir, tt.filename, err, tt.wantErr) } if err != nil && tt.errMsg != "" && !strings.Contains(err.Error(), tt.errMsg) { t.Errorf("secureFilePath(%q, %q) error = %v, want error containing %q", tt.scriptsDir, tt.filename, err, tt.errMsg) } }) } } func TestParseScriptFile(t *testing.T) { // Create a temporary directory tempDir := t.TempDir() // Test cases tests := []struct { name string content string wantErr bool check func(t *testing.T, script *Script) }{ { name: "valid script", content: `/*** { "description": "Test script", "category": "test", "tags": ["test", "example"], "author": "Test Author", "version": "1.0.0" } ***/ function test() { return "hello"; }`, wantErr: false, check: func(t *testing.T, script *Script) { if script.Metadata.Description != "Test script" { t.Errorf("got description %q, want %q", script.Metadata.Description, "Test script") } if script.Metadata.Category != "test" { t.Errorf("got category %q, want %q", script.Metadata.Category, "test") } if len(script.Metadata.Tags) != 2 { t.Errorf("got %d tags, want 2", len(script.Metadata.Tags)) } }, }, { name: "missing front matter", content: `function test() { return "hello"; }`, wantErr: true, }, { name: "invalid JSON in front matter", content: `/*** { invalid json } ***/ function test() { return "hello"; }`, wantErr: true, }, { name: "missing description", content: `/*** { "category": "test" } ***/ function test() { return "hello"; }`, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create test file filename := "test_script.ts" filePath := filepath.Join(tempDir, filename) if err := os.WriteFile(filePath, []byte(tt.content), 0644); err != nil { t.Fatalf("failed to create test file: %v", err) } // Parse the file script, err := parseScriptFile(filePath) if (err != nil) != tt.wantErr { t.Errorf("parseScriptFile() error = %v, wantErr %v", err, tt.wantErr) } if !tt.wantErr && tt.check != nil { tt.check(t, script) } }) } } func TestSanitizeJavaScript(t *testing.T) { tests := []struct { name string input string want string }{ {"no changes needed", "function test() { return 42; }", "function test() { return 42; }"}, {"remove script tags", "code<script>evil</script>more", "codemore"}, {"escape backticks", "const str = `hello`;", "const str = \\`hello\\`;"}, {"remove HTML comments", "code<!--comment-->more", "codemore"}, {"multiple sanitizations", "<script>`test`</script><!--bad-->", ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := sanitizeJavaScript(tt.input) if got != tt.want { t.Errorf("sanitizeJavaScript() = %q, want %q", got, tt.want) } }) } } func TestEscapeForJavaScript(t *testing.T) { tests := []struct { name string input string want string }{ {"no escaping needed", "simple text", "simple text"}, {"escape quotes", `"quoted"`, `\"quoted\"`}, {"escape single quotes", `'quoted'`, `\'quoted\'`}, {"escape backslashes", `path\to\file`, `path\\to\\file`}, {"escape newlines", "line1\nline2", `line1\nline2`}, {"escape tabs", "col1\tcol2", `col1\tcol2`}, {"complex escaping", `"test"\n'value'`, `\"test\"\\n\'value\'`}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := escapeForJavaScript(tt.input) if got != tt.want { t.Errorf("escapeForJavaScript() = %q, want %q", got, tt.want) } }) } } func TestSaveAndRemoveScript(t *testing.T) { // Set up test scripts directory tempDir := t.TempDir() oldGetScriptsDir := getScriptsDirectory getScriptsDirectory = func() (string, error) { return tempDir, nil } defer func() { getScriptsDirectory = oldGetScriptsDir }() // Test save script metadata := ScriptMetadata{ Description: "Test save script", Category: "test", Tags: []string{"test"}, Author: "Test", Version: "1.0.0", } code := "function test() { return 'saved'; }" scriptName := "test_save_script" // Save the script err := saveScript(scriptName, code, metadata) if err != nil { t.Fatalf("saveScript() error = %v", err) } // Verify file exists expectedPath := filepath.Join(tempDir, scriptName+".ts") if _, err := os.Stat(expectedPath); os.IsNotExist(err) { t.Errorf("script file was not created at %s", expectedPath) } // Test remove script err = removeScript(scriptName) if err != nil { t.Fatalf("removeScript() error = %v", err) } // Verify file is removed if _, err := os.Stat(expectedPath); !os.IsNotExist(err) { t.Errorf("script file was not removed from %s", expectedPath) } // Test removing non-existent script err = removeScript("non_existent") if err == nil { t.Errorf("removeScript() should error for non-existent script") } } func TestGenerateLibraryCode(t *testing.T) { scripts := []Script{ { Name: "testFunc", Metadata: ScriptMetadata{ Description: "Test function", Category: "test", Tags: []string{"test", "example"}, Examples: []string{"testFunc()", "testFunc(42)"}, Parameters: map[string]string{"value": "input value"}, ReturnType: "string", Author: "Test Author", Version: "1.0.0", }, Code: "function testFunc(value) { return 'test: ' + value; }", }, } code := generateLibraryCode(scripts) // Check that the generated code contains expected elements checks := []string{ "window.brummerLibrary = {", "testFunc:", "Test function", "window.lib = window.brummerLibrary", "__meta:", "list: function()", "help: function(", } for _, check := range checks { if !strings.Contains(code, check) { t.Errorf("generated code missing expected element: %q", check) } } // Verify it's valid JavaScript by checking basic syntax if strings.Count(code, "{") != strings.Count(code, "}") { t.Errorf("generated code has unbalanced braces") } } func TestLoadAllScripts(t *testing.T) { // Set up test scripts directory tempDir := t.TempDir() oldGetScriptsDir := getScriptsDirectory getScriptsDirectory = func() (string, error) { return tempDir, nil } defer func() { getScriptsDirectory = oldGetScriptsDir }() // Create test scripts script1 := `/*** { "description": "Script 1" } ***/ function script1() { return 1; }` script2 := `/*** { "description": "Script 2", "category": "util" } ***/ function script2() { return 2; }` // Write scripts os.WriteFile(filepath.Join(tempDir, "script1.ts"), []byte(script1), 0644) os.WriteFile(filepath.Join(tempDir, "script2.ts"), []byte(script2), 0644) // Also create a non-.ts file that should be ignored os.WriteFile(filepath.Join(tempDir, "notscript.js"), []byte("// not a ts file"), 0644) // Load all scripts scripts, err := loadAllScripts() if err != nil { t.Fatalf("loadAllScripts() error = %v", err) } // Verify correct number of scripts loaded if len(scripts) != 2 { t.Errorf("got %d scripts, want 2", len(scripts)) } // Verify script details scriptNames := make(map[string]bool) for _, s := range scripts { scriptNames[s.Name] = true } if !scriptNames["script1"] || !scriptNames["script2"] { t.Errorf("expected scripts not found, got: %v", scriptNames) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/standardbeagle/brummer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server