test: Replace http server for recipes with nginx container
This commit is contained in:
+7
-2
@@ -39,8 +39,13 @@ services:
|
||||
- MYSQL_DATABASE=nextcloud
|
||||
- MYSQL_USER=nextcloud
|
||||
- MYSQL_HOST=db
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
|
||||
recipes:
|
||||
image: docker.io/library/nginx:alpine
|
||||
restart: always
|
||||
volumes:
|
||||
- ./tests/fixtures/test_recipe.html:/usr/share/nginx/html/test_recipe.html:ro
|
||||
- ./tests/fixtures/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
|
||||
mcp:
|
||||
build: .
|
||||
|
||||
@@ -153,21 +153,17 @@ async def test_cookbook_delete_nonexistent_recipe(nc_client: NextcloudClient):
|
||||
logger.info(f"Delete correctly failed with {e.response.status_code}")
|
||||
|
||||
|
||||
async def test_cookbook_import_recipe_from_url(
|
||||
nc_client: NextcloudClient, test_recipe_server: str
|
||||
):
|
||||
async def test_cookbook_import_recipe_from_url(nc_client: NextcloudClient):
|
||||
"""Test importing a recipe from a URL.
|
||||
|
||||
This is the key feature test - importing recipes from URLs using schema.org metadata.
|
||||
Uses a local test server to provide reliable, controlled test data.
|
||||
Uses an nginx container to serve reliable, controlled test data.
|
||||
"""
|
||||
|
||||
docker_host = "host.docker.internal"
|
||||
# Use the nginx container hostname within the Docker network
|
||||
test_url = "http://recipes/black-pepper-tofu"
|
||||
|
||||
docker_accessible_url = test_recipe_server.replace("localhost", docker_host)
|
||||
test_url = f"{docker_accessible_url}/black-pepper-tofu"
|
||||
|
||||
logger.info(f"Importing recipe from local test URL (Docker-accessible): {test_url}")
|
||||
logger.info(f"Importing recipe from nginx container: {test_url}")
|
||||
|
||||
try:
|
||||
imported_recipe = await nc_client.cookbook.import_recipe(test_url)
|
||||
@@ -205,7 +201,7 @@ async def test_cookbook_import_recipe_from_url(
|
||||
elif e.response.status_code == 400:
|
||||
# URL couldn't be imported
|
||||
logger.error(
|
||||
f"Failed to import recipe from local test URL: {test_url}. "
|
||||
f"Failed to import recipe from nginx container: {test_url}. "
|
||||
f"Status: {e.response.status_code}, Response: {e.response.text}"
|
||||
)
|
||||
raise
|
||||
|
||||
@@ -1319,77 +1319,3 @@ async def test_user_in_group(nc_client: NextcloudClient, test_user, test_group):
|
||||
logger.debug(f"Added user {user_config['userid']} to group {groupid}")
|
||||
|
||||
yield (user_config, groupid)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def test_recipe_server():
|
||||
"""
|
||||
Fixture to create a local HTTP server serving test recipe HTML pages.
|
||||
|
||||
This serves static HTML files with schema.org Recipe JSON-LD data for testing
|
||||
recipe import functionality without relying on external websites.
|
||||
|
||||
Yields the server URL (e.g., "http://localhost:8082")
|
||||
"""
|
||||
import threading
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
from pathlib import Path
|
||||
|
||||
httpd = None
|
||||
server_thread = None
|
||||
|
||||
# Get the path to the fixtures directory
|
||||
fixtures_dir = Path(__file__).parent / "fixtures"
|
||||
|
||||
class RecipeServerHandler(BaseHTTPRequestHandler):
|
||||
def log_message(self, format, *args):
|
||||
# Suppress default HTTP logging
|
||||
pass
|
||||
|
||||
def do_GET(self):
|
||||
# Map URL paths to fixture files
|
||||
if self.path == "/black-pepper-tofu":
|
||||
file_path = fixtures_dir / "test_recipe.html"
|
||||
else:
|
||||
# 404 for unknown paths
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
return
|
||||
|
||||
if file_path.exists():
|
||||
with open(file_path, "rb") as f:
|
||||
content = f.read()
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/html; charset=utf-8")
|
||||
self.send_header("Content-Length", str(len(content)))
|
||||
self.end_headers()
|
||||
self.wfile.write(content)
|
||||
else:
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
try:
|
||||
# Start the HTTP server on all interfaces (0.0.0.0) so Docker can reach it
|
||||
httpd = HTTPServer(("0.0.0.0", 8082), RecipeServerHandler)
|
||||
server_thread = threading.Thread(target=httpd.serve_forever)
|
||||
server_thread.daemon = True
|
||||
server_thread.start()
|
||||
logger.info(
|
||||
"Test recipe server started on http://0.0.0.0:8082 (accessible from Docker)"
|
||||
)
|
||||
|
||||
# Yield the server URL (use localhost for test code, will be replaced with Docker-accessible IP)
|
||||
yield "http://localhost:8082"
|
||||
|
||||
finally:
|
||||
# Clean up the server
|
||||
if httpd:
|
||||
logger.info("Shutting down test recipe server...")
|
||||
shutdown_thread = threading.Thread(target=httpd.shutdown)
|
||||
shutdown_thread.start()
|
||||
shutdown_thread.join(timeout=2)
|
||||
httpd.server_close()
|
||||
logger.info("Test recipe server shut down successfully")
|
||||
if server_thread:
|
||||
server_thread.join(timeout=1)
|
||||
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type text/html;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
try_files $uri $uri.html =404;
|
||||
}
|
||||
|
||||
# Serve test_recipe.html at /black-pepper-tofu
|
||||
location = /black-pepper-tofu {
|
||||
root /usr/share/nginx/html;
|
||||
try_files /test_recipe.html =404;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,25 +208,20 @@ async def test_mcp_cookbook_delete_recipe(
|
||||
async def test_mcp_cookbook_import_recipe_from_url(
|
||||
nc_mcp_client: ClientSession,
|
||||
nc_client: NextcloudClient,
|
||||
test_recipe_server: str,
|
||||
):
|
||||
"""Test importing a recipe from a URL via MCP tools.
|
||||
|
||||
This is the key feature test - importing recipes from URLs using schema.org metadata.
|
||||
Uses a local test server to provide reliable, controlled test data.
|
||||
Uses an nginx container to serve reliable, controlled test data.
|
||||
"""
|
||||
docker_host = "host.docker.internal"
|
||||
|
||||
docker_accessible_url = test_recipe_server.replace("localhost", docker_host)
|
||||
test_url = f"{docker_accessible_url}/black-pepper-tofu"
|
||||
# Use the nginx container hostname within the Docker network
|
||||
test_url = "http://recipes/black-pepper-tofu"
|
||||
|
||||
created_recipe_id = None
|
||||
|
||||
try:
|
||||
# 1. Import recipe via MCP
|
||||
logger.info(
|
||||
f"Importing recipe from local test URL via MCP (Docker-accessible): {test_url}"
|
||||
)
|
||||
logger.info(f"Importing recipe from nginx container via MCP: {test_url}")
|
||||
import_result = await nc_mcp_client.call_tool(
|
||||
"nc_cookbook_import_recipe", {"url": test_url}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user