Fix code formatting and linting issues

- Updated GitHub Actions workflow to use correct flake8 configuration
- Fixed line length issues by using 88 characters as configured
- Removed unused imports and trailing whitespace
- Fixed f-string placeholders and unused variables
- All linting checks now pass with project configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-30 20:49:40 -04:00
parent 16bd151337
commit ade9aacf56
33 changed files with 1099 additions and 1096 deletions

View File

@@ -1 +1 @@
"""Tests for API endpoints."""
"""Tests for API endpoints."""

View File

@@ -1,147 +1,144 @@
"""Tests for base endpoint class."""
import pytest
from unittest.mock import Mock
import pytest
from wikijs.client import WikiJSClient
from wikijs.endpoints.base import BaseEndpoint
class TestBaseEndpoint:
"""Test suite for BaseEndpoint."""
@pytest.fixture
def mock_client(self):
"""Create a mock WikiJS client."""
client = Mock(spec=WikiJSClient)
return client
@pytest.fixture
def base_endpoint(self, mock_client):
"""Create a BaseEndpoint instance with mock client."""
return BaseEndpoint(mock_client)
def test_init(self, mock_client):
"""Test BaseEndpoint initialization."""
endpoint = BaseEndpoint(mock_client)
assert endpoint._client is mock_client
def test_request(self, base_endpoint, mock_client):
"""Test _request method delegates to client."""
# Setup mock response
mock_response = {"data": "test"}
mock_client._request.return_value = mock_response
# Call _request
result = base_endpoint._request(
"GET",
"/test",
params={"param": "value"},
json_data={"data": "test"},
extra_param="extra"
extra_param="extra",
)
# Verify delegation to client
mock_client._request.assert_called_once_with(
method="GET",
endpoint="/test",
params={"param": "value"},
json_data={"data": "test"},
extra_param="extra"
extra_param="extra",
)
# Verify response
assert result == mock_response
def test_get(self, base_endpoint, mock_client):
"""Test _get method."""
mock_response = {"data": "test"}
mock_client._request.return_value = mock_response
result = base_endpoint._get("/test", params={"param": "value"})
mock_client._request.assert_called_once_with(
method="GET",
endpoint="/test",
params={"param": "value"},
json_data=None
json_data=None,
)
assert result == mock_response
def test_post(self, base_endpoint, mock_client):
"""Test _post method."""
mock_response = {"data": "test"}
mock_client._request.return_value = mock_response
result = base_endpoint._post(
"/test",
json_data={"data": "test"},
params={"param": "value"}
"/test", json_data={"data": "test"}, params={"param": "value"}
)
mock_client._request.assert_called_once_with(
method="POST",
endpoint="/test",
params={"param": "value"},
json_data={"data": "test"}
json_data={"data": "test"},
)
assert result == mock_response
def test_put(self, base_endpoint, mock_client):
"""Test _put method."""
mock_response = {"data": "test"}
mock_client._request.return_value = mock_response
result = base_endpoint._put(
"/test",
json_data={"data": "test"},
params={"param": "value"}
"/test", json_data={"data": "test"}, params={"param": "value"}
)
mock_client._request.assert_called_once_with(
method="PUT",
endpoint="/test",
params={"param": "value"},
json_data={"data": "test"}
json_data={"data": "test"},
)
assert result == mock_response
def test_delete(self, base_endpoint, mock_client):
"""Test _delete method."""
mock_response = {"data": "test"}
mock_client._request.return_value = mock_response
result = base_endpoint._delete("/test", params={"param": "value"})
mock_client._request.assert_called_once_with(
method="DELETE",
endpoint="/test",
params={"param": "value"},
json_data=None
json_data=None,
)
assert result == mock_response
def test_build_endpoint_single_part(self, base_endpoint):
"""Test _build_endpoint with single part."""
result = base_endpoint._build_endpoint("test")
assert result == "/test"
def test_build_endpoint_multiple_parts(self, base_endpoint):
"""Test _build_endpoint with multiple parts."""
result = base_endpoint._build_endpoint("api", "v1", "pages")
assert result == "/api/v1/pages"
def test_build_endpoint_with_slashes(self, base_endpoint):
"""Test _build_endpoint handles leading/trailing slashes."""
result = base_endpoint._build_endpoint("/api/", "/v1/", "/pages/")
assert result == "/api/v1/pages"
def test_build_endpoint_empty_parts(self, base_endpoint):
"""Test _build_endpoint filters out empty parts."""
result = base_endpoint._build_endpoint("api", "", "pages", None)
assert result == "/api/pages"
def test_build_endpoint_numeric_parts(self, base_endpoint):
"""Test _build_endpoint handles numeric parts."""
result = base_endpoint._build_endpoint("pages", 123, "edit")
assert result == "/pages/123/edit"
assert result == "/pages/123/edit"

