diff --git a/web/app/components/app/app-publisher/__tests__/index.spec.tsx b/web/app/components/app/app-publisher/__tests__/index.spec.tsx index f33404efc3..471eb9e3e5 100644 --- a/web/app/components/app/app-publisher/__tests__/index.spec.tsx +++ b/web/app/components/app/app-publisher/__tests__/index.spec.tsx @@ -564,6 +564,10 @@ describe('AppPublisher', () => { }) it('should switch workflow type, refresh app detail, and close the popover for published apps', async () => { + mockAppDetail = { + ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, + } mockFetchAppDetailDirect.mockResolvedValueOnce({ id: 'app-1', workflow_kind: AppTypeEnum.EVALUATION, @@ -596,6 +600,10 @@ describe('AppPublisher', () => { }) it('should publish an unpublished workflow as evaluation workflow through the evaluation publish endpoint', async () => { + mockAppDetail = { + ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, + } mockOnPublish.mockResolvedValue(undefined) mockFetchAppDetailDirect.mockResolvedValueOnce({ id: 'app-1', @@ -630,6 +638,7 @@ describe('AppPublisher', () => { it('should hide access and actions sections for evaluation workflow apps', () => { mockAppDetail = { ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, workflow_kind: AppTypeEnum.EVALUATION, } @@ -655,6 +664,7 @@ describe('AppPublisher', () => { it('should confirm before switching an evaluation workflow with associated targets to a standard workflow', async () => { mockAppDetail = { ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, workflow_kind: AppTypeEnum.EVALUATION, } mockEvaluationWorkflowAssociatedTargets = { @@ -706,6 +716,7 @@ describe('AppPublisher', () => { it('should switch an evaluation workflow directly when there are no associated targets', async () => { mockAppDetail = { ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, workflow_kind: AppTypeEnum.EVALUATION, } @@ -732,6 +743,7 @@ describe('AppPublisher', () => { it('should block switching an evaluation workflow when associated targets fail to load', async () => { mockAppDetail = { ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, workflow_kind: AppTypeEnum.EVALUATION, } mockRefetchEvaluationWorkflowAssociatedTargets.mockResolvedValueOnce({ @@ -755,6 +767,11 @@ describe('AppPublisher', () => { }) it('should block switching to evaluation workflow when restricted nodes exist', async () => { + mockAppDetail = { + ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, + } + render( { it('should keep the evaluation workflow switch visible but disabled when the current plan cannot access it', () => { mockCanAccessSnippetsAndEvaluation = false + mockAppDetail = { + ...mockAppDetail, + mode: AppModeEnum.WORKFLOW, + } render( { expect(sectionProps.summary?.workflowTypeSwitchDisabled).toBe(true) expect(sectionProps.summary?.workflowTypeSwitchDisabledReason).toBe('compliance.sandboxUpgradeTooltip') }) + + it('should not expose workflow type switching for non-workflow app modes', async () => { + render( + , + ) + + fireEvent.click(screen.getByText('common.publish')) + + expect(sectionProps.summary?.workflowTypeSwitchConfig).toBeUndefined() + + fireEvent.click(screen.getByText('publisher-switch-workflow-type')) + + await waitFor(() => { + expect(mockConvertWorkflowType).not.toHaveBeenCalled() + }) + expect(mockOnPublish).not.toHaveBeenCalled() + expect(mockFetchAppDetailDirect).not.toHaveBeenCalled() + expect(mockToastSuccess).not.toHaveBeenCalled() + }) }) diff --git a/web/app/components/app/app-publisher/use-workflow-type-switch.ts b/web/app/components/app/app-publisher/use-workflow-type-switch.ts index 25e633877a..f83f72c44f 100644 --- a/web/app/components/app/app-publisher/use-workflow-type-switch.ts +++ b/web/app/components/app/app-publisher/use-workflow-type-switch.ts @@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next' import { fetchAppDetailDirect } from '@/service/apps' import { useConvertWorkflowTypeMutation } from '@/service/use-apps' import { useEvaluationWorkflowAssociatedTargets } from '@/service/use-evaluation' -import { AppTypeEnum } from '@/types/app' +import { AppModeEnum, AppTypeEnum } from '@/types/app' type WorkflowTypeSwitchLabelKey = I18nKeysWithPrefix<'workflow', 'common.'> @@ -78,8 +78,11 @@ export const useWorkflowTypeSwitch = ({ } = useEvaluationWorkflowAssociatedTargets(appDetail?.id, { enabled: false }) const workflowTypeSwitchConfig = useMemo(() => { + if (appDetail?.mode !== AppModeEnum.WORKFLOW) + return undefined + return getWorkflowTypeSwitchConfig(appDetail?.workflow_kind) - }, [appDetail?.workflow_kind]) + }, [appDetail?.mode, appDetail?.workflow_kind]) const workflowTypeSwitchDisabledReason = useMemo(() => { if (workflowTypeSwitchConfig?.targetType !== AppTypeEnum.EVALUATION)