diff --git a/apps/api/plane/tests/conftest.py b/apps/api/plane/tests/conftest.py index 870779c42d62..f014abcc7a6f 100644 --- a/apps/api/plane/tests/conftest.py +++ b/apps/api/plane/tests/conftest.py @@ -6,6 +6,9 @@ from rest_framework.test import APIClient from pytest_django.fixtures import django_db_setup +# conftest_external is not a conftest.py, so pytest only sees its fixtures when imported here +from plane.tests.conftest_external import mock_celery, mock_redis # noqa: F401 + from plane.db.models import User, Workspace, WorkspaceMember from plane.db.models.api import APIToken diff --git a/apps/api/plane/tests/conftest_external.py b/apps/api/plane/tests/conftest_external.py index 16bc31a43062..d6f7f3530b13 100644 --- a/apps/api/plane/tests/conftest_external.py +++ b/apps/api/plane/tests/conftest_external.py @@ -28,29 +28,6 @@ def mock_redis(): yield mock_redis_client -@pytest.fixture -def mock_elasticsearch(): - """ - Mock Elasticsearch for testing without actual ES connection. - - This fixture patches Elasticsearch to return a MagicMock - that behaves like an Elasticsearch client. - """ - mock_es_client = MagicMock() - - # Configure the mock to handle common ES operations - mock_es_client.indices.exists.return_value = True - mock_es_client.indices.create.return_value = {"acknowledged": True} - mock_es_client.search.return_value = {"hits": {"total": {"value": 0}, "hits": []}} - mock_es_client.index.return_value = {"_id": "test_id", "result": "created"} - mock_es_client.update.return_value = {"_id": "test_id", "result": "updated"} - mock_es_client.delete.return_value = {"_id": "test_id", "result": "deleted"} - - # Start the patch - with patch("elasticsearch.Elasticsearch", return_value=mock_es_client): - yield mock_es_client - - @pytest.fixture def mock_celery(): """ diff --git a/apps/api/plane/tests/unit/test_external_fixtures.py b/apps/api/plane/tests/unit/test_external_fixtures.py new file mode 100644 index 000000000000..e0e6d9427d5b --- /dev/null +++ b/apps/api/plane/tests/unit/test_external_fixtures.py @@ -0,0 +1,22 @@ +# Copyright (c) 2023-present Plane Software, Inc. and contributors +# SPDX-License-Identifier: AGPL-3.0-only +# See the LICENSE file for details. + +from unittest.mock import MagicMock + +import pytest +from celery.app.task import Task + +from plane.settings import redis as redis_settings + + +@pytest.mark.unit +def test_mock_redis_patches_redis_instance(mock_redis): + assert isinstance(mock_redis, MagicMock) + assert redis_settings.redis_instance() is mock_redis + + +@pytest.mark.unit +def test_mock_celery_patches_task_delay(mock_celery): + assert Task.delay is mock_celery + assert Task.delay().id == "mock-task-id" diff --git a/apps/api/run_tests.sh b/apps/api/run_tests.sh index 7e22479b57e5..18ca77c75931 100755 --- a/apps/api/run_tests.sh +++ b/apps/api/run_tests.sh @@ -1,4 +1,6 @@ #!/bin/bash -# This is a simple wrapper script that calls the main test runner in the tests directory -exec tests/run_tests.sh "$@" \ No newline at end of file +# Thin wrapper around run_tests.py; run from apps/api so pytest.ini and test paths resolve, +# and through uv so `python` is the project venv (uv run syncs inexactly, safe in the dev/test images) +cd "$(dirname "$0")" || exit 1 +exec uv run python run_tests.py "$@" diff --git a/deployments/cli/community/docker-compose.yml b/deployments/cli/community/docker-compose.yml index 0ebd5dbc8ab8..eb181bc61f67 100644 --- a/deployments/cli/community/docker-compose.yml +++ b/deployments/cli/community/docker-compose.yml @@ -55,12 +55,13 @@ x-app-env: &app-env WEB_URL: ${WEB_URL:-http://localhost} DEBUG: ${DEBUG:-0} CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS} - GUNICORN_WORKERS: 1 + GUNICORN_WORKERS: ${GUNICORN_WORKERS:-1} USE_MINIO: ${USE_MINIO:-1} DATABASE_URL: ${DATABASE_URL:-postgresql://plane:plane@plane-db/plane} SECRET_KEY: ${SECRET_KEY} AMQP_URL: ${AMQP_URL:-amqp://plane:plane@plane-mq:5672/plane} API_KEY_RATE_LIMIT: ${API_KEY_RATE_LIMIT:-60/minute} + AUTHENTICATION_RATE_LIMIT: ${AUTHENTICATION_RATE_LIMIT:-10/minute} NUM_PROXIES: ${NUM_PROXIES:-} MINIO_ENDPOINT_SSL: ${MINIO_ENDPOINT_SSL:-0} LIVE_SERVER_SECRET_KEY: ${LIVE_SERVER_SECRET_KEY} diff --git a/deployments/cli/community/variables.env b/deployments/cli/community/variables.env index f1e396366cab..8c5680c6523b 100644 --- a/deployments/cli/community/variables.env +++ b/deployments/cli/community/variables.env @@ -79,9 +79,6 @@ FILE_SIZE_LIMIT=5242880 # Gunicorn Workers GUNICORN_WORKERS=1 -# UNCOMMENT `DOCKER_PLATFORM` IF YOU ARE ON `ARM64` AND DOCKER IMAGE IS NOT AVAILABLE FOR RESPECTIVE `APP_RELEASE` -# DOCKER_PLATFORM=linux/amd64 - # Force HTTPS for handling SSL Termination MINIO_ENDPOINT_SSL=0 diff --git a/deployments/swarm/community/swarm.sh b/deployments/swarm/community/swarm.sh index be119a2ad4d8..2249c9ea6520 100755 --- a/deployments/swarm/community/swarm.sh +++ b/deployments/swarm/community/swarm.sh @@ -584,7 +584,7 @@ function askForAction() { echo " 7) Exit" echo read -p "Action [3]: " ACTION - until [[ -z "$ACTION" || "$ACTION" =~ ^[1-6]$ ]]; do + until [[ -z "$ACTION" || "$ACTION" =~ ^[1-7]$ ]]; do echo "$ACTION: invalid selection." read -p "Action [3]: " ACTION done