mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
Merge remote-tracking branch 'origin/main' into feat/queue-based-graph-engine
This commit is contained in:
@ -8,7 +8,7 @@ from yarl import URL
|
||||
from configs.app_config import DifyConfig
|
||||
|
||||
|
||||
def test_dify_config(monkeypatch):
|
||||
def test_dify_config(monkeypatch: pytest.MonkeyPatch):
|
||||
# clear system environment variables
|
||||
os.environ.clear()
|
||||
|
||||
@ -48,7 +48,7 @@ def test_dify_config(monkeypatch):
|
||||
|
||||
# NOTE: If there is a `.env` file in your Workspace, this test might not succeed as expected.
|
||||
# This is due to `pymilvus` loading all the variables from the `.env` file into `os.environ`.
|
||||
def test_flask_configs(monkeypatch):
|
||||
def test_flask_configs(monkeypatch: pytest.MonkeyPatch):
|
||||
flask_app = Flask("app")
|
||||
# clear system environment variables
|
||||
os.environ.clear()
|
||||
@ -101,7 +101,7 @@ def test_flask_configs(monkeypatch):
|
||||
assert str(URL(str(config["CODE_EXECUTION_ENDPOINT"])) / "v1") == "http://127.0.0.1:8194/v1"
|
||||
|
||||
|
||||
def test_inner_api_config_exist(monkeypatch):
|
||||
def test_inner_api_config_exist(monkeypatch: pytest.MonkeyPatch):
|
||||
# Set environment variables using monkeypatch
|
||||
monkeypatch.setenv("CONSOLE_API_URL", "https://example.com")
|
||||
monkeypatch.setenv("CONSOLE_WEB_URL", "https://example.com")
|
||||
@ -119,7 +119,7 @@ def test_inner_api_config_exist(monkeypatch):
|
||||
assert len(config.INNER_API_KEY) > 0
|
||||
|
||||
|
||||
def test_db_extras_options_merging(monkeypatch):
|
||||
def test_db_extras_options_merging(monkeypatch: pytest.MonkeyPatch):
|
||||
"""Test that DB_EXTRAS options are properly merged with default timezone setting"""
|
||||
# Set environment variables
|
||||
monkeypatch.setenv("DB_USERNAME", "postgres")
|
||||
@ -164,7 +164,13 @@ def test_db_extras_options_merging(monkeypatch):
|
||||
],
|
||||
)
|
||||
def test_celery_broker_url_with_special_chars_password(
|
||||
monkeypatch, broker_url, expected_host, expected_port, expected_username, expected_password, expected_db
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
broker_url,
|
||||
expected_host,
|
||||
expected_port,
|
||||
expected_username,
|
||||
expected_password,
|
||||
expected_db,
|
||||
):
|
||||
"""Test that CELERY_BROKER_URL with various formats are handled correctly."""
|
||||
from kombu.utils.url import parse_url
|
||||
|
||||
0
api/tests/unit_tests/extensions/storage/__init__.py
Normal file
0
api/tests/unit_tests/extensions/storage/__init__.py
Normal file
313
api/tests/unit_tests/extensions/storage/test_supabase_storage.py
Normal file
313
api/tests/unit_tests/extensions/storage/test_supabase_storage.py
Normal file
@ -0,0 +1,313 @@
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from extensions.storage.supabase_storage import SupabaseStorage
|
||||
|
||||
|
||||
class TestSupabaseStorage:
|
||||
"""Test suite for SupabaseStorage class."""
|
||||
|
||||
def test_init_success_with_all_config(self):
|
||||
"""Test successful initialization when all required config is provided."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with patch("extensions.storage.supabase_storage.Client") as mock_client_class:
|
||||
mock_client = Mock()
|
||||
mock_client_class.return_value = mock_client
|
||||
|
||||
# Mock bucket_exists to return True so create_bucket is not called
|
||||
with patch.object(SupabaseStorage, "bucket_exists", return_value=True):
|
||||
storage = SupabaseStorage()
|
||||
|
||||
assert storage.bucket_name == "test-bucket"
|
||||
mock_client_class.assert_called_once_with(
|
||||
supabase_url="https://test.supabase.co", supabase_key="test-api-key"
|
||||
)
|
||||
|
||||
def test_init_raises_error_when_url_missing(self):
|
||||
"""Test initialization raises ValueError when SUPABASE_URL is None."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = None
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with pytest.raises(ValueError, match="SUPABASE_URL is not set"):
|
||||
SupabaseStorage()
|
||||
|
||||
def test_init_raises_error_when_api_key_missing(self):
|
||||
"""Test initialization raises ValueError when SUPABASE_API_KEY is None."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = None
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with pytest.raises(ValueError, match="SUPABASE_API_KEY is not set"):
|
||||
SupabaseStorage()
|
||||
|
||||
def test_init_raises_error_when_bucket_name_missing(self):
|
||||
"""Test initialization raises ValueError when SUPABASE_BUCKET_NAME is None."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = None
|
||||
|
||||
with pytest.raises(ValueError, match="SUPABASE_BUCKET_NAME is not set"):
|
||||
SupabaseStorage()
|
||||
|
||||
def test_create_bucket_when_not_exists(self):
|
||||
"""Test create_bucket creates bucket when it doesn't exist."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with patch("extensions.storage.supabase_storage.Client") as mock_client_class:
|
||||
mock_client = Mock()
|
||||
mock_client_class.return_value = mock_client
|
||||
|
||||
with patch.object(SupabaseStorage, "bucket_exists", return_value=False):
|
||||
storage = SupabaseStorage()
|
||||
|
||||
mock_client.storage.create_bucket.assert_called_once_with(id="test-bucket", name="test-bucket")
|
||||
|
||||
def test_create_bucket_when_exists(self):
|
||||
"""Test create_bucket does not create bucket when it already exists."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with patch("extensions.storage.supabase_storage.Client") as mock_client_class:
|
||||
mock_client = Mock()
|
||||
mock_client_class.return_value = mock_client
|
||||
|
||||
with patch.object(SupabaseStorage, "bucket_exists", return_value=True):
|
||||
storage = SupabaseStorage()
|
||||
|
||||
mock_client.storage.create_bucket.assert_not_called()
|
||||
|
||||
@pytest.fixture
|
||||
def storage_with_mock_client(self):
|
||||
"""Fixture providing SupabaseStorage with mocked client."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with patch("extensions.storage.supabase_storage.Client") as mock_client_class:
|
||||
mock_client = Mock()
|
||||
mock_client_class.return_value = mock_client
|
||||
|
||||
with patch.object(SupabaseStorage, "bucket_exists", return_value=True):
|
||||
storage = SupabaseStorage()
|
||||
# Create fresh mock for each test
|
||||
mock_client.reset_mock()
|
||||
yield storage, mock_client
|
||||
|
||||
def test_save(self, storage_with_mock_client):
|
||||
"""Test save calls client.storage.from_(bucket).upload(path, data)."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
filename = "test.txt"
|
||||
data = b"test data"
|
||||
|
||||
storage.save(filename, data)
|
||||
|
||||
mock_client.storage.from_.assert_called_once_with("test-bucket")
|
||||
mock_client.storage.from_().upload.assert_called_once_with(filename, data)
|
||||
|
||||
def test_load_once_returns_bytes(self, storage_with_mock_client):
|
||||
"""Test load_once returns bytes."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
expected_data = b"test content"
|
||||
mock_client.storage.from_().download.return_value = expected_data
|
||||
|
||||
result = storage.load_once("test.txt")
|
||||
|
||||
assert result == expected_data
|
||||
# Verify the correct calls were made
|
||||
assert "test-bucket" in [call[0][0] for call in mock_client.storage.from_.call_args_list if call[0]]
|
||||
mock_client.storage.from_().download.assert_called_with("test.txt")
|
||||
|
||||
def test_load_stream_yields_chunks(self, storage_with_mock_client):
|
||||
"""Test load_stream yields chunks."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
test_data = b"test content for streaming"
|
||||
mock_client.storage.from_().download.return_value = test_data
|
||||
|
||||
result = storage.load_stream("test.txt")
|
||||
|
||||
assert isinstance(result, Generator)
|
||||
|
||||
# Collect all chunks
|
||||
chunks = list(result)
|
||||
|
||||
# Verify chunks contain the expected data
|
||||
assert b"".join(chunks) == test_data
|
||||
# Verify the correct calls were made
|
||||
assert "test-bucket" in [call[0][0] for call in mock_client.storage.from_.call_args_list if call[0]]
|
||||
mock_client.storage.from_().download.assert_called_with("test.txt")
|
||||
|
||||
def test_download_writes_bytes_to_disk(self, storage_with_mock_client, tmp_path):
|
||||
"""Test download writes expected bytes to disk."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
test_data = b"test file content"
|
||||
mock_client.storage.from_().download.return_value = test_data
|
||||
|
||||
target_file = tmp_path / "downloaded_file.txt"
|
||||
|
||||
storage.download("test.txt", str(target_file))
|
||||
|
||||
# Verify file was written with correct content
|
||||
assert target_file.read_bytes() == test_data
|
||||
# Verify the correct calls were made
|
||||
assert "test-bucket" in [call[0][0] for call in mock_client.storage.from_.call_args_list if call[0]]
|
||||
mock_client.storage.from_().download.assert_called_with("test.txt")
|
||||
|
||||
def test_exists_with_list_containing_items(self, storage_with_mock_client):
|
||||
"""Test exists returns True when list() returns items (using len() > 0)."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
# Mock list return with special object that has count() method
|
||||
mock_list_result = Mock()
|
||||
mock_list_result.count.return_value = 1
|
||||
mock_client.storage.from_().list.return_value = mock_list_result
|
||||
|
||||
result = storage.exists("test.txt")
|
||||
|
||||
assert result is True
|
||||
# from_ gets called during init too, so just check it was called with the right bucket
|
||||
assert "test-bucket" in [call[0][0] for call in mock_client.storage.from_.call_args_list if call[0]]
|
||||
mock_client.storage.from_().list.assert_called_with("test.txt")
|
||||
|
||||
def test_exists_with_count_method_greater_than_zero(self, storage_with_mock_client):
|
||||
"""Test exists returns True when list result has count() > 0."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
# Mock list return with count() method
|
||||
mock_list_result = Mock()
|
||||
mock_list_result.count.return_value = 1
|
||||
mock_client.storage.from_().list.return_value = mock_list_result
|
||||
|
||||
result = storage.exists("test.txt")
|
||||
|
||||
assert result is True
|
||||
# Verify the correct calls were made
|
||||
assert "test-bucket" in [call[0][0] for call in mock_client.storage.from_.call_args_list if call[0]]
|
||||
mock_client.storage.from_().list.assert_called_with("test.txt")
|
||||
mock_list_result.count.assert_called()
|
||||
|
||||
def test_exists_with_count_method_zero(self, storage_with_mock_client):
|
||||
"""Test exists returns False when list result has count() == 0."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
# Mock list return with count() method returning 0
|
||||
mock_list_result = Mock()
|
||||
mock_list_result.count.return_value = 0
|
||||
mock_client.storage.from_().list.return_value = mock_list_result
|
||||
|
||||
result = storage.exists("test.txt")
|
||||
|
||||
assert result is False
|
||||
# Verify the correct calls were made
|
||||
assert "test-bucket" in [call[0][0] for call in mock_client.storage.from_.call_args_list if call[0]]
|
||||
mock_client.storage.from_().list.assert_called_with("test.txt")
|
||||
mock_list_result.count.assert_called()
|
||||
|
||||
def test_exists_with_empty_list(self, storage_with_mock_client):
|
||||
"""Test exists returns False when list() returns empty list."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
# Mock list return with special object that has count() method returning 0
|
||||
mock_list_result = Mock()
|
||||
mock_list_result.count.return_value = 0
|
||||
mock_client.storage.from_().list.return_value = mock_list_result
|
||||
|
||||
result = storage.exists("test.txt")
|
||||
|
||||
assert result is False
|
||||
# Verify the correct calls were made
|
||||
assert "test-bucket" in [call[0][0] for call in mock_client.storage.from_.call_args_list if call[0]]
|
||||
mock_client.storage.from_().list.assert_called_with("test.txt")
|
||||
|
||||
def test_delete_calls_remove_with_filename(self, storage_with_mock_client):
|
||||
"""Test delete calls remove([...]) (some client versions require a list)."""
|
||||
storage, mock_client = storage_with_mock_client
|
||||
|
||||
filename = "test.txt"
|
||||
|
||||
storage.delete(filename)
|
||||
|
||||
mock_client.storage.from_.assert_called_once_with("test-bucket")
|
||||
mock_client.storage.from_().remove.assert_called_once_with(filename)
|
||||
|
||||
def test_bucket_exists_returns_true_when_bucket_found(self):
|
||||
"""Test bucket_exists returns True when bucket is found in list."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with patch("extensions.storage.supabase_storage.Client") as mock_client_class:
|
||||
mock_client = Mock()
|
||||
mock_client_class.return_value = mock_client
|
||||
|
||||
mock_bucket = Mock()
|
||||
mock_bucket.name = "test-bucket"
|
||||
mock_client.storage.list_buckets.return_value = [mock_bucket]
|
||||
storage = SupabaseStorage()
|
||||
result = storage.bucket_exists()
|
||||
|
||||
assert result is True
|
||||
assert mock_client.storage.list_buckets.call_count >= 1
|
||||
|
||||
def test_bucket_exists_returns_false_when_bucket_not_found(self):
|
||||
"""Test bucket_exists returns False when bucket is not found in list."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with patch("extensions.storage.supabase_storage.Client") as mock_client_class:
|
||||
mock_client = Mock()
|
||||
mock_client_class.return_value = mock_client
|
||||
|
||||
# Mock different bucket
|
||||
mock_bucket = Mock()
|
||||
mock_bucket.name = "different-bucket"
|
||||
mock_client.storage.list_buckets.return_value = [mock_bucket]
|
||||
mock_client.storage.create_bucket = Mock()
|
||||
|
||||
storage = SupabaseStorage()
|
||||
result = storage.bucket_exists()
|
||||
|
||||
assert result is False
|
||||
assert mock_client.storage.list_buckets.call_count >= 1
|
||||
|
||||
def test_bucket_exists_returns_false_when_no_buckets(self):
|
||||
"""Test bucket_exists returns False when no buckets exist."""
|
||||
with patch("extensions.storage.supabase_storage.dify_config") as mock_config:
|
||||
mock_config.SUPABASE_URL = "https://test.supabase.co"
|
||||
mock_config.SUPABASE_API_KEY = "test-api-key"
|
||||
mock_config.SUPABASE_BUCKET_NAME = "test-bucket"
|
||||
|
||||
with patch("extensions.storage.supabase_storage.Client") as mock_client_class:
|
||||
mock_client = Mock()
|
||||
mock_client_class.return_value = mock_client
|
||||
|
||||
mock_client.storage.list_buckets.return_value = []
|
||||
mock_client.storage.create_bucket = Mock()
|
||||
|
||||
storage = SupabaseStorage()
|
||||
result = storage.bucket_exists()
|
||||
|
||||
assert result is False
|
||||
assert mock_client.storage.list_buckets.call_count >= 1
|
||||
@ -43,28 +43,28 @@ def _get_test_app():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_request_receiver(monkeypatch) -> mock.Mock:
|
||||
def mock_request_receiver(monkeypatch: pytest.MonkeyPatch) -> mock.Mock:
|
||||
mock_log_request_started = mock.Mock()
|
||||
monkeypatch.setattr(ext_request_logging, "_log_request_started", mock_log_request_started)
|
||||
return mock_log_request_started
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_response_receiver(monkeypatch) -> mock.Mock:
|
||||
def mock_response_receiver(monkeypatch: pytest.MonkeyPatch) -> mock.Mock:
|
||||
mock_log_request_finished = mock.Mock()
|
||||
monkeypatch.setattr(ext_request_logging, "_log_request_finished", mock_log_request_finished)
|
||||
return mock_log_request_finished
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_logger(monkeypatch) -> logging.Logger:
|
||||
def mock_logger(monkeypatch: pytest.MonkeyPatch) -> logging.Logger:
|
||||
_logger = mock.MagicMock(spec=logging.Logger)
|
||||
monkeypatch.setattr(ext_request_logging, "logger", _logger)
|
||||
return _logger
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def enable_request_logging(monkeypatch):
|
||||
def enable_request_logging(monkeypatch: pytest.MonkeyPatch):
|
||||
monkeypatch.setattr(dify_config, "ENABLE_REQUEST_LOGGING", True)
|
||||
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
|
||||
|
||||
def test_naive_utc_now(monkeypatch):
|
||||
def test_naive_utc_now(monkeypatch: pytest.MonkeyPatch):
|
||||
tz_aware_utc_now = datetime.datetime.now(tz=datetime.UTC)
|
||||
|
||||
def _now_func(tz: datetime.timezone | None) -> datetime.datetime:
|
||||
|
||||
63
api/tests/unit_tests/libs/test_jwt_imports.py
Normal file
63
api/tests/unit_tests/libs/test_jwt_imports.py
Normal file
@ -0,0 +1,63 @@
|
||||
"""Test PyJWT import paths to catch changes in library structure."""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestPyJWTImports:
|
||||
"""Test PyJWT import paths used throughout the codebase."""
|
||||
|
||||
def test_invalid_token_error_import(self):
|
||||
"""Test that InvalidTokenError can be imported as used in login controller."""
|
||||
# This test verifies the import path used in controllers/web/login.py:2
|
||||
# If PyJWT changes this import path, this test will fail early
|
||||
try:
|
||||
from jwt import InvalidTokenError
|
||||
|
||||
# Verify it's the correct exception class
|
||||
assert issubclass(InvalidTokenError, Exception)
|
||||
|
||||
# Test that it can be instantiated
|
||||
error = InvalidTokenError("test error")
|
||||
assert str(error) == "test error"
|
||||
|
||||
except ImportError as e:
|
||||
pytest.fail(f"Failed to import InvalidTokenError from jwt: {e}")
|
||||
|
||||
def test_jwt_exceptions_import(self):
|
||||
"""Test that jwt.exceptions imports work as expected."""
|
||||
# Alternative import path that might be used
|
||||
try:
|
||||
# Verify it's the same class as the direct import
|
||||
from jwt import InvalidTokenError
|
||||
from jwt.exceptions import InvalidTokenError as InvalidTokenErrorAlt
|
||||
|
||||
assert InvalidTokenError is InvalidTokenErrorAlt
|
||||
|
||||
except ImportError as e:
|
||||
pytest.fail(f"Failed to import InvalidTokenError from jwt.exceptions: {e}")
|
||||
|
||||
def test_other_jwt_exceptions_available(self):
|
||||
"""Test that other common JWT exceptions are available."""
|
||||
# Test other exceptions that might be used in the codebase
|
||||
try:
|
||||
from jwt import DecodeError, ExpiredSignatureError, InvalidSignatureError
|
||||
|
||||
# Verify they are exception classes
|
||||
assert issubclass(DecodeError, Exception)
|
||||
assert issubclass(ExpiredSignatureError, Exception)
|
||||
assert issubclass(InvalidSignatureError, Exception)
|
||||
|
||||
except ImportError as e:
|
||||
pytest.fail(f"Failed to import JWT exceptions: {e}")
|
||||
|
||||
def test_jwt_main_functions_available(self):
|
||||
"""Test that main JWT functions are available."""
|
||||
try:
|
||||
from jwt import decode, encode
|
||||
|
||||
# Verify they are callable
|
||||
assert callable(decode)
|
||||
assert callable(encode)
|
||||
|
||||
except ImportError as e:
|
||||
pytest.fail(f"Failed to import JWT main functions: {e}")
|
||||
@ -143,7 +143,7 @@ def test_uuidv7_with_custom_timestamp():
|
||||
assert extracted_timestamp == custom_timestamp # Exact match for integer milliseconds
|
||||
|
||||
|
||||
def test_uuidv7_with_none_timestamp(monkeypatch):
|
||||
def test_uuidv7_with_none_timestamp(monkeypatch: pytest.MonkeyPatch):
|
||||
"""Test UUID generation with None timestamp uses current time."""
|
||||
mock_time = 1609459200
|
||||
mock_time_func = mock.Mock(return_value=mock_time)
|
||||
|
||||
@ -4,8 +4,8 @@ from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
from oss2 import Bucket # type: ignore
|
||||
from oss2.models import GetObjectResult, PutObjectResult # type: ignore
|
||||
from oss2 import Bucket
|
||||
from oss2.models import GetObjectResult, PutObjectResult
|
||||
|
||||
from tests.unit_tests.oss.__mock.base import (
|
||||
get_example_bucket,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from oss2 import Auth # type: ignore
|
||||
from oss2 import Auth
|
||||
|
||||
from extensions.storage.aliyun_oss_storage import AliyunOssStorage
|
||||
from tests.unit_tests.oss.__mock.aliyun_oss import setup_aliyun_oss_mock
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
from textwrap import dedent
|
||||
|
||||
import pytest
|
||||
from yaml import YAMLError # type: ignore
|
||||
from yaml import YAMLError
|
||||
|
||||
from core.tools.utils.yaml_utils import load_yaml_file
|
||||
|
||||
|
||||
Reference in New Issue
Block a user