Files
cmshoppe/tests/test_product_suite_gui.py
T

282 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import sys
import unittest
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
sys.path.insert(0, os.path.dirname(__file__))
from _helpers import TempDirMixin
from app import accounts, appconfig, image_studio, image_studio_images
from app import gui
if gui.QT_IMPORT_ERROR is not None:
raise unittest.SkipTest("PySide6 未安装")
from PySide6.QtGui import QImage
from PySide6.QtWidgets import QApplication, QLabel, QPushButton
from app.gui.tabs.product_suite import ProductSuiteTab, SuiteResultCard
class ProductSuiteGuiTests(TempDirMixin, unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.app = QApplication.instance() or QApplication([])
def tearDown(self):
for widget in QApplication.topLevelWidgets():
widget.close()
widget.deleteLater()
self.app.processEvents()
def _config(self, temp_dir):
return {
"chrome_path": "chrome.exe",
"user_data_root": os.path.join(temp_dir, "chrome_user_data_dir"),
"image_dir": os.path.join(temp_dir, "images"),
"db_path": os.path.join(temp_dir, "cmshopee.db"),
"debug_port_range": [9222, 9260],
"config_path": os.path.join(temp_dir, "config.json"),
"cmhub_config_path": os.path.join(temp_dir, "cmhub.json"),
}
def _write_image(self, path):
image = QImage(40, 30, QImage.Format_RGB32)
image.fill(0xFF336699)
self.assertTrue(image.save(path))
def test_tab_builds_suite_controls_without_old_detail_workspace(self):
with self.make_temp_dir() as temp_dir:
config = self._config(temp_dir)
accounts.create_account("主店", "alias-a", debug_port=9222, config=config)
tab = ProductSuiteTab(config=config, db_path=config["db_path"])
self.addCleanup(tab.close)
tab.resize(1180, 760)
tab.show()
self.app.processEvents()
self.assertEqual("productSuiteTab", tab.objectName())
self.assertEqual(1, tab.task_tabs.count())
self.assertEqual("套图任务 1", tab.task_tabs.tabText(0))
self.assertEqual("alias-a", tab.account_combo.currentData())
self.assertEqual("Shopee", tab.platform_combo.currentData())
self.assertEqual("中国台湾", tab.country_combo.currentData())
self.assertEqual("繁体中文", tab.language_combo.currentData())
self.assertEqual("1:1", tab.ratio_combo.currentData())
self.assertEqual("Shopee", tab.platform_combo.currentText())
self.assertEqual("中国台湾", tab.country_combo.currentText())
self.assertEqual("繁体中文", tab.language_combo.currentText())
self.assertEqual("1:1", tab.ratio_combo.currentText())
self.assertEqual("平台", tab.platform_label.text())
self.assertEqual("站点", tab.country_label.text())
self.assertEqual("语言", tab.language_label.text())
self.assertEqual("比例", tab.ratio_label.text())
for column, combo in enumerate(
(
tab.platform_combo,
tab.country_combo,
tab.language_combo,
tab.ratio_combo,
)
):
self.assertIs(combo, tab.settings_grid.itemAtPosition(1, column).widget())
self.assertEqual(
1,
len(
{
tab.platform_combo.width(),
tab.country_combo.width(),
tab.language_combo.width(),
tab.ratio_combo.width(),
}
),
)
self.assertLessEqual(tab.task_tabs.maximumHeight(), 36)
self.assertEqual(120, tab.account_combo.minimumWidth())
self.assertEqual(160, tab.account_combo.maximumWidth())
self.assertGreaterEqual(tab.item_id_edit.minimumWidth(), 120)
self.assertLessEqual(tab.item_id_edit.maximumWidth(), 140)
self.assertLess(
tab.context_bar_layout.indexOf(tab.history_button),
tab.context_bar_layout.indexOf(tab.account_combo),
)
self.assertLess(
tab.context_bar_layout.indexOf(tab.open_folder_button),
tab.context_bar_layout.indexOf(tab.account_combo),
)
self.assertLess(
tab.context_bar_layout.indexOf(tab.add_images_button),
tab.context_bar_layout.indexOf(tab.account_combo),
)
self.assertEqual(-1, tab.results_toolbar_layout.indexOf(tab.history_button))
self.assertEqual(-1, tab.results_toolbar_layout.indexOf(tab.open_folder_button))
self.assertEqual("打开结果文件夹", tab.open_folder_button.text())
self.assertEqual("合计 5 张", tab.category_total_label.text())
self.assertEqual("生成套图(5)", tab.generate_button.text())
visible_text = " ".join(
[widget.text() for widget in tab.findChildren(QLabel)]
+ [widget.text() for widget in tab.findChildren(QPushButton)]
)
self.assertNotIn("详情图", visible_text)
self.assertNotIn("AI工场", visible_text)
self.assertIn("白底图", visible_text)
self.assertIn("场景图", visible_text)
self.assertIn("卖点图", visible_text)
tab.add_custom_category()
self.assertFalse(tab.custom_category_edit.isHidden())
tab.custom_category_edit.setText("尺寸图")
tab._commit_custom_category()
self.assertTrue(tab.custom_category_edit.isHidden())
self.assertIn("尺寸图", tab._displayed_state.settings["categories"])
self.assertEqual("尺寸图", tab._displayed_state.active_category)
self.assert_removed(temp_dir)
def test_recent_dropdown_settings_restore_after_restart_and_project_wins(self):
with self.make_temp_dir() as temp_dir:
config_path = os.path.join(temp_dir, "config.json")
config = appconfig.save_config(self._config(temp_dir), path=config_path)
account = accounts.create_account(
"主店",
"alias-a",
debug_port=9222,
config=config,
)
project = image_studio.create_or_get_project(
account,
item_id="51100639510",
path=config["db_path"],
)
project_settings = image_studio.project_suite_settings(project)
project_settings["ratio"] = "4:3"
image_studio.update_project_suite_settings(
project.id,
project_settings,
path=config["db_path"],
)
first = ProductSuiteTab(
config=config,
config_path=config_path,
db_path=config["db_path"],
)
first.ratio_combo.setCurrentIndex(first.ratio_combo.findData("16:9"))
self.assertEqual(
"16:9",
appconfig.product_suite_last_settings(
appconfig.load_config(config_path)
)["ratio"],
)
first.close()
first.deleteLater()
self.app.processEvents()
reloaded = appconfig.load_config(config_path)
second = ProductSuiteTab(
config=reloaded,
config_path=config_path,
db_path=reloaded["db_path"],
)
self.addCleanup(second.close)
self.assertEqual("16:9", second.ratio_combo.currentData())
state = second._displayed_state
state.account_alias = "alias-a"
state.item_id = "51100639510"
second._bind_project(state, load_existing=True)
self.assertEqual("4:3", second.ratio_combo.currentData())
self.assertEqual("4:3", state.settings["ratio"])
self.assert_removed(temp_dir)
def test_task_tabs_keep_independent_prompt_and_settings(self):
with self.make_temp_dir() as temp_dir:
config = self._config(temp_dir)
accounts.create_account("主店", "alias-a", debug_port=9222, config=config)
tab = ProductSuiteTab(config=config, db_path=config["db_path"])
self.addCleanup(tab.close)
tab.prompt_edit.setPlainText("任务一卖点")
first_state = tab._displayed_state
tab.ratio_combo.setCurrentIndex(tab.ratio_combo.findData("3:4"))
second_state = tab.add_task(inherit=True)
self.assertEqual(2, tab.task_tabs.count())
self.assertEqual("任务一卖点", second_state.prompt)
self.assertEqual("3:4", second_state.settings["ratio"])
tab.prompt_edit.setPlainText("任务二卖点")
tab.ratio_combo.setCurrentIndex(tab.ratio_combo.findData("16:9"))
tab.task_tabs.setCurrentIndex(0)
self.assertIs(first_state, tab._displayed_state)
self.assertEqual("任务一卖点", tab.prompt_edit.toPlainText())
self.assertEqual("3:4", tab.ratio_combo.currentData())
self.assert_removed(temp_dir)
def test_project_settings_and_result_history_use_existing_backend(self):
with self.make_temp_dir() as temp_dir:
config = self._config(temp_dir)
account = accounts.create_account("主店", "alias-a", debug_port=9222, config=config)
project = image_studio.create_or_get_project(
account,
item_id="51100639510",
path=config["db_path"],
)
source_path = os.path.join(temp_dir, "source.png")
self._write_image(source_path)
source = image_studio_images.import_original_files(
project.id,
[source_path],
path=config["db_path"],
config=config,
)["assets"][0]
job = image_studio.create_job(
project.id,
source_asset_id=source.id,
job_type="场景图",
prompt="场景卖点",
path=config["db_path"],
)
image_studio.update_job_status(
job.id,
"failed",
error="上游超时 https://example.invalid/private",
path=config["db_path"],
)
tab = ProductSuiteTab(config=config, db_path=config["db_path"])
self.addCleanup(tab.close)
state = tab._displayed_state
state.account_alias = "alias-a"
state.item_id = "51100639510"
state.project_id = project.id
state.current_job_ids = [job.id]
tab._load_state(state)
self.assertEqual([source.id], tab.original_list.asset_ids())
self.assertEqual("共 1 张 · 成功 0 张", tab.result_summary_label.text())
cards = tab.findChildren(SuiteResultCard)
self.assertEqual(1, len(cards))
self.assertNotIn(
"https://",
" ".join(label.text() for label in cards[0].findChildren(QLabel)),
)
state.settings["ratio"] = "4:3"
state.prompt = "持久化卖点"
tab._persist_state(state)
stored = image_studio.get_project(project.id, path=config["db_path"])
self.assertEqual("持久化卖点", stored.draft_prompt)
self.assertEqual("4:3", image_studio.project_suite_settings(stored)["ratio"])
self.assert_removed(temp_dir)
if __name__ == "__main__":
unittest.main()