mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
test: use real prompt and dataset configuration models
This commit is contained in:
1 parent
f8da3473df
commit
97ce36b39e
2 files changed
+50
-175
No files matched your search
+13
-27
@@ -1,11 +1,11 @@
|
||||
import uuid
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from pytest_mock import MockerFixture
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from core.app.app_config.easy_ui_based_app.dataset.manager import DatasetConfigManager
|
||||
from core.app.app_config.entities import MetadataFilteringCondition, ModelConfig
|
||||
from core.entities.agent_entities import PlanningStrategy
|
||||
from models.dataset import Dataset
|
||||
from models.model import AppMode
|
||||
@@ -76,36 +76,14 @@ class TestDatasetConfigManagerConvert:
|
||||
assert result.dataset_ids == [valid_uuid]
|
||||
assert result.retrieve_config.query_variable == "query"
|
||||
|
||||
def test_convert_single_with_metadata_configs(self, valid_uuid, mocker: MockerFixture):
|
||||
mock_retrieve_config = MagicMock()
|
||||
mock_entity = MagicMock()
|
||||
mock_entity.dataset_ids = [valid_uuid]
|
||||
mock_entity.retrieve_config = mock_retrieve_config
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.dataset.manager.ModelConfig",
|
||||
return_value={"mock": "model"},
|
||||
)
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.dataset.manager.MetadataFilteringCondition",
|
||||
return_value={"mock": "condition"},
|
||||
)
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.dataset.manager.DatasetRetrieveConfigEntity",
|
||||
return_value=mock_retrieve_config,
|
||||
)
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.dataset.manager.DatasetEntity",
|
||||
return_value=mock_entity,
|
||||
)
|
||||
|
||||
def test_convert_single_with_metadata_configs(self, valid_uuid):
|
||||
config = {
|
||||
"dataset_query_variable": "query",
|
||||
"dataset_configs": {
|
||||
"retrieval_model": "single",
|
||||
"metadata_filtering_mode": "manual",
|
||||
"metadata_model_config": {"any": "value"},
|
||||
"metadata_filtering_conditions": {"any": "value"},
|
||||
"metadata_model_config": {"provider": "openai", "name": "gpt-4o", "mode": "chat"},
|
||||
"metadata_filtering_conditions": {"logical_operator": "or", "conditions": []},
|
||||
"datasets": {
|
||||
"strategy": "router",
|
||||
"datasets": [{"dataset": {"id": valid_uuid, "enabled": True}}],
|
||||
@@ -113,8 +91,16 @@ class TestDatasetConfigManagerConvert:
|
||||
},
|
||||
}
|
||||
result = DatasetConfigManager.convert(config)
|
||||
assert result is not None
|
||||
assert result.dataset_ids == [valid_uuid]
|
||||
assert result.retrieve_config is mock_retrieve_config
|
||||
assert result.retrieve_config.query_variable == "query"
|
||||
assert result.retrieve_config.metadata_filtering_mode == "manual"
|
||||
assert result.retrieve_config.metadata_model_config == ModelConfig(
|
||||
provider="openai", name="gpt-4o", mode="chat"
|
||||
)
|
||||
assert result.retrieve_config.metadata_filtering_conditions == MetadataFilteringCondition(
|
||||
logical_operator="or", conditions=[]
|
||||
)
|
||||
|
||||
def test_convert_multiple_defaults(self, valid_uuid):
|
||||
config = {
|
||||
|
||||
+37
-148
@@ -1,42 +1,11 @@
|
||||
from collections import UserString
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
from core.app.app_config.easy_ui_based_app.prompt_template.manager import (
|
||||
PromptTemplateConfigManager,
|
||||
)
|
||||
|
||||
# -----------------------------
|
||||
# Helpers
|
||||
# -----------------------------
|
||||
|
||||
|
||||
class DummyEnumValue(UserString):
|
||||
def __init__(self, value):
|
||||
super().__init__(value)
|
||||
self.value = value
|
||||
|
||||
|
||||
class DummyPromptType:
|
||||
def __init__(self):
|
||||
self.SIMPLE = DummyEnumValue("simple")
|
||||
self.ADVANCED = DummyEnumValue("advanced")
|
||||
|
||||
def value_of(self, value):
|
||||
for enum_value in self:
|
||||
if enum_value.value == value:
|
||||
return enum_value
|
||||
raise ValueError(f"invalid prompt type value {value}")
|
||||
|
||||
def __iter__(self):
|
||||
return iter([self.SIMPLE, self.ADVANCED])
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Convert Tests
|
||||
# -----------------------------
|
||||
from core.app.app_config.entities import PromptTemplateEntity
|
||||
from graphon.model_runtime.entities.message_entities import PromptMessageRole
|
||||
from models.model import AppMode
|
||||
|
||||
|
||||
class TestPromptTemplateConfigManagerConvert:
|
||||
@@ -44,49 +13,16 @@ class TestPromptTemplateConfigManagerConvert:
|
||||
with pytest.raises(ValueError, match="prompt_type is required"):
|
||||
PromptTemplateConfigManager.convert({})
|
||||
|
||||
def test_convert_simple_prompt(self, mocker: MockerFixture):
|
||||
mock_prompt_entity_cls = MagicMock()
|
||||
mock_prompt_entity_cls.PromptType = DummyPromptType()
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.PromptTemplateEntity",
|
||||
mock_prompt_entity_cls,
|
||||
)
|
||||
|
||||
mock_prompt_entity_cls.return_value = "simple_entity"
|
||||
|
||||
def test_convert_simple_prompt(self):
|
||||
config = {"prompt_type": "simple", "pre_prompt": "hello"}
|
||||
|
||||
result = PromptTemplateConfigManager.convert(config)
|
||||
|
||||
assert result == "simple_entity"
|
||||
mock_prompt_entity_cls.assert_called_once_with(prompt_type="simple", simple_prompt_template="hello")
|
||||
|
||||
def test_convert_advanced_chat_valid(self, mocker: MockerFixture):
|
||||
mock_prompt_entity_cls = MagicMock()
|
||||
mock_prompt_entity_cls.PromptType = DummyPromptType()
|
||||
mock_prompt_entity_cls.return_value = "advanced_entity"
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.PromptTemplateEntity",
|
||||
mock_prompt_entity_cls,
|
||||
)
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.PromptMessageRole.value_of",
|
||||
return_value="role_enum",
|
||||
)
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.AdvancedChatMessageEntity",
|
||||
return_value="chat_msg",
|
||||
)
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.AdvancedChatPromptTemplateEntity",
|
||||
return_value="chat_template",
|
||||
assert result == PromptTemplateEntity(
|
||||
prompt_type=PromptTemplateEntity.PromptType.SIMPLE, simple_prompt_template="hello"
|
||||
)
|
||||
|
||||
def test_convert_advanced_chat_valid(self):
|
||||
config = {
|
||||
"prompt_type": "advanced",
|
||||
"chat_prompt_config": {"prompt": [{"text": "hi", "role": "user"}]},
|
||||
@@ -94,7 +30,12 @@ class TestPromptTemplateConfigManagerConvert:
|
||||
|
||||
result = PromptTemplateConfigManager.convert(config)
|
||||
|
||||
assert result == "advanced_entity"
|
||||
assert result.prompt_type == PromptTemplateEntity.PromptType.ADVANCED
|
||||
assert result.advanced_chat_prompt_template is not None
|
||||
assert len(result.advanced_chat_prompt_template.messages) == 1
|
||||
message = result.advanced_chat_prompt_template.messages[0]
|
||||
assert message.text == "hi"
|
||||
assert message.role == PromptMessageRole.USER
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"message",
|
||||
@@ -103,15 +44,7 @@ class TestPromptTemplateConfigManagerConvert:
|
||||
{"text": "hi", "role": 123},
|
||||
],
|
||||
)
|
||||
def test_convert_advanced_invalid_message_fields(self, mocker: MockerFixture, message):
|
||||
mock_prompt_entity_cls = MagicMock()
|
||||
mock_prompt_entity_cls.PromptType = DummyPromptType()
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.PromptTemplateEntity",
|
||||
mock_prompt_entity_cls,
|
||||
)
|
||||
|
||||
def test_convert_advanced_invalid_message_fields(self, message):
|
||||
config = {
|
||||
"prompt_type": "advanced",
|
||||
"chat_prompt_config": {"prompt": [message]},
|
||||
@@ -120,21 +53,7 @@ class TestPromptTemplateConfigManagerConvert:
|
||||
with pytest.raises(ValueError):
|
||||
PromptTemplateConfigManager.convert(config)
|
||||
|
||||
def test_convert_advanced_completion_with_roles(self, mocker: MockerFixture):
|
||||
mock_prompt_entity_cls = MagicMock()
|
||||
mock_prompt_entity_cls.PromptType = DummyPromptType()
|
||||
mock_prompt_entity_cls.return_value = "advanced_entity"
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.PromptTemplateEntity",
|
||||
mock_prompt_entity_cls,
|
||||
)
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.AdvancedCompletionPromptTemplateEntity",
|
||||
return_value="completion_template",
|
||||
)
|
||||
|
||||
def test_convert_advanced_completion_with_roles(self):
|
||||
config = {
|
||||
"prompt_type": "advanced",
|
||||
"completion_prompt_config": {
|
||||
@@ -148,7 +67,12 @@ class TestPromptTemplateConfigManagerConvert:
|
||||
|
||||
result = PromptTemplateConfigManager.convert(config)
|
||||
|
||||
assert result == "advanced_entity"
|
||||
assert result.prompt_type == PromptTemplateEntity.PromptType.ADVANCED
|
||||
assert result.advanced_completion_prompt_template is not None
|
||||
assert result.advanced_completion_prompt_template.prompt == "complete"
|
||||
assert result.advanced_completion_prompt_template.role_prefix is not None
|
||||
assert result.advanced_completion_prompt_template.role_prefix.user == "U"
|
||||
assert result.advanced_completion_prompt_template.role_prefix.assistant == "A"
|
||||
|
||||
|
||||
# -----------------------------
|
||||
@@ -160,46 +84,21 @@ class TestValidateAndSetDefaults:
|
||||
def setup_method(self):
|
||||
self.valid_model = {"mode": "chat"}
|
||||
|
||||
def _patch_prompt_type(self, mocker: MockerFixture):
|
||||
mock_prompt_entity_cls = MagicMock()
|
||||
mock_prompt_entity_cls.PromptType = DummyPromptType()
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.PromptTemplateEntity",
|
||||
mock_prompt_entity_cls,
|
||||
)
|
||||
return mock_prompt_entity_cls
|
||||
|
||||
def test_default_prompt_type_set(self, mocker: MockerFixture):
|
||||
self._patch_prompt_type(mocker)
|
||||
|
||||
def test_default_prompt_type_set(self):
|
||||
config = {"model": self.valid_model}
|
||||
|
||||
result, keys = PromptTemplateConfigManager.validate_and_set_defaults("chat_app", config)
|
||||
result, keys = PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
assert result["prompt_type"] == "simple"
|
||||
assert isinstance(keys, list)
|
||||
|
||||
def test_invalid_prompt_type_raises(self, mocker: MockerFixture):
|
||||
class InvalidEnum(DummyPromptType):
|
||||
def __iter__(self):
|
||||
return iter([DummyEnumValue("valid")])
|
||||
|
||||
mock_prompt_entity_cls = MagicMock()
|
||||
mock_prompt_entity_cls.PromptType = InvalidEnum()
|
||||
|
||||
mocker.patch(
|
||||
"core.app.app_config.easy_ui_based_app.prompt_template.manager.PromptTemplateEntity",
|
||||
mock_prompt_entity_cls,
|
||||
)
|
||||
|
||||
def test_invalid_prompt_type_raises(self):
|
||||
config = {"prompt_type": "invalid", "model": self.valid_model}
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
PromptTemplateConfigManager.validate_and_set_defaults("chat_app", config)
|
||||
|
||||
def test_invalid_chat_prompt_config_type(self, mocker: MockerFixture):
|
||||
self._patch_prompt_type(mocker)
|
||||
PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
def test_invalid_chat_prompt_config_type(self):
|
||||
config = {
|
||||
"prompt_type": "simple",
|
||||
"chat_prompt_config": "invalid",
|
||||
@@ -207,11 +106,9 @@ class TestValidateAndSetDefaults:
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
PromptTemplateConfigManager.validate_and_set_defaults("chat_app", config)
|
||||
|
||||
def test_simple_mode_invalid_pre_prompt_type(self, mocker: MockerFixture):
|
||||
self._patch_prompt_type(mocker)
|
||||
PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
def test_simple_mode_invalid_pre_prompt_type(self):
|
||||
config = {
|
||||
"prompt_type": "simple",
|
||||
"pre_prompt": 123,
|
||||
@@ -219,11 +116,9 @@ class TestValidateAndSetDefaults:
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
PromptTemplateConfigManager.validate_and_set_defaults("chat_app", config)
|
||||
|
||||
def test_advanced_requires_one_config(self, mocker: MockerFixture):
|
||||
self._patch_prompt_type(mocker)
|
||||
PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
def test_advanced_requires_one_config(self):
|
||||
config = {
|
||||
"prompt_type": "advanced",
|
||||
"chat_prompt_config": {},
|
||||
@@ -232,11 +127,9 @@ class TestValidateAndSetDefaults:
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
PromptTemplateConfigManager.validate_and_set_defaults("chat_app", config)
|
||||
|
||||
def test_advanced_invalid_model_mode(self, mocker: MockerFixture):
|
||||
self._patch_prompt_type(mocker)
|
||||
PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
def test_advanced_invalid_model_mode(self):
|
||||
config = {
|
||||
"prompt_type": "advanced",
|
||||
"chat_prompt_config": {"prompt": []},
|
||||
@@ -244,11 +137,9 @@ class TestValidateAndSetDefaults:
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
PromptTemplateConfigManager.validate_and_set_defaults("chat_app", config)
|
||||
|
||||
def test_advanced_chat_prompt_length_exceeds(self, mocker: MockerFixture):
|
||||
self._patch_prompt_type(mocker)
|
||||
PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
def test_advanced_chat_prompt_length_exceeds(self):
|
||||
config = {
|
||||
"prompt_type": "advanced",
|
||||
"chat_prompt_config": {"prompt": [{}] * 11},
|
||||
@@ -256,11 +147,9 @@ class TestValidateAndSetDefaults:
|
||||
}
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
PromptTemplateConfigManager.validate_and_set_defaults("chat_app", config)
|
||||
|
||||
def test_completion_prefix_defaults_set_when_empty(self, mocker: MockerFixture):
|
||||
self._patch_prompt_type(mocker)
|
||||
PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
def test_completion_prefix_defaults_set_when_empty(self):
|
||||
config = {
|
||||
"prompt_type": "advanced",
|
||||
"completion_prompt_config": {
|
||||
@@ -273,7 +162,7 @@ class TestValidateAndSetDefaults:
|
||||
"model": {"mode": "completion"},
|
||||
}
|
||||
|
||||
updated, _ = PromptTemplateConfigManager.validate_and_set_defaults("chat", config)
|
||||
updated, _ = PromptTemplateConfigManager.validate_and_set_defaults(AppMode.CHAT, config)
|
||||
|
||||
roles = updated["completion_prompt_config"]["conversation_histories_role"]
|
||||
assert roles["user_prefix"] == "Human"
|
||||
|
||||
Reference in new issue
Block a user