Merge branch 'refactor/backend-architecture' into development

This commit is contained in:
yangshilin
2026-03-18 17:18:23 +08:00
parent 2070a03d35
commit 48b70e1350
266 changed files with 12386 additions and 9690 deletions

View File

@@ -4,7 +4,7 @@ from unittest.mock import Mock, patch
from qcloud_cos.cos_exception import CosClientError, CosServiceError
from api.services.memoir_images.storage import (
from app.features.memoir.memoir_images.storage import (
CosDownloadUrlError,
CosUploadError,
TencentCosStorageService,
@@ -26,7 +26,7 @@ class MemoirImageStorageTest(unittest.TestCase):
},
clear=False,
)
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_from_env_reuses_singleton_for_same_config(self, client_cls):
TencentCosStorageService._instance = None
TencentCosStorageService._instance_config = None
@@ -38,7 +38,7 @@ class MemoirImageStorageTest(unittest.TestCase):
self.assertIs(first, second)
client_cls.assert_called_once()
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_upload_bytes_returns_persistent_cos_url(self, client_cls):
client = Mock()
client.put_object.return_value = {
@@ -66,7 +66,7 @@ class MemoirImageStorageTest(unittest.TestCase):
)
client.put_object.assert_called_once()
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_upload_bytes_normalizes_duplicate_appid_suffix_in_base_url(self, client_cls):
client = Mock()
client_cls.return_value = client
@@ -102,7 +102,7 @@ class MemoirImageStorageTest(unittest.TestCase):
"https://life-echo-dev-1319381411.cos.ap-shanghai.myqcloud.com/memoirs/u1/c1/0-demo.png",
)
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_get_download_url_returns_presigned_download_url(self, client_cls):
client = Mock()
client.get_presigned_download_url.return_value = "https://cos.example.com/0.png?q-sign-algorithm=sha1"
@@ -143,7 +143,7 @@ class MemoirImageStorageTest(unittest.TestCase):
self.assertEqual(key, "memoirs/u1/c1/0-demo.png")
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_upload_bytes_raises_cos_upload_error_on_client_error(self, client_cls):
client = Mock()
client.put_object.side_effect = CosClientError("network timeout")
@@ -162,7 +162,7 @@ class MemoirImageStorageTest(unittest.TestCase):
self.assertTrue(ctx.exception.retryable)
self.assertIsInstance(ctx.exception.__cause__, CosClientError)
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_upload_bytes_raises_non_retryable_on_403(self, client_cls):
client = Mock()
svc_error = CosServiceError("PUT", "AccessDenied", 403)
@@ -181,7 +181,7 @@ class MemoirImageStorageTest(unittest.TestCase):
self.assertFalse(ctx.exception.retryable)
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_get_download_url_raises_cos_download_url_error(self, client_cls):
client = Mock()
client.get_presigned_download_url.side_effect = CosClientError("dns failure")
@@ -208,11 +208,11 @@ class MemoirImageStorageTest(unittest.TestCase):
def test_is_retryable_returns_true_for_5xx_service_error(self):
self.assertTrue(_is_retryable_cos_error(CosServiceError("GET", "Internal", 500)))
@patch("api.services.memoir_images.storage.CosS3Client")
@patch("app.features.memoir.memoir_images.storage.CosS3Client")
def test_cos_config_includes_scheme_and_token(self, client_cls):
client_cls.return_value = Mock()
with patch("api.services.memoir_images.storage.CosConfig") as config_cls:
with patch("app.features.memoir.memoir_images.storage.CosConfig") as config_cls:
TencentCosStorageService(
secret_id="id",
secret_key="key",