feat(settings): rename custom gateway models
This commit is contained in:
@@ -565,6 +565,48 @@ class AppConfigTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_rename_ai_model_preserves_fields_and_rejects_invalid_name(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
models_path = os.path.join(temp_dir, "ai_models.json")
|
||||
appconfig.add_ai_model(
|
||||
{
|
||||
"name": "Text 2",
|
||||
"category": "text",
|
||||
"enabled": False,
|
||||
"url": "https://example.invalid/v1/chat/completions",
|
||||
"model": "demo-model",
|
||||
"api_key": "sk-1234567890",
|
||||
"api_type": "chat",
|
||||
"connect_timeout_seconds": 12,
|
||||
"timeout_seconds": 45,
|
||||
"extra_body": {"temperature": 0},
|
||||
},
|
||||
path=models_path,
|
||||
)
|
||||
before = appconfig.get_model("Text 2", path=models_path)
|
||||
|
||||
renamed = appconfig.rename_ai_model(
|
||||
"Text 2",
|
||||
" 文本模型 ",
|
||||
path=models_path,
|
||||
)
|
||||
|
||||
self.assertEqual("文本模型", renamed["name"])
|
||||
self.assertEqual(
|
||||
{**before, "name": "文本模型"},
|
||||
appconfig.get_model("文本模型", path=models_path),
|
||||
)
|
||||
with self.assertRaisesRegex(appconfig.ConfigError, "模型名称不能为空"):
|
||||
appconfig.rename_ai_model("文本模型", " ", path=models_path)
|
||||
with self.assertRaisesRegex(appconfig.ConfigError, "模型名称已存在"):
|
||||
appconfig.rename_ai_model(
|
||||
"文本模型",
|
||||
"GPT-5.5 文本",
|
||||
path=models_path,
|
||||
)
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_ai_model_constraints_and_connection_validation(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
models_path = os.path.join(temp_dir, "ai_models.json")
|
||||
|
||||
@@ -2489,6 +2489,85 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_settings_tab_renames_model_and_migrates_default_references(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
cfg["ai"] = appconfig.default_config()["ai"]
|
||||
cfg["ai"]["default_text_model"] = "GPT-5.5 文本"
|
||||
appconfig.save_config(cfg, path=cfg["config_path"])
|
||||
statuses = []
|
||||
tab = SettingsTab(
|
||||
config=cfg,
|
||||
ai_models_path=cfg["ai_models_path"],
|
||||
status_callback=statuses.append,
|
||||
)
|
||||
self.addCleanup(tab.close)
|
||||
old_model = appconfig.get_model("GPT-5.5 文本", path=cfg["ai_models_path"])
|
||||
|
||||
picker_layout = tab.model_combo.parentWidget().layout()
|
||||
self.assertIs(tab.add_model_button, picker_layout.itemAt(1).widget())
|
||||
self.assertIs(tab.rename_model_button, picker_layout.itemAt(2).widget())
|
||||
self.assertIs(tab.delete_model_button, picker_layout.itemAt(3).widget())
|
||||
self.assertTrue(tab.rename_model_button.isEnabled())
|
||||
|
||||
with mock.patch(
|
||||
"app.gui.tabs.settings.QInputDialog.getText",
|
||||
return_value=("自定义文本模型", True),
|
||||
):
|
||||
tab.rename_model()
|
||||
|
||||
self.assertEqual("自定义文本模型", tab.current_model_name)
|
||||
self.assertEqual(
|
||||
{**old_model, "name": "自定义文本模型"},
|
||||
appconfig.get_model("自定义文本模型", path=cfg["ai_models_path"]),
|
||||
)
|
||||
self.assertIsNone(tab._model_by_name("GPT-5.5 文本"))
|
||||
self.assertEqual(
|
||||
"自定义文本模型",
|
||||
tab.default_text_model_combo.currentData(),
|
||||
)
|
||||
saved = appconfig.load_config(cfg["config_path"])
|
||||
self.assertEqual("自定义文本模型", saved["ai"]["default_text_model"])
|
||||
self.assertEqual("Nano Banana 2", saved["ai"]["default_image_model"])
|
||||
self.assertIn(
|
||||
"AI 模型已重命名:GPT-5.5 文本 → 自定义文本模型",
|
||||
statuses[-1],
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"app.gui.tabs.settings.QInputDialog.getText",
|
||||
return_value=("", False),
|
||||
):
|
||||
tab.rename_model()
|
||||
self.assertEqual("自定义文本模型", tab.current_model_name)
|
||||
|
||||
tab.model_combo.setCurrentIndex(tab.model_combo.findData("Nano Banana 2"))
|
||||
with mock.patch(
|
||||
"app.gui.tabs.settings.QInputDialog.getText",
|
||||
return_value=("自定义图片模型", True),
|
||||
):
|
||||
tab.rename_model()
|
||||
saved = appconfig.load_config(cfg["config_path"])
|
||||
self.assertEqual("自定义图片模型", saved["ai"]["default_image_model"])
|
||||
self.assertEqual(
|
||||
"自定义图片模型",
|
||||
tab.default_image_model_combo.currentData(),
|
||||
)
|
||||
|
||||
with mock.patch(
|
||||
"app.gui.tabs.settings.QInputDialog.getText",
|
||||
return_value=("自定义文本模型", True),
|
||||
), mock.patch("app.gui.tabs.settings.QMessageBox.warning") as warning:
|
||||
tab.rename_model()
|
||||
warning.assert_called_once()
|
||||
self.assertEqual("自定义图片模型", tab.current_model_name)
|
||||
self.assertEqual(
|
||||
"自定义图片模型",
|
||||
appconfig.load_config(cfg["config_path"])["ai"]["default_image_model"],
|
||||
)
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_settings_tab_starts_connection_test_worker(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
cfg = self.make_config(temp_dir)
|
||||
|
||||
Reference in New Issue
Block a user