diff --git a/docker-compose.yml b/docker-compose.yml index b85a8df..8bdbf3c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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: . diff --git a/tests/client/cookbook/test_cookbook_api.py b/tests/client/cookbook/test_cookbook_api.py index 5151374..c94df2e 100644 --- a/tests/client/cookbook/test_cookbook_api.py +++ b/tests/client/cookbook/test_cookbook_api.py @@ -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 diff --git a/tests/conftest.py b/tests/conftest.py index 66fc606..3e898cc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -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) diff --git a/tests/fixtures/nginx.conf b/tests/fixtures/nginx.conf new file mode 100644 index 0000000..14298e8 --- /dev/null +++ b/tests/fixtures/nginx.conf @@ -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; + } + } +} diff --git a/tests/server/test_cookbook_mcp.py b/tests/server/test_cookbook_mcp.py index 286659e..e4c90a3 100644 --- a/tests/server/test_cookbook_mcp.py +++ b/tests/server/test_cookbook_mcp.py @@ -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} )