172 lines
6.3 KiB
Python
172 lines
6.3 KiB
Python
"""Tests for Phase H — Wiki plugin: models, schemas, plugin manifest.
|
|
|
|
All tests use mocks — no real DB needed.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
|
|
class TestWikiPluginManifest:
|
|
"""Test the Wiki plugin manifest."""
|
|
|
|
def test_plugin_manifest_valid(self):
|
|
"""Wiki plugin manifest is valid."""
|
|
from app.plugins.builtins.wiki.plugin import WikiPlugin
|
|
|
|
assert WikiPlugin.manifest.name == "wiki"
|
|
assert WikiPlugin.manifest.version == "1.0.0"
|
|
assert WikiPlugin.manifest.display_name == "Wiki"
|
|
assert "wiki:read" in WikiPlugin.manifest.permissions
|
|
assert "wiki:write" in WikiPlugin.manifest.permissions
|
|
assert "wiki:delete" in WikiPlugin.manifest.permissions
|
|
assert "wiki:admin" in WikiPlugin.manifest.permissions
|
|
|
|
def test_plugin_has_routes(self):
|
|
"""Wiki plugin has routes defined."""
|
|
from app.plugins.builtins.wiki.plugin import WikiPlugin
|
|
|
|
assert len(WikiPlugin.manifest.routes) > 0
|
|
assert WikiPlugin.manifest.routes[0].path == "/api/v1/wiki"
|
|
|
|
def test_plugin_has_menu_item(self):
|
|
"""Wiki plugin has a menu item."""
|
|
from app.plugins.builtins.wiki.plugin import WikiPlugin
|
|
|
|
assert len(WikiPlugin.manifest.menu_items) > 0
|
|
assert WikiPlugin.manifest.menu_items[0].path == "/wiki"
|
|
|
|
def test_plugin_has_dependencies(self):
|
|
"""Wiki plugin depends on permissions plugin."""
|
|
from app.plugins.builtins.wiki.plugin import WikiPlugin
|
|
|
|
assert "permissions" in WikiPlugin.manifest.dependencies
|
|
|
|
|
|
class TestWikiRoutes:
|
|
"""Test the Wiki routes are properly defined."""
|
|
|
|
def test_routes_count(self):
|
|
"""Wiki plugin has 9 routes."""
|
|
from app.plugins.builtins.wiki.routes import router
|
|
|
|
assert len(router.routes) == 9
|
|
|
|
def test_routes_have_correct_paths(self):
|
|
"""Wiki routes have correct API paths."""
|
|
from app.plugins.builtins.wiki.routes import router
|
|
|
|
paths = {r.path for r in router.routes}
|
|
assert "/api/v1/wiki/articles" in paths
|
|
assert "/api/v1/wiki/articles/{article_id}" in paths
|
|
assert "/api/v1/wiki/articles/{article_id}/versions" in paths
|
|
assert "/api/v1/wiki/articles/{article_id}/versions/{version}/restore" in paths
|
|
assert "/api/v1/wiki/categories" in paths
|
|
|
|
|
|
class TestWikiSchemas:
|
|
"""Test the Wiki Pydantic schemas."""
|
|
|
|
def test_article_create_valid(self):
|
|
"""ArticleCreate accepts valid data."""
|
|
from app.plugins.builtins.wiki.schemas import ArticleCreate
|
|
|
|
article = ArticleCreate(title="Test Article", slug="test-article")
|
|
assert article.title == "Test Article"
|
|
assert article.slug == "test-article"
|
|
assert article.status == "draft"
|
|
assert article.tags == []
|
|
|
|
def test_article_create_invalid_status(self):
|
|
"""ArticleCreate rejects invalid status."""
|
|
from app.plugins.builtins.wiki.schemas import ArticleCreate
|
|
from pydantic import ValidationError
|
|
|
|
with pytest.raises(ValidationError):
|
|
ArticleCreate(title="Test", slug="test", status="invalid")
|
|
|
|
def test_article_update_partial(self):
|
|
"""ArticleUpdate allows partial updates."""
|
|
from app.plugins.builtins.wiki.schemas import ArticleUpdate
|
|
|
|
update = ArticleUpdate(title="Updated Title")
|
|
assert update.title == "Updated Title"
|
|
assert update.content is None
|
|
|
|
def test_category_create_valid(self):
|
|
"""CategoryCreate accepts valid data."""
|
|
from app.plugins.builtins.wiki.schemas import CategoryCreate
|
|
|
|
cat = CategoryCreate(name="Test Category", slug="test-category")
|
|
assert cat.name == "Test Category"
|
|
assert cat.slug == "test-category"
|
|
assert cat.sort_order == 0
|
|
|
|
|
|
class TestWikiModels:
|
|
"""Test the Wiki SQLAlchemy models."""
|
|
|
|
def test_wiki_article_model_fields(self):
|
|
"""WikiArticle model has all required fields."""
|
|
from app.plugins.builtins.wiki.models import WikiArticle
|
|
|
|
assert hasattr(WikiArticle, "title")
|
|
assert hasattr(WikiArticle, "slug")
|
|
assert hasattr(WikiArticle, "content")
|
|
assert hasattr(WikiArticle, "content_html")
|
|
assert hasattr(WikiArticle, "summary")
|
|
assert hasattr(WikiArticle, "category_id")
|
|
assert hasattr(WikiArticle, "tags")
|
|
assert hasattr(WikiArticle, "status")
|
|
assert hasattr(WikiArticle, "entity_links")
|
|
assert hasattr(WikiArticle, "version")
|
|
assert hasattr(WikiArticle, "published_at")
|
|
assert hasattr(WikiArticle, "tenant_id")
|
|
assert hasattr(WikiArticle, "owner_id")
|
|
|
|
def test_wiki_category_model_fields(self):
|
|
"""WikiCategory model has all required fields."""
|
|
from app.plugins.builtins.wiki.models import WikiCategory
|
|
|
|
assert hasattr(WikiCategory, "name")
|
|
assert hasattr(WikiCategory, "slug")
|
|
assert hasattr(WikiCategory, "description")
|
|
assert hasattr(WikiCategory, "parent_id")
|
|
assert hasattr(WikiCategory, "sort_order")
|
|
assert hasattr(WikiCategory, "tenant_id")
|
|
|
|
def test_wiki_article_version_model_fields(self):
|
|
"""WikiArticleVersion model has all required fields."""
|
|
from app.plugins.builtins.wiki.models import WikiArticleVersion
|
|
|
|
assert hasattr(WikiArticleVersion, "article_id")
|
|
assert hasattr(WikiArticleVersion, "version")
|
|
assert hasattr(WikiArticleVersion, "title")
|
|
assert hasattr(WikiArticleVersion, "content")
|
|
assert hasattr(WikiArticleVersion, "edited_by")
|
|
assert hasattr(WikiArticleVersion, "edit_comment")
|
|
assert hasattr(WikiArticleVersion, "tenant_id")
|
|
|
|
def test_models_have_tenant_mixin(self):
|
|
"""All Wiki models have tenant_id (TenantMixin)."""
|
|
from app.plugins.builtins.wiki.models import WikiArticle, WikiCategory, WikiArticleVersion
|
|
|
|
for model in [WikiArticle, WikiCategory, WikiArticleVersion]:
|
|
assert hasattr(model, "tenant_id")
|
|
|
|
|
|
class TestWikiServices:
|
|
"""Test the Wiki service helper functions."""
|
|
|
|
def test_slugify(self):
|
|
"""_slugify converts text to URL-safe slug."""
|
|
from app.plugins.builtins.wiki.services import _slugify
|
|
|
|
assert _slugify("Hello World") == "hello-world"
|
|
assert _slugify("Überblick") == "ueberblick"
|
|
assert _slugify("Test Article 123") == "test-article-123"
|