import { defineComponent } from 'vue' import { mount } from '@vue/test-utils' import { describe, expect, it } from 'vitest' import { readFileSync } from 'node:fs' import { resolve } from 'node:path' import AppDialog from './AppDialog.vue' const ElDialogStub = defineComponent({ props: { modelValue: Boolean, showClose: Boolean, closeOnClickModal: Boolean, closeOnPressEscape: Boolean, }, template: '
', }) const ElButtonStub = defineComponent({ props: { disabled: Boolean, loading: Boolean, }, emits: ['click'], template: '', }) function mountDialog(props: Record = {}) { return mount(AppDialog, { props: { modelValue: true, title: '编辑资料', ...props }, slots: { default: '

弹框内容

' }, global: { stubs: { ElDialog: ElDialogStub, ElButton: ElButtonStub }, directives: { loading: {} }, }, }) } describe('AppDialog', () => { it('provides default cancel and confirm actions', async () => { const wrapper = mountDialog() const buttons = wrapper.findAll('button') expect(buttons.map((button) => button.text())).toEqual(['取消', '确定']) await buttons[1].trigger('click') expect(wrapper.emitted('confirm')).toHaveLength(1) await buttons[0].trigger('click') expect(wrapper.emitted('cancel')).toHaveLength(1) expect(wrapper.emitted('update:modelValue')).toEqual([[false]]) }) it('prevents accidental closing while confirmation is submitting', () => { const wrapper = mountDialog({ confirmLoading: true }) const dialog = wrapper.getComponent(ElDialogStub) const cancelButton = wrapper.findAll('button')[0] expect(dialog.props('showClose')).toBe(false) expect(dialog.props('closeOnClickModal')).toBe(false) expect(dialog.props('closeOnPressEscape')).toBe(false) expect(cancelButton.attributes('disabled')).toBeDefined() }) it('can render a content-only dialog without footer actions', () => { const wrapper = mountDialog({ showFooter: false }) expect(wrapper.findAll('button')).toHaveLength(0) }) it('keeps the dialog chrome fixed while long content scrolls in the body', () => { const source = readFileSync(resolve(process.cwd(), 'src/shared/components/AppDialog.vue'), 'utf8') expect(source).toContain(':global(.app-dialog.el-dialog) { display: flex;') expect(source).toContain(':global(.app-dialog .el-dialog__body) { min-height: 0; overflow-y: auto;') expect(source).toContain('max-height: calc(100svh - 20px)') }) })