Use POST for suggested questions

This commit is contained in:
-LAN- 2025-09-27 02:54:57 +08:00
parent e0fb754e80
commit c9eabe1612
8 changed files with 221 additions and 6 deletions

View File

@ -269,7 +269,7 @@ class MessageSuggestedQuestionApi(Resource):
@login_required
@account_initialization_required
@get_app_model(mode=[AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT])
def get(self, app_model, message_id):
def post(self, app_model, message_id):
message_id = str(message_id)
try:

View File

@ -163,7 +163,7 @@ class MessageMoreLikeThisApi(InstalledAppResource):
endpoint="installed_app_suggested_question",
)
class MessageSuggestedQuestionApi(InstalledAppResource):
def get(self, installed_app, message_id):
def post(self, installed_app, message_id):
app_model = installed_app.app
app_mode = AppMode.value_of(app_model.mode)
if app_mode not in {AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT}:

View File

@ -249,7 +249,7 @@ class MessageSuggestedQuestionApi(WebApiResource):
}
)
@marshal_with(suggested_questions_response_fields)
def get(self, app_model, end_user, message_id):
def post(self, app_model, end_user, message_id):
app_mode = AppMode.value_of(app_model.mode)
if app_mode not in {AppMode.CHAT, AppMode.AGENT_CHAT, AppMode.ADVANCED_CHAT}:
raise NotCompletionAppError()

View File

@ -0,0 +1,60 @@
import inspect
import uuid
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
from flask import Flask
from controllers.console.app import message as console_message_module
from controllers.console.app.message import MessageSuggestedQuestionApi
from core.app.entities.app_invoke_entities import InvokeFrom
from models.account import Account
@pytest.fixture
def flask_app():
app = Flask(__name__)
app.config["TESTING"] = True
return app
@pytest.fixture
def account_user():
user = Account(name="Tester", email="tester@example.com")
user.id = "user-id"
return user
class TestConsoleAppMessageSuggestedQuestionApi:
def test_post_forwards_to_service(self, flask_app, account_user, monkeypatch):
app_model = SimpleNamespace(id="app-id", mode="chat")
questions = ["a", "b"]
service_mock = MagicMock(return_value=questions)
monkeypatch.setattr(console_message_module, "current_user", account_user, raising=False)
monkeypatch.setattr(
console_message_module.MessageService,
"get_suggested_questions_after_answer",
service_mock,
raising=False,
)
handler = inspect.unwrap(MessageSuggestedQuestionApi.post)
controller = MessageSuggestedQuestionApi()
message_id = uuid.uuid4()
with flask_app.test_request_context(
f"/apps/{app_model.id}/chat-messages/{message_id}/suggested-questions",
method="POST",
json={},
):
result = handler(controller, app_model, message_id)
assert result == {"data": questions}
service_mock.assert_called_once_with(
app_model=app_model,
message_id=str(message_id),
user=account_user,
invoke_from=InvokeFrom.DEBUGGER,
)

View File

