diff --git a/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx b/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx index ac6a45f4e4..edcc4c1bc0 100644 --- a/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx +++ b/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx @@ -14,6 +14,24 @@ const mockSetPublishMenuOpen = vi.fn() const mockToggleInputPanel = vi.fn() const mockTogglePublishMenu = vi.fn() const mockPublishSnippetMutateAsync = vi.fn() +const mockFetchInspectVars = vi.fn() +const mockInspectVarsCrud = { + hasNodeInspectVars: vi.fn(), + hasSetInspectVar: vi.fn(), + fetchInspectVarValue: vi.fn(), + editInspectVarValue: vi.fn(), + renameInspectVarName: vi.fn(), + appendNodeInspectVars: vi.fn(), + deleteInspectVar: vi.fn(), + deleteNodeInspectorVars: vi.fn(), + deleteAllInspectorVars: vi.fn(), + isInspectVarEdited: vi.fn(), + resetToLastRunVar: vi.fn(), + invalidateSysVarValues: vi.fn(), + resetConversationVar: vi.fn(), + invalidateConversationVarValues: vi.fn(), +} +let capturedHooksStore: Record | undefined vi.mock('@/hooks/use-breakpoints', () => ({ default: () => 'desktop', @@ -69,6 +87,16 @@ vi.mock('@/app/components/snippets/hooks/use-configs-map', () => ({ }), })) +vi.mock('@/app/components/workflow/hooks/use-fetch-workflow-inspect-vars', () => ({ + useSetWorkflowVarsWithValue: () => ({ + fetchInspectVars: mockFetchInspectVars, + }), +})) + +vi.mock('@/app/components/snippets/hooks/use-inspect-vars-crud', () => ({ + useInspectVarsCrud: () => mockInspectVarsCrud, +})) + vi.mock('@/app/components/snippets/hooks/use-nodes-sync-draft', () => ({ useNodesSyncDraft: () => ({ doSyncWorkflowDraft: vi.fn(), @@ -111,9 +139,19 @@ vi.mock('@/app/components/evaluation', () => ({ })) vi.mock('@/app/components/workflow', () => ({ - WorkflowWithInnerContext: ({ children }: { children: React.ReactNode }) => ( -
{children}
- ), + WorkflowWithInnerContext: ({ + children, + hooksStore, + }: { + children: React.ReactNode + hooksStore?: Record + }) => { + capturedHooksStore = hooksStore + + return ( +
{children}
+ ) + }, })) vi.mock('@/app/components/snippets/components/snippet-children', () => ({ @@ -193,6 +231,7 @@ describe('SnippetMain', () => { vi.clearAllMocks() mockSyncInputFieldsDraft.mockResolvedValue(undefined) mockPublishSnippetMutateAsync.mockResolvedValue(undefined) + capturedHooksStore = undefined }) describe('Input Fields Sync', () => { @@ -243,4 +282,26 @@ describe('SnippetMain', () => { expect(mockSetPublishMenuOpen).toHaveBeenCalledWith(false) }) }) + + describe('Inspect Vars', () => { + it('should pass inspect vars handlers to WorkflowWithInnerContext', () => { + renderSnippetMain() + + expect(capturedHooksStore?.fetchInspectVars).toBe(mockFetchInspectVars) + expect(capturedHooksStore?.hasNodeInspectVars).toBe(mockInspectVarsCrud.hasNodeInspectVars) + expect(capturedHooksStore?.hasSetInspectVar).toBe(mockInspectVarsCrud.hasSetInspectVar) + expect(capturedHooksStore?.fetchInspectVarValue).toBe(mockInspectVarsCrud.fetchInspectVarValue) + expect(capturedHooksStore?.editInspectVarValue).toBe(mockInspectVarsCrud.editInspectVarValue) + expect(capturedHooksStore?.renameInspectVarName).toBe(mockInspectVarsCrud.renameInspectVarName) + expect(capturedHooksStore?.appendNodeInspectVars).toBe(mockInspectVarsCrud.appendNodeInspectVars) + expect(capturedHooksStore?.deleteInspectVar).toBe(mockInspectVarsCrud.deleteInspectVar) + expect(capturedHooksStore?.deleteNodeInspectorVars).toBe(mockInspectVarsCrud.deleteNodeInspectorVars) + expect(capturedHooksStore?.deleteAllInspectorVars).toBe(mockInspectVarsCrud.deleteAllInspectorVars) + expect(capturedHooksStore?.isInspectVarEdited).toBe(mockInspectVarsCrud.isInspectVarEdited) + expect(capturedHooksStore?.resetToLastRunVar).toBe(mockInspectVarsCrud.resetToLastRunVar) + expect(capturedHooksStore?.invalidateSysVarValues).toBe(mockInspectVarsCrud.invalidateSysVarValues) + expect(capturedHooksStore?.resetConversationVar).toBe(mockInspectVarsCrud.resetConversationVar) + expect(capturedHooksStore?.invalidateConversationVarValues).toBe(mockInspectVarsCrud.invalidateConversationVarValues) + }) + }) }) diff --git a/web/app/components/snippets/components/snippet-main.tsx b/web/app/components/snippets/components/snippet-main.tsx index ed01d27c0b..b6f3eb1f9f 100644 --- a/web/app/components/snippets/components/snippet-main.tsx +++ b/web/app/components/snippets/components/snippet-main.tsx @@ -21,9 +21,11 @@ import { useStore as useAppStore } from '@/app/components/app/store' import Evaluation from '@/app/components/evaluation' import { WorkflowWithInnerContext } from '@/app/components/workflow' import { useAvailableNodesMetaData } from '@/app/components/workflow-app/hooks' +import { useSetWorkflowVarsWithValue } from '@/app/components/workflow/hooks/use-fetch-workflow-inspect-vars' import { BlockEnum } from '@/app/components/workflow/types' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { useConfigsMap } from '../hooks/use-configs-map' +import { useInspectVarsCrud } from '../hooks/use-inspect-vars-crud' import { useNodesSyncDraft } from '../hooks/use-nodes-sync-draft' import { useSnippetRefreshDraft } from '../hooks/use-snippet-refresh-draft' import { useSnippetDetailStore } from '../store' @@ -65,6 +67,25 @@ const SnippetMain = ({ } = useNodesSyncDraft(snippetId) const { handleRefreshWorkflowDraft } = useSnippetRefreshDraft(snippetId) const configsMap = useConfigsMap(snippetId) + const { fetchInspectVars } = useSetWorkflowVarsWithValue({ + ...configsMap, + }) + const { + hasNodeInspectVars, + hasSetInspectVar, + fetchInspectVarValue, + editInspectVarValue, + renameInspectVarName, + appendNodeInspectVars, + deleteInspectVar, + deleteNodeInspectorVars, + deleteAllInspectorVars, + isInspectVarEdited, + resetToLastRunVar, + invalidateSysVarValues, + resetConversationVar, + invalidateConversationVarValues, + } = useInspectVarsCrud(snippetId) const workflowAvailableNodesMetaData = useAvailableNodesMetaData() const availableNodesMetaData = useMemo(() => { const nodes = workflowAvailableNodesMetaData.nodes.filter(node => @@ -128,9 +149,45 @@ const SnippetMain = ({ syncWorkflowDraftWhenPageClose, handleRefreshWorkflowDraft, availableNodesMetaData, + fetchInspectVars, + hasNodeInspectVars, + hasSetInspectVar, + fetchInspectVarValue, + editInspectVarValue, + renameInspectVarName, + appendNodeInspectVars, + deleteInspectVar, + deleteNodeInspectorVars, + deleteAllInspectorVars, + isInspectVarEdited, + resetToLastRunVar, + invalidateSysVarValues, + resetConversationVar, + invalidateConversationVarValues, configsMap, } - }, [availableNodesMetaData, configsMap, doSyncWorkflowDraft, handleRefreshWorkflowDraft, syncWorkflowDraftWhenPageClose]) + }, [ + appendNodeInspectVars, + availableNodesMetaData, + configsMap, + deleteAllInspectorVars, + deleteInspectVar, + deleteNodeInspectorVars, + doSyncWorkflowDraft, + editInspectVarValue, + fetchInspectVarValue, + fetchInspectVars, + handleRefreshWorkflowDraft, + hasNodeInspectVars, + hasSetInspectVar, + invalidateConversationVarValues, + invalidateSysVarValues, + isInspectVarEdited, + renameInspectVarName, + resetConversationVar, + resetToLastRunVar, + syncWorkflowDraftWhenPageClose, + ]) return (
diff --git a/web/app/components/snippets/hooks/__tests__/use-inspect-vars-crud.spec.ts b/web/app/components/snippets/hooks/__tests__/use-inspect-vars-crud.spec.ts new file mode 100644 index 0000000000..69e264d0cc --- /dev/null +++ b/web/app/components/snippets/hooks/__tests__/use-inspect-vars-crud.spec.ts @@ -0,0 +1,95 @@ +import { renderHook } from '@testing-library/react' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { useInspectVarsCrud } from '../use-inspect-vars-crud' + +const mockApis = { + hasNodeInspectVars: vi.fn(), + hasSetInspectVar: vi.fn(), + fetchInspectVarValue: vi.fn(), + editInspectVarValue: vi.fn(), + renameInspectVarName: vi.fn(), + appendNodeInspectVars: vi.fn(), + deleteInspectVar: vi.fn(), + deleteNodeInspectorVars: vi.fn(), + deleteAllInspectorVars: vi.fn(), + isInspectVarEdited: vi.fn(), + resetToLastRunVar: vi.fn(), + invalidateSysVarValues: vi.fn(), + resetConversationVar: vi.fn(), + invalidateConversationVarValues: vi.fn(), +} + +const mockUseInspectVarsCrudCommon = vi.fn(() => mockApis) +vi.mock('../../../workflow/hooks/use-inspect-vars-crud-common', () => ({ + useInspectVarsCrudCommon: (...args: Parameters) => mockUseInspectVarsCrudCommon(...args), +})) + +const mockConfigsMap = { + flowId: 'snippet-123', + flowType: 'snippet', + fileSettings: { + image: { enabled: false }, + fileUploadConfig: {}, + }, +} + +vi.mock('../use-configs-map', () => ({ + useConfigsMap: () => mockConfigsMap, +})) + +describe('useInspectVarsCrud', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + describe('Composition', () => { + it('should pass configsMap to useInspectVarsCrudCommon', () => { + renderHook(() => useInspectVarsCrud('snippet-123')) + + expect(mockUseInspectVarsCrudCommon).toHaveBeenCalledWith( + expect.objectContaining({ + flowId: 'snippet-123', + flowType: 'snippet', + }), + ) + }) + + it('should return all APIs from useInspectVarsCrudCommon', () => { + const { result } = renderHook(() => useInspectVarsCrud('snippet-123')) + + expect(result.current.hasNodeInspectVars).toBe(mockApis.hasNodeInspectVars) + expect(result.current.fetchInspectVarValue).toBe(mockApis.fetchInspectVarValue) + expect(result.current.editInspectVarValue).toBe(mockApis.editInspectVarValue) + expect(result.current.deleteInspectVar).toBe(mockApis.deleteInspectVar) + expect(result.current.deleteAllInspectorVars).toBe(mockApis.deleteAllInspectorVars) + expect(result.current.resetToLastRunVar).toBe(mockApis.resetToLastRunVar) + expect(result.current.resetConversationVar).toBe(mockApis.resetConversationVar) + }) + }) + + describe('API Surface', () => { + it('should expose all expected API methods', () => { + const { result } = renderHook(() => useInspectVarsCrud('snippet-123')) + + const expectedKeys = [ + 'hasNodeInspectVars', + 'hasSetInspectVar', + 'fetchInspectVarValue', + 'editInspectVarValue', + 'renameInspectVarName', + 'appendNodeInspectVars', + 'deleteInspectVar', + 'deleteNodeInspectorVars', + 'deleteAllInspectorVars', + 'isInspectVarEdited', + 'resetToLastRunVar', + 'invalidateSysVarValues', + 'resetConversationVar', + 'invalidateConversationVarValues', + ] + + for (const key of expectedKeys) + expect(result.current).toHaveProperty(key) + }) + }) +}) diff --git a/web/app/components/snippets/hooks/use-inspect-vars-crud.ts b/web/app/components/snippets/hooks/use-inspect-vars-crud.ts new file mode 100644 index 0000000000..71ae6df068 --- /dev/null +++ b/web/app/components/snippets/hooks/use-inspect-vars-crud.ts @@ -0,0 +1,13 @@ +import { useInspectVarsCrudCommon } from '../../workflow/hooks/use-inspect-vars-crud-common' +import { useConfigsMap } from './use-configs-map' + +export const useInspectVarsCrud = (snippetId: string) => { + const configsMap = useConfigsMap(snippetId) + const apis = useInspectVarsCrudCommon({ + ...configsMap, + }) + + return { + ...apis, + } +}