test: Replace http server for recipes with nginx container

This commit is contained in:
Chris Coutinho
2025-10-17 04:30:03 +02:00
parent 2999d4b65e
commit 27519d0f62
5 changed files with 41 additions and 95 deletions
+7 -2
View File
@@ -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: .
+6 -10
View File
@@ -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
-74
View File
@@ -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)
+24
View File
@@ -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;
}
}
}
+4 -9
View File
@@ -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}
)