Improved parameter validation
Change-Id: If2e7ec1b063a6e114a6c5582463af784b75c37b8
diff --git a/tools/search_test.go b/tools/search_test.go
index 5966877..b80915a 100644
--- a/tools/search_test.go
+++ b/tools/search_test.go
@@ -32,6 +32,9 @@
// Verify it's an object type
assert.Equal(t, "object", schema["type"])
+ assert.Equal(t, "KorAP Search Parameters", schema["title"])
+ assert.Contains(t, schema["description"], "Parameters for searching text corpora")
+ assert.Equal(t, false, schema["additionalProperties"])
// Verify properties exist
properties, ok := schema["properties"].(map[string]interface{})
@@ -40,12 +43,168 @@
assert.Contains(t, properties, "query_language")
assert.Contains(t, properties, "corpus")
assert.Contains(t, properties, "count")
- // Note: offset and context will be added in future iterations
+
+ // Verify query property details
+ query, ok := properties["query"].(map[string]interface{})
+ assert.True(t, ok)
+ assert.Equal(t, "string", query["type"])
+ assert.Contains(t, query["description"], "search query")
+ assert.Equal(t, 1, query["minLength"])
+ assert.Equal(t, 1000, query["maxLength"])
+ examples, ok := query["examples"].([]string)
+ assert.True(t, ok)
+ assert.Contains(t, examples, "Haus")
+
+ // Verify query_language property details
+ queryLang, ok := properties["query_language"].(map[string]interface{})
+ assert.True(t, ok)
+ assert.Equal(t, "string", queryLang["type"])
+ assert.Contains(t, queryLang["description"], "Query language to use for parsing")
+ enum, ok := queryLang["enum"].([]string)
+ assert.True(t, ok)
+ assert.Contains(t, enum, "poliqarp")
+ assert.Contains(t, enum, "cosmas2")
+ assert.Contains(t, enum, "annis")
+ assert.Contains(t, enum, "cql")
+ assert.Contains(t, enum, "cqp")
+ assert.Contains(t, enum, "fcsql")
+ assert.Equal(t, "poliqarp", queryLang["default"])
+
+ // Verify corpus property details
+ corpus, ok := properties["corpus"].(map[string]interface{})
+ assert.True(t, ok)
+ assert.Equal(t, "string", corpus["type"])
+ assert.Contains(t, corpus["description"], "Virtual corpus query")
+ assert.NotEmpty(t, corpus["pattern"])
+ corpusExamples, ok := corpus["examples"].([]string)
+ assert.True(t, ok)
+ assert.Contains(t, corpusExamples, "corpusSigle = \"GOE\"")
+
+ // Verify count property details
+ count, ok := properties["count"].(map[string]interface{})
+ assert.True(t, ok)
+ assert.Equal(t, "integer", count["type"])
+ assert.Contains(t, count["description"], "Maximum number")
+ assert.Equal(t, 0, count["minimum"])
+ assert.Equal(t, 10000, count["maximum"])
+ assert.Equal(t, 25, count["default"])
+ countExamples, ok := count["examples"].([]interface{})
+ assert.True(t, ok)
+ assert.Contains(t, countExamples, 25)
// Verify required fields
required, ok := schema["required"].([]string)
assert.True(t, ok)
assert.Contains(t, required, "query")
+ assert.Len(t, required, 1) // Only query should be required
+}
+
+func TestSearchTool_SchemaCompliance(t *testing.T) {
+ // Test various parameter combinations against the schema
+ client := &service.Client{}
+ tool := NewSearchTool(client)
+
+ tests := []struct {
+ name string
+ arguments map[string]interface{}
+ expectValid bool
+ errorMsg string
+ }{
+ {
+ name: "valid_minimal",
+ arguments: map[string]interface{}{
+ "query": "test",
+ },
+ expectValid: true,
+ },
+ {
+ name: "valid_full",
+ arguments: map[string]interface{}{
+ "query": "word",
+ "query_language": "cosmas2",
+ "corpus": "test-corpus",
+ "count": 10,
+ },
+ expectValid: true,
+ },
+ {
+ name: "missing_required_query",
+ arguments: map[string]interface{}{
+ "query_language": "poliqarp",
+ },
+ expectValid: false,
+ errorMsg: "query parameter is required",
+ },
+ {
+ name: "invalid_query_language",
+ arguments: map[string]interface{}{
+ "query": "test",
+ "query_language": "invalid",
+ },
+ expectValid: false,
+ errorMsg: "invalid query language",
+ },
+ {
+ name: "invalid_count_negative",
+ arguments: map[string]interface{}{
+ "query": "test",
+ "count": -1,
+ },
+ expectValid: false,
+ errorMsg: "count must be",
+ },
+ {
+ name: "invalid_count_too_large",
+ arguments: map[string]interface{}{
+ "query": "test",
+ "count": 20000,
+ },
+ expectValid: false,
+ errorMsg: "count must be",
+ },
+ {
+ name: "empty_query",
+ arguments: map[string]interface{}{
+ "query": "",
+ },
+ expectValid: false,
+ errorMsg: "query is required and cannot be empty",
+ },
+ {
+ name: "count_zero_valid",
+ arguments: map[string]interface{}{
+ "query": "test",
+ "count": 0,
+ },
+ expectValid: true, // Zero count should be valid (uses default behavior)
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ request := mcp.CallToolRequest{
+ Params: mcp.CallToolParams{
+ Arguments: tt.arguments,
+ },
+ }
+
+ _, err := tool.Execute(context.Background(), request)
+
+ if tt.expectValid {
+ // For valid requests, we expect authentication/client errors, not validation errors
+ if err != nil {
+ assert.NotContains(t, err.Error(), "validation")
+ assert.Contains(t, err.Error(), "authentication")
+ }
+ } else {
+ // For invalid requests, we expect validation errors
+ assert.Error(t, err)
+ if tt.errorMsg != "" {
+ assert.Contains(t, err.Error(), tt.errorMsg)
+ }
+ }
+ })
+ }
}
func TestNewSearchTool(t *testing.T) {