@ -0,0 +1,84 @@
import inspect
import uuid
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
from flask import Flask
from controllers.console.explore.error import NotChatAppError
from controllers.console.explore.message import MessageSuggestedQuestionApi
from core.app.entities.app_invoke_entities import InvokeFrom
from models.account import Account
from models.model import AppMode
@pytest.fixture
def flask_app():
app = Flask(__name__)
app.config["TESTING"] = True
return app
@pytest.fixture
def account_user():
user = Account(name="Tester", email="tester@example.com")
user.id = "user-id"
return user
class TestConsoleExploreMessageSuggestedQuestionApi:
def test_post_returns_questions(self, flask_app, account_user, monkeypatch):
installed_app = SimpleNamespace(app=SimpleNamespace(mode=AppMode.CHAT.value))
questions = ["q1"]
service_mock = MagicMock(return_value=questions)
monkeypatch.setattr(
"controllers.console.explore.message.current_user",
account_user,
raising=False,
)
monkeypatch.setattr(
"controllers.console.explore.message.MessageService.get_suggested_questions_after_answer",
service_mock,
raising=False,
)
handler = inspect.unwrap(MessageSuggestedQuestionApi.post)
controller = MessageSuggestedQuestionApi()
message_id = uuid.uuid4()
with flask_app.test_request_context(
f"/messages/{message_id}/suggested-questions",
method="POST",
json={},
):
result = handler(controller, installed_app, message_id)
assert result == {"data": questions}
service_mock.assert_called_once_with(
app_model=installed_app.app,
user=account_user,
message_id=str(message_id),
invoke_from=InvokeFrom.EXPLORE,
)
def test_non_chat_app_raises(self, flask_app, account_user, monkeypatch):
installed_app = SimpleNamespace(app=SimpleNamespace(mode=AppMode.COMPLETION.value))
monkeypatch.setattr(
"controllers.console.explore.message.current_user",
account_user,
raising=False,
)
handler = inspect.unwrap(MessageSuggestedQuestionApi.post)
controller = MessageSuggestedQuestionApi()
message_id = uuid.uuid4()
with flask_app.test_request_context(
f"/messages/{message_id}/suggested-questions",
method="POST",
json={},
):
with pytest.raises(NotChatAppError):
handler(controller, installed_app, message_id)

View File

@ -0,0 +1,67 @@
import inspect
import uuid
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
from flask import Flask
from controllers.web.error import NotCompletionAppError
from controllers.web.message import MessageSuggestedQuestionApi
from core.app.entities.app_invoke_entities import InvokeFrom
from models.model import AppMode
@pytest.fixture
def flask_app():
app = Flask(__name__)
app.config["TESTING"] = True
return app
class TestWebMessageSuggestedQuestionApi:
def test_post_returns_questions(self, flask_app, monkeypatch):
app_model = SimpleNamespace(mode=AppMode.CHAT.value)
end_user = SimpleNamespace()
questions = ["Q1", "Q2"]
service_mock = MagicMock(return_value=questions)
monkeypatch.setattr(
"controllers.web.message.MessageService.get_suggested_questions_after_answer",
service_mock,
raising=False,
)
handler = inspect.unwrap(MessageSuggestedQuestionApi.post)
controller = MessageSuggestedQuestionApi()
message_id = uuid.uuid4()
with flask_app.test_request_context(
f"/messages/{message_id}/suggested-questions",
method="POST",
json={},
):
result = handler(controller, app_model, end_user, message_id)
assert result == {"data": questions}
service_mock.assert_called_once_with(
app_model=app_model,
user=end_user,
message_id=str(message_id),
invoke_from=InvokeFrom.WEB_APP,
)
def test_non_chat_app_raises(self, flask_app):
app_model = SimpleNamespace(mode=AppMode.COMPLETION.value)
end_user = SimpleNamespace()
handler = inspect.unwrap(MessageSuggestedQuestionApi.post)
controller = MessageSuggestedQuestionApi()
message_id = uuid.uuid4()
with flask_app.test_request_context(
f"/messages/{message_id}/suggested-questions",
method="POST",
json={},
):
with pytest.raises(NotCompletionAppError):
handler(controller, app_model, end_user, message_id)

View File

@ -61,9 +61,11 @@ export const sendCompletionMessage = async (appId: string, body: Record<string,
}
export const fetchSuggestedQuestions = (appId: string, messageId: string, getAbortController?: any) => {
return get(
return post(
`apps/${appId}/chat-messages/${messageId}/suggested-questions`,
{},
{
body: {},
},
{
getAbortController,
},

View File

@ -271,7 +271,9 @@ export const removeMessage = (messageId: string, isInstalledApp: boolean, instal
}
export const fetchSuggestedQuestions = (messageId: string, isInstalledApp: boolean, installedAppId = '') => {
return (getAction('get', isInstalledApp))(getUrl(`/messages/${messageId}/suggested-questions`, isInstalledApp, installedAppId))
return (getAction('post', isInstalledApp))(getUrl(`/messages/${messageId}/suggested-questions`, isInstalledApp, installedAppId), {
body: {},
})
}
export const audioToText = (url: string, isPublicAPI: boolean, body: FormData) => {