/* eslint-disable vue/one-component-per-file */ import { flushPromises, mount } from '@vue/test-utils'; import { defineComponent, h, nextTick } from 'vue'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import SysJobModal from './SysJobModal.vue'; const apiMocks = vi.hoisted(() => ({ get: vi.fn(), post: vi.fn(), })); vi.mock('#/api/request', () => ({ api: apiMocks })); vi.mock('#/locales', () => ({ $t: (key: string) => key })); vi.mock('#/components/cron/CronPicker.vue', () => ({ default: defineComponent({ name: 'CronPicker', setup: () => () => h('div') }), })); vi.mock('#/components/dict/DictSelect.vue', () => ({ default: defineComponent({ name: 'DictSelect', setup: () => () => h('div') }), })); vi.mock('#/views/ai/workflow/components/WorkflowFormItem.vue', () => ({ default: defineComponent({ name: 'WorkflowFormItem', setup: () => () => h('div'), }), })); vi.mock('@easyflow/common-ui', () => ({ EasyFlowFormModal: defineComponent({ name: 'EasyFlowFormModal', props: { confirmDisabled: Boolean, confirmLoading: Boolean, open: Boolean, }, emits: ['confirm'], setup(props, { emit, slots }) { return () => props.open ? h('section', [ ...(slots.default?.() || []), h( 'button', { 'data-test': 'confirm', onClick: () => emit('confirm'), }, 'confirm', ), ]) : null; }, }), })); vi.mock('element-plus', () => ({ ElAlert: defineComponent({ name: 'ElAlert', props: { title: { default: '', type: String } }, setup(props) { return () => h('p', props.title); }, }), ElForm: defineComponent({ name: 'ElForm', setup(_, { expose, slots }) { expose({ resetFields: vi.fn(), validate: (callback: (valid: boolean) => void) => callback(true), }); return () => h('form', slots.default?.()); }, }), ElFormItem: defineComponent({ name: 'ElFormItem', setup(_, { slots }) { return () => h('div', slots.default?.()); }, }), ElInput: defineComponent({ name: 'ElInput', setup: () => () => h('input') }), ElMessage: { error: vi.fn(), success: vi.fn() }, ElOption: defineComponent({ name: 'ElOption', setup: () => () => h('div') }), ElSelect: defineComponent({ name: 'ElSelect', setup(_, { slots }) { return () => h('div', slots.default?.()); }, }), })); describe('sys job modal', () => { beforeEach(() => { vi.clearAllMocks(); apiMocks.get.mockRejectedValue(new Error('工作流不存在')); apiMocks.post.mockResolvedValue({ errorCode: 0, message: '保存成功' }); }); it('releases loading and keeps new task creation available after a deleted workflow fails to load', async () => { const wrapper = mount(SysJobModal, { global: { directives: { loading: { mounted(element, binding) { element.dataset.loading = String(binding.value); }, updated(element, binding) { element.dataset.loading = String(binding.value); }, }, }, }, }); (wrapper.vm as { openDialog: (row: unknown) => void }).openDialog({ id: 1, jobParams: { workflowId: '101', workflowParams: {} }, jobType: 1, }); await flushPromises(); expect(apiMocks.get).toHaveBeenCalledWith( '/api/v1/sysJob/workflowRunningParameters', { params: { id: '101' } }, ); expect(wrapper.get('form').attributes('data-loading')).toBe('false'); expect(wrapper.text()).toContain('所选工作流已不可用,请重新选择'); expect( wrapper .findComponent({ name: 'EasyFlowFormModal' }) .props('confirmDisabled'), ).toBe(true); await wrapper.get('[data-test="confirm"]').trigger('click'); expect(apiMocks.post).not.toHaveBeenCalled(); (wrapper.vm as { openDialog: (row: unknown) => void }).openDialog({}); await flushPromises(); expect(wrapper.get('form').attributes('data-loading')).toBe('false'); expect( wrapper .findComponent({ name: 'EasyFlowFormModal' }) .props('confirmDisabled'), ).toBe(false); }); it('blocks save while workflow parameters are loading', async () => { let resolveParameters: ((value: unknown) => void) | undefined; apiMocks.get.mockReturnValue( new Promise((resolve) => { resolveParameters = resolve; }), ); const wrapper = mount(SysJobModal, { global: { directives: { loading: { mounted(element, binding) { element.dataset.loading = String(binding.value); }, updated(element, binding) { element.dataset.loading = String(binding.value); }, }, }, }, }); (wrapper.vm as { openDialog: (row: unknown) => void }).openDialog({ id: 1, jobParams: { workflowId: '101', workflowParams: {} }, jobType: 1, }); await nextTick(); const modal = wrapper.findComponent({ name: 'EasyFlowFormModal' }); expect(modal.props('confirmDisabled')).toBe(true); expect(modal.props('confirmLoading')).toBe(true); await wrapper.get('[data-test="confirm"]').trigger('click'); expect(apiMocks.post).not.toHaveBeenCalled(); resolveParameters?.({ data: { parameters: [] } }); await flushPromises(); expect(modal.props('confirmDisabled')).toBe(false); expect(modal.props('confirmLoading')).toBe(false); await wrapper.get('[data-test="confirm"]').trigger('click'); await flushPromises(); expect(apiMocks.post).toHaveBeenCalledTimes(1); }); });