From 5a7a955210575a18baeef37eb32a9bbe35db73a0 Mon Sep 17 00:00:00 2001 From: treekimm <31647061+treekimm@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:07:59 +0900 Subject: [PATCH] fix: prioritize URL conversation_id over localStorage in embedded chatbot (#35519) Co-authored-by: KimNamWoo Co-authored-by: Claude Opus 4.6 --- .../embedded-chatbot/__tests__/hooks.spec.tsx | 34 +++++++++++++++++++ .../base/chat/embedded-chatbot/hooks.tsx | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/web/app/components/base/chat/embedded-chatbot/__tests__/hooks.spec.tsx b/web/app/components/base/chat/embedded-chatbot/__tests__/hooks.spec.tsx index b4f3f01070..a6a35f4c7b 100644 --- a/web/app/components/base/chat/embedded-chatbot/__tests__/hooks.spec.tsx +++ b/web/app/components/base/chat/embedded-chatbot/__tests__/hooks.spec.tsx @@ -532,6 +532,7 @@ describe('useEmbeddedChatbot', () => { }) it('handleChangeConversation updates current conversation and refetches chat list', async () => { + mockStoreState.embeddedConversationId = null const { result } = await renderWithClient(() => useEmbeddedChatbot(AppSourceType.webApp)) act(() => { @@ -548,6 +549,39 @@ describe('useEmbeddedChatbot', () => { expect(result.current.clearChatList).toBe(false) }) + // Scenario: URL-provided conversation_id should take precedence over localStorage value. + it('should prioritize URL conversation_id over localStorage', async () => { + localStorage.setItem(CONVERSATION_ID_INFO, JSON.stringify({ + 'app-1': { 'embedded-user-1': 'stored-conv-id' }, + })) + mockStoreState.embeddedConversationId = 'url-conv-id' + mockGetProcessedSystemVariablesFromUrlParams.mockResolvedValue({ + user_id: 'embedded-user-1', + conversation_id: 'url-conv-id', + }) + + const { result } = await renderWithClient(() => useEmbeddedChatbot(AppSourceType.webApp)) + + await waitFor(() => { + expect(result.current.currentConversationId).toBe('url-conv-id') + }) + }) + + // Scenario: When no URL conversation_id is provided, fall back to localStorage. + it('should fall back to localStorage when no URL conversation_id is provided', async () => { + localStorage.setItem(CONVERSATION_ID_INFO, JSON.stringify({ + 'app-1': { DEFAULT: 'stored-conv-id' }, + })) + mockStoreState.embeddedConversationId = null + mockStoreState.embeddedUserId = null + + const { result } = await renderWithClient(() => useEmbeddedChatbot(AppSourceType.webApp)) + + await waitFor(() => { + expect(result.current.currentConversationId).toBe('stored-conv-id') + }) + }) + it('handleFeedback invokes updateFeedback service successfully', async () => { const { updateFeedback } = await import('@/service/share') const { result } = await renderWithClient(() => useEmbeddedChatbot(AppSourceType.webApp)) diff --git a/web/app/components/base/chat/embedded-chatbot/hooks.tsx b/web/app/components/base/chat/embedded-chatbot/hooks.tsx index 4ce6bc6318..39cbe66fbb 100644 --- a/web/app/components/base/chat/embedded-chatbot/hooks.tsx +++ b/web/app/components/base/chat/embedded-chatbot/hooks.tsx @@ -113,7 +113,7 @@ export const useEmbeddedChatbot = (appSourceType: AppSourceType, tryAppId?: stri }) }, [setConversationIdInfo]) const allowResetChat = !conversationId - const currentConversationId = useMemo(() => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || conversationId || '', [appId, conversationIdInfo, userId, conversationId]) + const currentConversationId = useMemo(() => conversationId || conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || '', [appId, conversationIdInfo, userId, conversationId]) const handleConversationIdInfoChange = useCallback((changeConversationId: string) => { if (appId) { let prevValue = conversationIdInfo?.[appId || '']