dify/api/tests/unit_tests/controllers/openapi/test_app_payloads.py
2026-07-15 06:48:28 +00:00

78 lines
2.4 KiB
Python

"""Unit tests for app payload-rendering helpers — independent of
HTTP plumbing or DB. Pin the response shapes that are CLI contracts.
"""
from __future__ import annotations
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
from controllers.openapi.apps import ( # pyright: ignore[reportPrivateUsage]
_EMPTY_PARAMETERS,
_is_listable,
parameters_payload,
)
from controllers.service_api.app.error import AppUnavailableError
from models.model import AppMode
def _fake_app(**overrides):
base = {
"id": "app1",
"name": "X",
"description": "d",
"mode": "chat",
"author_name": "alice",
"tags": [SimpleNamespace(name="prod")],
"updated_at": None,
"enable_api": True,
"workflow": None,
"app_model_config": None,
}
base.update(overrides)
return SimpleNamespace(**base)
def test_parameters_payload_raises_app_unavailable_when_no_config():
app = _fake_app(mode="chat")
app.app_model_config_with_session = MagicMock(return_value=None)
session = MagicMock()
with pytest.raises(AppUnavailableError):
parameters_payload(app, session=session)
app.app_model_config_with_session.assert_called_once_with(session=session)
def test_empty_parameters_constant_matches_describe_fallback_shape():
"""The fallback dict served by /describe when an app has no config
must match the spec's stated keys (opening_statement, suggested_questions,
user_input_form, file_upload, system_parameters)."""
assert set(_EMPTY_PARAMETERS.keys()) == {
"opening_statement",
"suggested_questions",
"user_input_form",
"file_upload",
"system_parameters",
}
assert _EMPTY_PARAMETERS["suggested_questions"] == []
assert _EMPTY_PARAMETERS["user_input_form"] == []
assert _EMPTY_PARAMETERS["opening_statement"] is None
assert _EMPTY_PARAMETERS["file_upload"] is None
assert _EMPTY_PARAMETERS["system_parameters"] == {}
@pytest.mark.parametrize(
"mode",
[AppMode.COMPLETION, AppMode.CHAT, AppMode.ADVANCED_CHAT, AppMode.WORKFLOW, AppMode.AGENT_CHAT],
)
def test_is_listable_accepts_supported_app_types(mode):
assert _is_listable(_fake_app(mode=mode)) is True
@pytest.mark.parametrize("mode", [AppMode.AGENT, AppMode.CHANNEL, AppMode.RAG_PIPELINE])
def test_is_listable_hides_non_app_modes(mode):
assert _is_listable(_fake_app(mode=mode)) is False