View File

@@ -1,8 +1,9 @@
"""Tests for Pages API endpoint."""
import pytest
from unittest.mock import Mock, patch
import pytest
from wikijs.client import WikiJSClient
from wikijs.endpoints.pages import PagesEndpoint
from wikijs.exceptions import APIError, ValidationError
@@ -11,18 +12,18 @@ from wikijs.models.page import Page, PageCreate, PageUpdate
class TestPagesEndpoint:
"""Test suite for PagesEndpoint."""
@pytest.fixture
def mock_client(self):
"""Create a mock WikiJS client."""
client = Mock(spec=WikiJSClient)
return client
@pytest.fixture
def pages_endpoint(self, mock_client):
"""Create a PagesEndpoint instance with mock client."""
return PagesEndpoint(mock_client)
@pytest.fixture
def sample_page_data(self):
"""Sample page data from API."""
@@ -41,9 +42,9 @@ class TestPagesEndpoint:
"authorEmail": "test@example.com",
"editor": "markdown",
"createdAt": "2023-01-01T00:00:00Z",
"updatedAt": "2023-01-02T00:00:00Z"
"updatedAt": "2023-01-02T00:00:00Z",
}
@pytest.fixture
def sample_page_create(self):
"""Sample PageCreate object."""
@@ -52,57 +53,49 @@ class TestPagesEndpoint:
path="new-page",
content="# New Page\n\nContent here.",
description="A new page",
tags=["new", "test"]
tags=["new", "test"],
)
@pytest.fixture
def sample_page_update(self):
"""Sample PageUpdate object."""
return PageUpdate(
title="Updated Page",
content="# Updated Page\n\nUpdated content.",
tags=["updated", "test"]
tags=["updated", "test"],
)
def test_init(self, mock_client):
"""Test PagesEndpoint initialization."""
endpoint = PagesEndpoint(mock_client)
assert endpoint._client is mock_client
def test_list_basic(self, pages_endpoint, sample_page_data):
"""Test basic page listing."""
# Mock the GraphQL response
mock_response = {
"data": {
"pages": [sample_page_data]
}
}
mock_response = {"data": {"pages": [sample_page_data]}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call list method
pages = pages_endpoint.list()
# Verify request
pages_endpoint._post.assert_called_once()
call_args = pages_endpoint._post.call_args
assert call_args[0][0] == "/graphql"
# Verify response
assert len(pages) == 1
assert isinstance(pages[0], Page)
assert pages[0].id == 123
assert pages[0].title == "Test Page"
assert pages[0].path == "test-page"
def test_list_with_parameters(self, pages_endpoint, sample_page_data):
"""Test page listing with filter parameters."""
mock_response = {
"data": {
"pages": [sample_page_data]
}
}
mock_response = {"data": {"pages": [sample_page_data]}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call with parameters
pages = pages_endpoint.list(
limit=10,
@@ -112,14 +105,14 @@ class TestPagesEndpoint:
locale="en",
author_id=1,
order_by="created_at",
order_direction="DESC"
order_direction="DESC",
)
# Verify request
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
variables = query_data["variables"]
assert variables["limit"] == 10
assert variables["offset"] == 5
assert variables["search"] == "test"
@@ -128,133 +121,117 @@ class TestPagesEndpoint:
assert variables["authorId"] == 1
assert variables["orderBy"] == "created_at"
assert variables["orderDirection"] == "DESC"
# Verify response
assert len(pages) == 1
assert isinstance(pages[0], Page)
def test_list_validation_errors(self, pages_endpoint):
"""Test list method parameter validation."""
# Test invalid limit
with pytest.raises(ValidationError, match="limit must be greater than 0"):
pages_endpoint.list(limit=0)
# Test invalid offset
with pytest.raises(ValidationError, match="offset must be non-negative"):
pages_endpoint.list(offset=-1)
# Test invalid order_by
with pytest.raises(ValidationError, match="order_by must be one of"):
pages_endpoint.list(order_by="invalid")
# Test invalid order_direction
with pytest.raises(ValidationError, match="order_direction must be ASC or DESC"):
with pytest.raises(
ValidationError, match="order_direction must be ASC or DESC"
):
pages_endpoint.list(order_direction="INVALID")
def test_list_api_error(self, pages_endpoint):
"""Test list method handling API errors."""
# Mock GraphQL error response
mock_response = {
"errors": [{"message": "GraphQL error"}]
}
mock_response = {"errors": [{"message": "GraphQL error"}]}
pages_endpoint._post = Mock(return_value=mock_response)
with pytest.raises(APIError, match="GraphQL errors"):
pages_endpoint.list()
def test_get_success(self, pages_endpoint, sample_page_data):
"""Test getting a page by ID."""
mock_response = {
"data": {
"page": sample_page_data
}
}
mock_response = {"data": {"page": sample_page_data}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call method
page = pages_endpoint.get(123)
# Verify request
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
assert query_data["variables"]["id"] == 123
# Verify response
assert isinstance(page, Page)
assert page.id == 123
assert page.title == "Test Page"
def test_get_validation_error(self, pages_endpoint):
"""Test get method parameter validation."""
with pytest.raises(ValidationError, match="page_id must be a positive integer"):
pages_endpoint.get(0)
with pytest.raises(ValidationError, match="page_id must be a positive integer"):
pages_endpoint.get(-1)
with pytest.raises(ValidationError, match="page_id must be a positive integer"):
pages_endpoint.get("invalid")
def test_get_not_found(self, pages_endpoint):
"""Test get method when page not found."""
mock_response = {
"data": {
"page": None
}
}
mock_response = {"data": {"page": None}}
pages_endpoint._post = Mock(return_value=mock_response)
with pytest.raises(APIError, match="Page with ID 123 not found"):
pages_endpoint.get(123)
def test_get_by_path_success(self, pages_endpoint, sample_page_data):
"""Test getting a page by path."""
mock_response = {
"data": {
"pageByPath": sample_page_data
}
}
mock_response = {"data": {"pageByPath": sample_page_data}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call method
page = pages_endpoint.get_by_path("test-page")
# Verify request
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
variables = query_data["variables"]
assert variables["path"] == "test-page"
assert variables["locale"] == "en"
# Verify response
assert isinstance(page, Page)
assert page.path == "test-page"
def test_get_by_path_validation_error(self, pages_endpoint):
"""Test get_by_path method parameter validation."""
with pytest.raises(ValidationError, match="path must be a non-empty string"):
pages_endpoint.get_by_path("")
with pytest.raises(ValidationError, match="path must be a non-empty string"):
pages_endpoint.get_by_path(None)
def test_create_success(self, pages_endpoint, sample_page_create, sample_page_data):
"""Test creating a new page."""
mock_response = {
"data": {
"createPage": sample_page_data
}
}
mock_response = {"data": {"createPage": sample_page_data}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call method
created_page = pages_endpoint.create(sample_page_create)
# Verify request
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
variables = query_data["variables"]
assert variables["title"] == "New Page"
assert variables["path"] == "new-page"
assert variables["content"] == "# New Page\n\nContent here."
@@ -262,194 +239,177 @@ class TestPagesEndpoint:
assert variables["tags"] == ["new", "test"]
assert variables["isPublished"] is True
assert variables["isPrivate"] is False
# Verify response
assert isinstance(created_page, Page)
assert created_page.id == 123
def test_create_with_dict(self, pages_endpoint, sample_page_data):
"""Test creating a page with dict data."""
mock_response = {
"data": {
"createPage": sample_page_data
}
}
mock_response = {"data": {"createPage": sample_page_data}}
pages_endpoint._post = Mock(return_value=mock_response)
page_dict = {
"title": "Dict Page",
"path": "dict-page",
"content": "Content from dict",
}
# Call method
created_page = pages_endpoint.create(page_dict)
# Verify response
assert isinstance(created_page, Page)
def test_create_validation_error(self, pages_endpoint):
"""Test create method validation errors."""
# Test invalid data type
with pytest.raises(ValidationError, match="page_data must be PageCreate object or dict"):
with pytest.raises(
ValidationError,
match="page_data must be PageCreate object or dict",
):
pages_endpoint.create("invalid")
# Test invalid dict data
with pytest.raises(ValidationError, match="Invalid page data"):
pages_endpoint.create({"invalid": "data"})
def test_create_api_error(self, pages_endpoint, sample_page_create):
"""Test create method API errors."""
mock_response = {
"errors": [{"message": "Creation failed"}]
}
mock_response = {"errors": [{"message": "Creation failed"}]}
pages_endpoint._post = Mock(return_value=mock_response)
with pytest.raises(APIError, match="Failed to create page"):
pages_endpoint.create(sample_page_create)
def test_update_success(self, pages_endpoint, sample_page_update, sample_page_data):
"""Test updating a page."""
mock_response = {
"data": {
"updatePage": sample_page_data
}
}
mock_response = {"data": {"updatePage": sample_page_data}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call method
updated_page = pages_endpoint.update(123, sample_page_update)
# Verify request
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
variables = query_data["variables"]
assert variables["id"] == 123
assert variables["title"] == "Updated Page"
assert variables["content"] == "# Updated Page\n\nUpdated content."
assert variables["tags"] == ["updated", "test"]
assert "description" not in variables # Should not include None values
# Verify response
assert isinstance(updated_page, Page)
def test_update_validation_errors(self, pages_endpoint, sample_page_update):
"""Test update method validation errors."""
# Test invalid page_id
with pytest.raises(ValidationError, match="page_id must be a positive integer"):
pages_endpoint.update(0, sample_page_update)
# Test invalid page_data type
with pytest.raises(ValidationError, match="page_data must be PageUpdate object or dict"):
with pytest.raises(
ValidationError,
match="page_data must be PageUpdate object or dict",
):
pages_endpoint.update(123, "invalid")
def test_delete_success(self, pages_endpoint):
"""Test deleting a page."""
mock_response = {
"data": {
"deletePage": {
"success": True,
"message": "Page deleted successfully"
"message": "Page deleted successfully",
}
}
}
pages_endpoint._post = Mock(return_value=mock_response)
# Call method
result = pages_endpoint.delete(123)
# Verify request
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
assert query_data["variables"]["id"] == 123
# Verify response
assert result is True
def test_delete_validation_error(self, pages_endpoint):
"""Test delete method validation errors."""
with pytest.raises(ValidationError, match="page_id must be a positive integer"):
pages_endpoint.delete(0)
def test_delete_failure(self, pages_endpoint):
"""Test delete method when deletion fails."""
mock_response = {
"data": {
"deletePage": {
"success": False,
"message": "Deletion failed"
}
}
"data": {"deletePage": {"success": False, "message": "Deletion failed"}}
}
pages_endpoint._post = Mock(return_value=mock_response)
with pytest.raises(APIError, match="Page deletion failed: Deletion failed"):
pages_endpoint.delete(123)
def test_search_success(self, pages_endpoint, sample_page_data):
"""Test searching pages."""
mock_response = {
"data": {
"pages": [sample_page_data]
}
}
mock_response = {"data": {"pages": [sample_page_data]}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call method
results = pages_endpoint.search("test query", limit=5)
# Verify request (should call list with search parameter)
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
variables = query_data["variables"]
assert variables["search"] == "test query"
assert variables["limit"] == 5
# Verify response
assert len(results) == 1
assert isinstance(results[0], Page)
def test_search_validation_error(self, pages_endpoint):
"""Test search method validation errors."""
with pytest.raises(ValidationError, match="query must be a non-empty string"):
pages_endpoint.search("")
with pytest.raises(ValidationError, match="limit must be greater than 0"):
pages_endpoint.search("test", limit=0)
def test_get_by_tags_match_all(self, pages_endpoint, sample_page_data):
"""Test getting pages by tags (match all)."""
mock_response = {
"data": {
"pages": [sample_page_data]
}
}
mock_response = {"data": {"pages": [sample_page_data]}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call method
results = pages_endpoint.get_by_tags(["test", "example"], match_all=True)
# Verify request (should call list with tags parameter)
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
variables = query_data["variables"]
assert variables["tags"] == ["test", "example"]
# Verify response
assert len(results) == 1
assert isinstance(results[0], Page)
def test_get_by_tags_validation_error(self, pages_endpoint):
"""Test get_by_tags method validation errors."""
with pytest.raises(ValidationError, match="tags must be a non-empty list"):
pages_endpoint.get_by_tags([])
with pytest.raises(ValidationError, match="limit must be greater than 0"):
pages_endpoint.get_by_tags(["test"], limit=0)
def test_normalize_page_data(self, pages_endpoint):
"""Test page data normalization."""
api_data = {
@@ -457,11 +417,11 @@ class TestPagesEndpoint:
"title": "Test",
"isPublished": True,
"authorId": 1,
"createdAt": "2023-01-01T00:00:00Z"
"createdAt": "2023-01-01T00:00:00Z",
}
normalized = pages_endpoint._normalize_page_data(api_data)
# Check field mapping
assert normalized["id"] == 123
assert normalized["title"] == "Test"
@@ -469,57 +429,48 @@ class TestPagesEndpoint:
assert normalized["author_id"] == 1
assert normalized["created_at"] == "2023-01-01T00:00:00Z"
assert normalized["tags"] == [] # Default value
def test_normalize_page_data_missing_fields(self, pages_endpoint):
"""Test page data normalization with missing fields."""
api_data = {
"id": 123,
"title": "Test"
}
api_data = {"id": 123, "title": "Test"}
normalized = pages_endpoint._normalize_page_data(api_data)
# Check that only present fields are included
assert "id" in normalized
assert "title" in normalized
assert "is_published" not in normalized
assert "tags" in normalized # Should have default value
@patch('wikijs.endpoints.pages.Page')
def test_list_page_parsing_error(self, mock_page_class, pages_endpoint, sample_page_data):
@patch("wikijs.endpoints.pages.Page")
def test_list_page_parsing_error(
self, mock_page_class, pages_endpoint, sample_page_data
):
"""Test handling of page parsing errors in list method."""
# Mock Page constructor to raise an exception
mock_page_class.side_effect = ValueError("Parsing error")
mock_response = {
"data": {
"pages": [sample_page_data]
}
}
mock_response = {"data": {"pages": [sample_page_data]}}
pages_endpoint._post = Mock(return_value=mock_response)
with pytest.raises(APIError, match="Failed to parse page data"):
pages_endpoint.list()
def test_graphql_query_structure(self, pages_endpoint, sample_page_data):
"""Test that GraphQL queries have correct structure."""
mock_response = {
"data": {
"pages": [sample_page_data]
}
}
mock_response = {"data": {"pages": [sample_page_data]}}
pages_endpoint._post = Mock(return_value=mock_response)
# Call list method
pages_endpoint.list()
# Verify the GraphQL query structure
call_args = pages_endpoint._post.call_args
query_data = call_args[1]["json_data"]
assert "query" in query_data
assert "variables" in query_data
assert "pages(" in query_data["query"]
assert "id" in query_data["query"]
assert "title" in query_data["query"]
assert "content" in query_data["query"]
assert "content" in query_data["query"]