feat: implement Wiki.js MCP Server with full test coverage
Implements Phase 1.1b - Wiki.js MCP Server for documentation management and lessons learned capture. **Features:** - GraphQL client for Wiki.js API - Page management (CRUD operations) - Lessons learned workflow - Mode detection (project vs company-wide) - Hybrid configuration system - 18 comprehensive tests (all passing) **Components:** - config.py: Configuration loader with mode detection - wikijs_client.py: GraphQL client implementation - server.py: MCP server with 8 tools - tools/pages.py: Page management tools - tools/lessons_learned.py: Lessons learned tools **Tools Provided:** - search_pages: Search by keywords and tags - get_page: Retrieve specific page - create_page: Create new page with markdown - update_page: Update existing page - list_pages: List pages under path - create_lesson: Create lessons learned entry - search_lessons: Search previous lessons - tag_lesson: Add/update lesson tags **Testing:** - 18 unit tests with mocks (all passing) - Integration tests with real Wiki.js instance - Configuration validation tests - GraphQL error handling tests **Documentation:** - Comprehensive README.md with usage guide - TESTING.md with testing instructions - Integration test script for validation Verified working with live Wiki.js instance at http://wikijs.hotport 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
185
mcp-servers/wikijs/test_integration.py
Normal file
185
mcp-servers/wikijs/test_integration.py
Normal file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Integration test script for Wiki.js MCP Server.
|
||||
Tests against real Wiki.js instance.
|
||||
|
||||
Usage:
|
||||
python test_integration.py
|
||||
"""
|
||||
import asyncio
|
||||
import sys
|
||||
from mcp_server.config import WikiJSConfig
|
||||
from mcp_server.wikijs_client import WikiJSClient
|
||||
|
||||
|
||||
async def test_connection():
|
||||
"""Test basic connection to Wiki.js"""
|
||||
print("🔌 Testing Wiki.js connection...")
|
||||
|
||||
try:
|
||||
config_loader = WikiJSConfig()
|
||||
config = config_loader.load()
|
||||
|
||||
print(f"✓ Configuration loaded")
|
||||
print(f" - API URL: {config['api_url']}")
|
||||
print(f" - Base Path: {config['base_path']}")
|
||||
print(f" - Mode: {config['mode']}")
|
||||
if config.get('project'):
|
||||
print(f" - Project: {config['project']}")
|
||||
|
||||
client = WikiJSClient(
|
||||
api_url=config['api_url'],
|
||||
api_token=config['api_token'],
|
||||
base_path=config['base_path'],
|
||||
project=config.get('project')
|
||||
)
|
||||
|
||||
print("✓ Client initialized")
|
||||
return client
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Configuration failed: {e}")
|
||||
return None
|
||||
|
||||
|
||||
async def test_list_pages(client):
|
||||
"""Test listing pages"""
|
||||
print("\n📄 Testing list_pages...")
|
||||
|
||||
try:
|
||||
pages = await client.list_pages("")
|
||||
print(f"✓ Found {len(pages)} pages")
|
||||
|
||||
if pages:
|
||||
print(f" Sample pages:")
|
||||
for page in pages[:5]:
|
||||
print(f" - {page.get('title')} ({page.get('path')})")
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"✗ List pages failed: {e}")
|
||||
return False
|
||||
|
||||
|
||||
async def test_search_pages(client):
|
||||
"""Test searching pages"""
|
||||
print("\n🔍 Testing search_pages...")
|
||||
|
||||
try:
|
||||
results = await client.search_pages("test", limit=5)
|
||||
print(f"✓ Search returned {len(results)} results")
|
||||
|
||||
if results:
|
||||
print(f" Sample results:")
|
||||
for result in results[:3]:
|
||||
print(f" - {result.get('title')}")
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"✗ Search failed: {e}")
|
||||
return False
|
||||
|
||||
|
||||
async def test_create_page(client):
|
||||
"""Test creating a page"""
|
||||
print("\n➕ Testing create_page...")
|
||||
|
||||
# Use timestamp to create unique page path
|
||||
import time
|
||||
timestamp = int(time.time())
|
||||
page_path = f"testing/integration-test-{timestamp}"
|
||||
|
||||
try:
|
||||
page = await client.create_page(
|
||||
path=page_path,
|
||||
title=f"Integration Test Page - {timestamp}",
|
||||
content="# Integration Test\n\nThis page was created by the Wiki.js MCP Server integration test.",
|
||||
description="Automated test page",
|
||||
tags=["test", "integration", "mcp"],
|
||||
is_published=False # Don't publish test page
|
||||
)
|
||||
|
||||
print(f"✓ Page created successfully")
|
||||
print(f" - ID: {page.get('id')}")
|
||||
print(f" - Path: {page.get('path')}")
|
||||
print(f" - Title: {page.get('title')}")
|
||||
|
||||
return page_path # Return path for testing get_page
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"✗ Create page failed: {e}")
|
||||
print(f" Error details: {traceback.format_exc()}")
|
||||
return None
|
||||
|
||||
|
||||
async def test_get_page(client, page_path):
|
||||
"""Test getting a specific page"""
|
||||
print("\n📖 Testing get_page...")
|
||||
|
||||
try:
|
||||
page = await client.get_page(page_path)
|
||||
|
||||
if page:
|
||||
print(f"✓ Page retrieved successfully")
|
||||
print(f" - Title: {page.get('title')}")
|
||||
print(f" - Tags: {', '.join(page.get('tags', []))}")
|
||||
print(f" - Published: {page.get('isPublished')}")
|
||||
return True
|
||||
else:
|
||||
print(f"✗ Page not found: {page_path}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Get page failed: {e}")
|
||||
return False
|
||||
|
||||
|
||||
async def main():
|
||||
"""Run all integration tests"""
|
||||
print("=" * 60)
|
||||
print("Wiki.js MCP Server - Integration Tests")
|
||||
print("=" * 60)
|
||||
|
||||
# Test connection
|
||||
client = await test_connection()
|
||||
if not client:
|
||||
print("\n❌ Integration tests failed: Cannot connect to Wiki.js")
|
||||
sys.exit(1)
|
||||
|
||||
# Run tests
|
||||
results = []
|
||||
|
||||
results.append(await test_list_pages(client))
|
||||
results.append(await test_search_pages(client))
|
||||
|
||||
page_path = await test_create_page(client)
|
||||
if page_path:
|
||||
results.append(True)
|
||||
# Test getting the created page
|
||||
results.append(await test_get_page(client, page_path))
|
||||
else:
|
||||
results.append(False)
|
||||
results.append(False)
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 60)
|
||||
print("Test Summary")
|
||||
print("=" * 60)
|
||||
|
||||
passed = sum(results)
|
||||
total = len(results)
|
||||
|
||||
print(f"✓ Passed: {passed}/{total}")
|
||||
print(f"✗ Failed: {total - passed}/{total}")
|
||||
|
||||
if passed == total:
|
||||
print("\n✅ All integration tests passed!")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("\n❌ Some integration tests failed")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user