Fix 3 critical issues identified in repository review

**Critical Fixes:**

1. **Fixed Error Hierarchy** (wikijs/exceptions.py)
   - ConnectionError and TimeoutError now properly inherit from APIError
   - Ensures consistent exception handling across the SDK
   - Added proper __init__ methods with status_code=None

2. **Fixed test_connection Method** (wikijs/client.py)
   - Changed from basic HTTP GET to proper GraphQL query validation
   - Now uses query { site { title } } to validate API connectivity
   - Provides better error messages for authentication failures
   - Validates both connectivity AND API access

3. **Implemented JWT Token Refresh** (wikijs/auth/jwt.py)
   - Added base_url parameter to JWTAuth class
   - Implemented complete refresh() method with HTTP request to /api/auth/refresh
   - Handles token, refresh token, and expiration updates
   - Proper error handling for network failures and auth errors

**Bonus Fixes:**
- Dynamic user agent version (uses __version__ from version.py instead of hardcoded)
- Updated all JWT tests to include required base_url parameter
- Updated test mocks to match new GraphQL-based test_connection

**Test Results:**
- All 231 tests passing 
- Test coverage: 91.64% (target: 85%) 
- No test failures or errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2025-10-22 17:44:44 +00:00
parent 3e2430fbe0
commit 66f4471e53
6 changed files with 197 additions and 94 deletions

View File

@@ -23,6 +23,7 @@ from .utils import (
normalize_url,
parse_wiki_response,
)
from .version import __version__
class WikiJSClient:
@@ -82,7 +83,7 @@ class WikiJSClient:
# Request configuration
self.timeout = timeout
self.verify_ssl = verify_ssl
self.user_agent = user_agent or "wikijs-python-sdk/0.1.0"
self.user_agent = user_agent or f"wikijs-python-sdk/{__version__}"
# Initialize HTTP session
self._session = self._create_session()
@@ -229,6 +230,9 @@ class WikiJSClient:
def test_connection(self) -> bool:
"""Test connection to Wiki.js instance.
This method validates the connection by making an actual GraphQL query
to the Wiki.js API, ensuring both connectivity and authentication work.
Returns:
True if connection successful
@@ -236,6 +240,7 @@ class WikiJSClient:
ConfigurationError: If client is not properly configured
ConnectionError: If cannot connect to server
AuthenticationError: If authentication fails
TimeoutError: If connection test times out
"""
if not self.base_url:
raise ConfigurationError("Base URL not configured")
@@ -244,20 +249,47 @@ class WikiJSClient:
raise ConfigurationError("Authentication not configured")
try:
# Try to hit a basic endpoint (will implement with actual endpoints)
# For now, just test basic connectivity
self._session.get(
self.base_url, timeout=self.timeout, verify=self.verify_ssl
)
# Test with minimal GraphQL query to validate API access
query = """
query {
site {
title
}
}
"""
response = self._request("POST", "/graphql", json_data={"query": query})
# Check for GraphQL errors
if "errors" in response:
error_msg = response["errors"][0].get("message", "Unknown error")
raise AuthenticationError(
f"GraphQL query failed: {error_msg}"
)
# Verify we got expected data structure
if "data" not in response or "site" not in response["data"]:
raise APIError(
"Unexpected response format from Wiki.js API"
)
return True
except requests.exceptions.Timeout:
raise TimeoutError(
f"Connection test timed out after {self.timeout} seconds"
)
except AuthenticationError:
# Re-raise authentication errors as-is
raise
except requests.exceptions.ConnectionError as e:
raise ConnectionError(f"Cannot connect to {self.base_url}: {str(e)}")
except TimeoutError:
# Re-raise timeout errors as-is
raise
except ConnectionError:
# Re-raise connection errors as-is
raise
except APIError:
# Re-raise API errors as-is
raise
except Exception as e:
raise ConnectionError(f"Connection test failed: {str(e)}")