import os import sys import unittest from types import SimpleNamespace sys.path.insert(0, os.path.dirname(__file__)) from app import product_suite, prompts class ProductSuiteTests(unittest.TestCase): def test_defaults_and_per_image_total(self): settings = product_suite.default_suite_settings() self.assertEqual(["白底图", "场景图", "卖点图"], product_suite.category_order(settings)) self.assertEqual(5, product_suite.suite_total_count(settings, 3)) settings["per_image_primary"] = True self.assertEqual(13, product_suite.suite_total_count(settings, 3)) def test_custom_category_validation_and_normalization(self): self.assertEqual("分类名称不能为空", product_suite.suite_name_error("")) self.assertEqual("分类名称不能包含空格", product_suite.suite_name_error("使用 场景")) self.assertEqual("分类名称不能超过10个字", product_suite.suite_name_error("一二三四五六七八九十甲")) self.assertEqual("分类名称已存在", product_suite.suite_name_error("场景图", {"场景图"})) settings = product_suite.normalize_suite_settings( { "ratio": "3:4", "categories": {"白底图": 2, "场景图": 0, "卖点图": 1, "尺寸图": 2}, "custom_category_order": ["尺寸图"], } ) self.assertEqual("3:4", settings["ratio"]) self.assertEqual(["白底图", "场景图", "卖点图", "尺寸图"], product_suite.category_order(settings)) self.assertEqual(5, product_suite.suite_total_count(settings, 1)) def test_recent_settings_only_keep_allowed_dropdown_values(self): self.assertEqual( { "platform": "Shopee", "country": "中国台湾", "language": "繁体中文", "ratio": "1:1", }, product_suite.last_suite_settings( { "platform": "未知平台", "country": "未知站点", "language": "未知语言", "ratio": "2:3", "per_image_primary": True, "categories": {"白底图": 9}, } ), ) selected = product_suite.last_suite_settings( { "platform": "Amazon", "country": "新加坡", "language": "英文", "ratio": "4:3", } ) self.assertEqual("Amazon", selected["platform"]) self.assertEqual("新加坡", selected["country"]) self.assertEqual("英文", selected["language"]) self.assertEqual("4:3", selected["ratio"]) def test_job_specs_include_selected_context_and_source_assignment(self): settings = product_suite.default_suite_settings() settings.update( { "platform": "Shopee", "country": "中国台湾", "language": "繁体中文", "ratio": "4:3", "per_image_primary": True, "categories": {"白底图": 1, "场景图": 1, "卖点图": 0}, } ) assets = [SimpleNamespace(id=11), SimpleNamespace(id=12)] specs = product_suite.build_job_specs( assets, "40小时续航,适合通勤", settings, "51100639510", template_text=prompts.load_default_product_suite_prompt(), ) self.assertEqual(3, len(specs)) self.assertEqual([11, 11, 12], [spec["source_asset_id"] for spec in specs]) self.assertEqual(["白底图", "场景图", "场景图"], [spec["job_type"] for spec in specs]) for spec in specs: self.assertIn("平台:Shopee", spec["prompt"]) self.assertIn("国家地区:中国台湾", spec["prompt"]) self.assertIn("输出语言:繁体中文", spec["prompt"]) self.assertIn("本次生成比例:4:3", spec["prompt"]) self.assertNotIn("商品ID:51100639510", spec["prompt"]) self.assertIn("40小时续航", spec["prompt"]) self.assertIn("禁止海报长图、详情页长图和多宫格拼接版面", spec["prompt"]) self.assertIn("禁止在画面中出现任何国旗", spec["prompt"]) self.assertIn("当前上传图片是本任务唯一主参考图", spec["prompt"]) self.assertTrue( spec["prompt"].splitlines()[-1].startswith("本次生成比例:4:3") ) self.assertIn("套图名称:白底图,白底主图", specs[0]["prompt"]) self.assertIn("套图名称:场景图,生活化场景", specs[1]["prompt"]) white_prompt = specs[0]["prompt"] self.assertLess(white_prompt.index("重要尺寸要求"), white_prompt.index("重要禁用内容")) self.assertLess(white_prompt.index("重要禁用内容"), white_prompt.index("价格信息规则")) self.assertLess(white_prompt.index("价格信息规则"), white_prompt.index("尺码信息规则")) self.assertLess(white_prompt.index("尺码信息规则"), white_prompt.index("参考图规则")) self.assertLess(white_prompt.index("参考图规则"), white_prompt.index("商品卖点与要求")) def test_product_suite_template_validation_and_custom_category_rendering(self): default_text = prompts.load_default_product_suite_prompt() self.assertEqual([], product_suite.product_suite_prompt_errors(default_text)) unknown = default_text + "\n{未知变量}" self.assertIn("未知变量", ";".join(product_suite.product_suite_prompt_errors(unknown))) missing = default_text.replace("{图片比例}", "") self.assertIn( "缺少必需变量", ";".join(product_suite.product_suite_prompt_errors(missing)), ) inline_rule = default_text.replace( "{价格信息规则}", "价格:{价格信息规则}", ) self.assertIn( "只读规则变量必须独占一行", ";".join(product_suite.product_suite_prompt_errors(inline_rule)), ) literal_brace = default_text + "\n普通内容{" self.assertIn( "不支持的字面花括号", ";".join(product_suite.product_suite_prompt_errors(literal_brace)), ) settings = product_suite.default_suite_settings() context = product_suite.product_suite_prompt_context( "突出轻量材质", settings, "尺寸图", "draft_hidden", ) rendered = product_suite.render_product_suite_prompt(default_text, context) self.assertIn("套图名称:尺寸图", rendered) self.assertNotIn("draft_", rendered) self.assertNotIn("白底主图", rendered) def test_product_suite_optional_item_and_reference_variables(self): template = prompts.load_default_product_suite_prompt() + ( "\n商品ID:{商品ID}\n参考图序号:{主参考图序号}" ) context = product_suite.product_suite_prompt_context( "卖点", product_suite.default_suite_settings(), "卖点图", "", source_index=2, ) rendered = product_suite.render_product_suite_prompt(template, context) self.assertIn("商品ID:未绑定商品", rendered) self.assertIn("参考图序号:2", rendered) if __name__ == "__main__": unittest.main()