fix: Resolve all CI failures (ruff linting + MCP test failures)
Fixed 7 ruff linting errors: - SIM102: Simplified nested if statements in rag_chunker.py - SIM113: Use enumerate() in streaming_ingest.py - ARG001: Prefix unused signal handler args with underscore - SIM105: Replace try-except-pass with contextlib.suppress (3 instances) Fixed 7 MCP server test failures: - Updated generate_config_tool to output unified format (not legacy) - Updated test_validate_valid_config to use unified format - Renamed test_submit_config_accepts_legacy_format to test_submit_config_rejects_legacy_format (tests rejection, not acceptance) - Updated all submit_config tests to use unified format: - test_submit_config_requires_token - test_submit_config_from_file_path - test_submit_config_detects_category - test_submit_config_validates_name_format - test_submit_config_validates_url_format Added v3.0.0 release planning documents: - RELEASE_EXECUTIVE_SUMMARY_v3.0.0.md (one-page overview) - RELEASE_PLAN_v3.0.0.md (complete 4-week campaign) - RELEASE_CONTENT_CHECKLIST_v3.0.0.md (content creation guide) All tests should now pass. Ready for v3.0.0 release. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -208,10 +208,8 @@ class TestWeaviateIntegration:
|
||||
|
||||
finally:
|
||||
# Cleanup - Delete collection
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
client.schema.delete_class(class_name)
|
||||
except Exception:
|
||||
pass # Best effort cleanup
|
||||
|
||||
def test_weaviate_metadata_preservation(self, sample_skill_dir, tmp_path):
|
||||
"""Test that metadata is correctly stored and retrieved."""
|
||||
@@ -357,10 +355,8 @@ class TestChromaIntegration:
|
||||
|
||||
finally:
|
||||
# Cleanup - Delete collection
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
client.delete_collection(name=collection_name)
|
||||
except Exception:
|
||||
pass # Best effort cleanup
|
||||
|
||||
def test_chroma_query_filtering(self, sample_skill_dir, tmp_path):
|
||||
"""Test metadata filtering in ChromaDB queries."""
|
||||
@@ -523,10 +519,8 @@ class TestQdrantIntegration:
|
||||
|
||||
finally:
|
||||
# Cleanup - Delete collection
|
||||
try:
|
||||
with contextlib.suppress(Exception):
|
||||
client.delete_collection(collection_name)
|
||||
except Exception:
|
||||
pass # Best effort cleanup
|
||||
|
||||
def test_qdrant_payload_filtering(self, sample_skill_dir, tmp_path):
|
||||
"""Test payload filtering in Qdrant."""
|
||||
|
||||
@@ -459,14 +459,18 @@ class TestValidateConfigTool(unittest.IsolatedAsyncioTestCase):
|
||||
|
||||
async def test_validate_valid_config(self):
|
||||
"""Test validating a valid config"""
|
||||
# Create valid config
|
||||
# Create valid config (unified format)
|
||||
config_path = Path("configs/valid.json")
|
||||
valid_config = {
|
||||
"name": "valid-test",
|
||||
"base_url": "https://example.com/",
|
||||
"selectors": {"main_content": "article", "title": "h1", "code_blocks": "pre"},
|
||||
"rate_limit": 0.5,
|
||||
"max_pages": 100,
|
||||
"description": "Test configuration",
|
||||
"sources": [{
|
||||
"type": "documentation",
|
||||
"base_url": "https://example.com/",
|
||||
"selectors": {"main_content": "article", "title": "h1", "code_blocks": "pre"},
|
||||
"rate_limit": 0.5,
|
||||
"max_pages": 100,
|
||||
}],
|
||||
}
|
||||
with open(config_path, "w") as f:
|
||||
json.dump(valid_config, f)
|
||||
@@ -569,7 +573,7 @@ class TestSubmitConfigTool(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_submit_config_requires_token(self):
|
||||
"""Should error without GitHub token"""
|
||||
args = {
|
||||
"config_json": '{"name": "test", "description": "Test", "base_url": "https://example.com"}'
|
||||
"config_json": '{"name": "test", "description": "Test", "sources": [{"type": "documentation", "base_url": "https://example.com"}]}'
|
||||
}
|
||||
result = await skill_seeker_server.submit_config_tool(args)
|
||||
self.assertIn("GitHub token required", result[0].text)
|
||||
@@ -590,7 +594,7 @@ class TestSubmitConfigTool(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_submit_config_validates_name_format(self):
|
||||
"""Should reject invalid name characters"""
|
||||
args = {
|
||||
"config_json": '{"name": "React@2024!", "description": "Test", "base_url": "https://example.com"}',
|
||||
"config_json": '{"name": "React@2024!", "description": "Test", "sources": [{"type": "documentation", "base_url": "https://example.com"}]}',
|
||||
"github_token": "fake_token",
|
||||
}
|
||||
result = await skill_seeker_server.submit_config_tool(args)
|
||||
@@ -599,35 +603,28 @@ class TestSubmitConfigTool(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_submit_config_validates_url_format(self):
|
||||
"""Should reject invalid URL format"""
|
||||
args = {
|
||||
"config_json": '{"name": "test", "description": "Test", "base_url": "not-a-url"}',
|
||||
"config_json": '{"name": "test", "description": "Test", "sources": [{"type": "documentation", "base_url": "not-a-url"}]}',
|
||||
"github_token": "fake_token",
|
||||
}
|
||||
result = await skill_seeker_server.submit_config_tool(args)
|
||||
self.assertIn("validation failed", result[0].text.lower())
|
||||
|
||||
async def test_submit_config_accepts_legacy_format(self):
|
||||
"""Should accept valid legacy config"""
|
||||
valid_config = {
|
||||
async def test_submit_config_rejects_legacy_format(self):
|
||||
"""Should reject legacy config format (removed in v2.11.0)"""
|
||||
legacy_config = {
|
||||
"name": "testframework",
|
||||
"description": "Test framework docs",
|
||||
"base_url": "https://docs.test.com/",
|
||||
"base_url": "https://docs.test.com/", # Legacy: base_url at root level
|
||||
"selectors": {"main_content": "article", "title": "h1", "code_blocks": "pre code"},
|
||||
"max_pages": 100,
|
||||
}
|
||||
args = {"config_json": json.dumps(valid_config), "github_token": "fake_token"}
|
||||
args = {"config_json": json.dumps(legacy_config), "github_token": "fake_token"}
|
||||
|
||||
# Mock GitHub API call
|
||||
with patch("github.Github") as mock_gh:
|
||||
mock_repo = MagicMock()
|
||||
mock_issue = MagicMock()
|
||||
mock_issue.html_url = "https://github.com/test/issue/1"
|
||||
mock_issue.number = 1
|
||||
mock_repo.create_issue.return_value = mock_issue
|
||||
mock_gh.return_value.get_repo.return_value = mock_repo
|
||||
|
||||
result = await skill_seeker_server.submit_config_tool(args)
|
||||
self.assertIn("Config submitted successfully", result[0].text)
|
||||
self.assertIn("https://github.com", result[0].text)
|
||||
result = await skill_seeker_server.submit_config_tool(args)
|
||||
# Should reject with helpful error message
|
||||
self.assertIn("❌", result[0].text)
|
||||
self.assertIn("LEGACY CONFIG FORMAT DETECTED", result[0].text)
|
||||
self.assertIn("sources", result[0].text) # Should mention unified format with sources array
|
||||
|
||||
async def test_submit_config_accepts_unified_format(self):
|
||||
"""Should accept valid unified config"""
|
||||
@@ -658,7 +655,12 @@ class TestSubmitConfigTool(unittest.IsolatedAsyncioTestCase):
|
||||
"""Should accept config_path parameter"""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
|
||||
json.dump(
|
||||
{"name": "testfile", "description": "From file", "base_url": "https://test.com/"}, f
|
||||
{
|
||||
"name": "testfile",
|
||||
"description": "From file",
|
||||
"sources": [{"type": "documentation", "base_url": "https://test.com/"}],
|
||||
},
|
||||
f,
|
||||
)
|
||||
temp_path = f.name
|
||||
|
||||
@@ -681,7 +683,7 @@ class TestSubmitConfigTool(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_submit_config_detects_category(self):
|
||||
"""Should auto-detect category from config name"""
|
||||
args = {
|
||||
"config_json": '{"name": "react-test", "description": "React", "base_url": "https://react.dev/"}',
|
||||
"config_json": '{"name": "react-test", "description": "React", "sources": [{"type": "documentation", "base_url": "https://react.dev/"}]}',
|
||||
"github_token": "fake_token",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user