fix(douyin): require explicit self-declaration
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# Language: 中文
|
||||
import asyncio
|
||||
import unittest
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
from uploader.douyin_uploader import main as douyin_main
|
||||
from uploader.douyin_uploader.main import DouYinVideo
|
||||
|
||||
|
||||
class DouyinDeclarationTests(unittest.TestCase):
|
||||
def test_upload_only_sets_explicit_declaration(self):
|
||||
video = DouYinVideo(
|
||||
"标题", "/tmp/demo.mp4", [], 0, "/tmp/cookie.json",
|
||||
declaration="已确认声明原文",
|
||||
)
|
||||
self.assertEqual(video.declaration, "已确认声明原文")
|
||||
|
||||
def test_missing_declaration_does_not_fall_back_to_personal_opinion(self):
|
||||
video = DouYinVideo("标题", "/tmp/demo.mp4", [], 0, "/tmp/cookie.json")
|
||||
self.assertIsNone(video.declaration)
|
||||
|
||||
def test_legacy_positional_runtime_flags_keep_their_meaning(self):
|
||||
video = DouYinVideo(
|
||||
"标题", "/tmp/demo.mp4", [], 0, "/tmp/cookie.json",
|
||||
None, "", "", None, "",
|
||||
"scheduled", False, False,
|
||||
)
|
||||
self.assertEqual(video.publish_strategy, "scheduled")
|
||||
self.assertFalse(video.debug)
|
||||
self.assertFalse(video.headless)
|
||||
self.assertIsNone(video.declaration)
|
||||
|
||||
def test_apply_declaration_skips_when_unspecified(self):
|
||||
video = DouYinVideo("标题", "/tmp/demo.mp4", [], 0, "/tmp/cookie.json")
|
||||
video.set_self_declaration = AsyncMock()
|
||||
asyncio.run(video.apply_self_declaration(object()))
|
||||
video.set_self_declaration.assert_not_awaited()
|
||||
|
||||
def test_apply_declaration_uses_exact_explicit_text(self):
|
||||
page = object()
|
||||
video = DouYinVideo(
|
||||
"标题", "/tmp/demo.mp4", [], 0, "/tmp/cookie.json",
|
||||
declaration="已确认声明原文",
|
||||
)
|
||||
video.set_self_declaration = AsyncMock(return_value=True)
|
||||
asyncio.run(video.apply_self_declaration(page))
|
||||
video.set_self_declaration.assert_awaited_once_with(page, "已确认声明原文")
|
||||
|
||||
def test_explicit_declaration_failure_blocks_publish(self):
|
||||
video = DouYinVideo(
|
||||
"标题", "/tmp/demo.mp4", [], 0, "/tmp/cookie.json",
|
||||
declaration="已确认声明原文",
|
||||
)
|
||||
video.set_self_declaration = AsyncMock(return_value=False)
|
||||
with self.assertRaisesRegex(RuntimeError, "自主声明"):
|
||||
asyncio.run(video.apply_self_declaration(object()))
|
||||
|
||||
def test_declaration_failure_closes_browser_resources(self):
|
||||
video = DouYinVideo(
|
||||
"标题", "/tmp/demo.mp4", [], 0, "/tmp/cookie.json",
|
||||
declaration="已确认声明原文",
|
||||
)
|
||||
video.validate_upload_args = AsyncMock()
|
||||
video.fill_title_and_description = AsyncMock()
|
||||
video.set_thumbnail = AsyncMock()
|
||||
video.apply_self_declaration = AsyncMock(side_effect=RuntimeError("抖音自主声明设置失败"))
|
||||
|
||||
locator = MagicMock()
|
||||
locator.set_input_files = AsyncMock()
|
||||
locator.count = AsyncMock(return_value=1)
|
||||
page = MagicMock()
|
||||
page.goto = AsyncMock()
|
||||
page.wait_for_url = AsyncMock()
|
||||
page.wait_for_selector = AsyncMock()
|
||||
page.locator.return_value = locator
|
||||
|
||||
context = MagicMock()
|
||||
context.new_page = AsyncMock(return_value=page)
|
||||
context.close = AsyncMock(side_effect=OSError("close failed"))
|
||||
browser = MagicMock()
|
||||
browser.new_context = AsyncMock(return_value=context)
|
||||
browser.close = AsyncMock()
|
||||
playwright = MagicMock()
|
||||
playwright.chromium.launch = AsyncMock(return_value=browser)
|
||||
|
||||
with (
|
||||
patch.object(douyin_main, "set_init_script", AsyncMock(return_value=context)),
|
||||
patch.object(douyin_main.asyncio, "sleep", AsyncMock()),
|
||||
self.assertRaisesRegex(RuntimeError, "自主声明"),
|
||||
):
|
||||
asyncio.run(video.upload(playwright))
|
||||
|
||||
context.close.assert_awaited_once()
|
||||
browser.close.assert_awaited_once()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user