128 lines
3.6 KiB
Python
128 lines
3.6 KiB
Python
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.api.v1 import task_actions
|
|
from app.core.response import CloverHTTPException
|
|
from app.services.fission_service import _source_copy_from_payload
|
|
|
|
|
|
class _Query:
|
|
def __init__(self, rows):
|
|
self._rows = rows
|
|
|
|
def filter(self, *args, **kwargs):
|
|
return self
|
|
|
|
def all(self):
|
|
return self._rows
|
|
|
|
def count(self):
|
|
return len(self._rows)
|
|
|
|
|
|
class _Db:
|
|
def __init__(self, text_rows, image_rows):
|
|
self._queries = [_Query(text_rows), _Query(image_rows)]
|
|
|
|
def query(self, *args, **kwargs):
|
|
return self._queries.pop(0)
|
|
|
|
|
|
class _Task:
|
|
id = 7
|
|
image_count = 3
|
|
|
|
|
|
def test_submit_review_requires_at_least_one_text_and_one_image():
|
|
db = _Db(text_rows=[], image_rows=[])
|
|
|
|
with pytest.raises(CloverHTTPException) as exc:
|
|
task_actions._validate_strategy_selection(db, _Task())
|
|
|
|
assert "请至少选择 1 条文案" in exc.value.biz_message
|
|
assert "请至少选择 1 张图片" in exc.value.biz_message
|
|
|
|
|
|
def test_submit_review_requires_at_least_one_image():
|
|
db = _Db(text_rows=[("A",)], image_rows=[])
|
|
|
|
with pytest.raises(CloverHTTPException) as exc:
|
|
task_actions._validate_strategy_selection(db, _Task())
|
|
|
|
assert exc.value.biz_message == "请至少选择 1 张图片"
|
|
|
|
|
|
def test_submit_review_requires_at_least_one_text():
|
|
db = _Db(text_rows=[], image_rows=[("A", 1)])
|
|
|
|
with pytest.raises(CloverHTTPException) as exc:
|
|
task_actions._validate_strategy_selection(db, _Task())
|
|
|
|
assert exc.value.biz_message == "请至少选择 1 条文案"
|
|
|
|
|
|
def test_submit_review_passes_with_one_text_and_one_image():
|
|
db = _Db(text_rows=[("B",)], image_rows=[("C", 7)])
|
|
|
|
task_actions._validate_strategy_selection(db, _Task())
|
|
|
|
|
|
def test_submit_review_does_not_require_all_strategies_or_full_image_count():
|
|
db = _Db(
|
|
text_rows=[("A",)],
|
|
image_rows=[("B", 4)],
|
|
)
|
|
|
|
task_actions._validate_strategy_selection(db, _Task())
|
|
|
|
|
|
def test_fission_source_extracts_copy_body_from_json_candidate():
|
|
payload = json.dumps({
|
|
"title": "早八伪素颜",
|
|
"content": "通勤前快速提亮,不卡粉。",
|
|
"selling_points": ["黄皮友好", "妆感轻"],
|
|
}, ensure_ascii=False)
|
|
|
|
source = _source_copy_from_payload(payload)
|
|
|
|
assert "早八伪素颜" in source
|
|
assert "通勤前快速提亮" in source
|
|
assert "selling_points" not in source
|
|
assert "{" not in source
|
|
|
|
|
|
def test_delivery_status_get_is_read_only_contract():
|
|
from app.api.v1 import delivery
|
|
|
|
assert "commit" not in delivery.get_package_download.__code__.co_names
|
|
assert "commit" not in delivery.download_package_file.__code__.co_names
|
|
assert "commit" in delivery.mark_package_downloaded.__code__.co_names
|
|
|
|
|
|
def test_workspace_switch_response_includes_role_contract():
|
|
from app.api.v1 import workspaces
|
|
|
|
constants = workspaces.switch_workspace.__code__.co_consts
|
|
|
|
assert ("current_workspace_id", "role", "token") in constants
|
|
|
|
|
|
def test_production_cors_filters_wildcard():
|
|
source = Path("main.py").read_text()
|
|
|
|
assert "CORS_ALLOW_ORIGINS" in Path("app/core/config.py").read_text()
|
|
assert 'origin != "*"' in source
|
|
assert "allow_origins=_cors_origins()" in source
|
|
|
|
|
|
def test_production_rejects_default_seed_password_contract():
|
|
source = Path("app/services/auth_service.py").read_text()
|
|
seed_source = Path("scripts/seed_data.py").read_text()
|
|
|
|
assert 'DEFAULT_SEED_PASSWORD = "Clover2026!"' in source
|
|
assert 'APP_ENV == "production"' in source
|
|
assert "默认密码已禁用" in source
|
|
assert "Production seed requires CLOVER_SEED_PASSWORD" in seed_source
|