import { mount } from '@vue/test-utils';
import { nextTick, ref } from 'vue';
import DModal from '../src/modal';
import DModalHeader from '../src/components/header';
import DModalFooter from '../src/components/footer';
import DIcon from '../../icon/src/icon';
import { useNamespace } from '../../shared/hooks/use-namespace';
import { wait } from '../../shared/utils/';
const ns = useNamespace('modal', true);
const noDotNs = useNamespace('modal');
const noDotIconNs = useNamespace('icon');
const buttonNoDotNs = useNamespace('button');
describe('d-modal', () => {
beforeEach(() => {
const overlayAnchor = document.createElement('div');
overlayAnchor.setAttribute('id', 'd-overlay-anchor');
overlayAnchor.style.position = 'fixed';
overlayAnchor.style.left = '0';
overlayAnchor.style.top = '0';
overlayAnchor.style.zIndex = '1000';
document.body.appendChild(overlayAnchor);
});
afterEach(() => {
const overlayAnchor = document.querySelector('#d-overlay-anchor');
overlayAnchor && document.body.removeChild(overlayAnchor);
});
it('render correctly', async () => {
const visible = ref(true);
const wrapper = mount({
setup() {
return () => (
<DModal v-model={visible.value} title="Start Snapshot Version">
{{
default: () => (
<>
<div>name: Tom</div>
<div>age: 20</div>
<div>address: Chengdu</div>
</>
),
}}
</DModal>
);
},
});
await wait(100);
await nextTick();
const modal = document.querySelector(ns.b());
expect(modal).toBeTruthy();
expect(modal?.childElementCount).toBe(3);
expect((modal?.childNodes[0] as HTMLElement).className).toContain('btn-close');
expect((modal?.childNodes[1].childNodes[0] as HTMLElement).className).toContain(noDotNs.e('header'));
expect((modal?.childNodes[2] as HTMLElement).className).toContain(noDotNs.e('body'));
wrapper.unmount();
});
it('custom header', async () => {
const visible = ref(false);
const wrapper = mount({
setup() {
return () => (
<DModal v-model={visible.value}>
{{
header: () => (
<DModalHeader>
<DIcon name="like"></DIcon>
<span>Good Title</span>
</DModalHeader>
),
default: () => (
<>
<div>name: Tom</div>
<div>age: 20</div>
<div>address: Chengdu</div>
</>
),
}}
</DModal>
);
},
});
await wait(100);
await nextTick();
visible.value = true;
await wait(100);
await nextTick();
const modalHeader = document.querySelector(ns.e('header'));
expect(modalHeader?.children[0]?.className).toContain(noDotIconNs.e('container'));
expect(modalHeader?.children[1].innerHTML).toContain('Good Title');
expect(modalHeader?.childElementCount).toBe(2);
wrapper.unmount();
});
it('custom footer', async () => {
const visible = ref(false);
const wrapper = mount({
setup() {
return () => (
<DModal v-model={visible.value} title="Start Snapshot Version">
{{
default: () => (
<>
<div>name: Tom</div>
<div>age: 20</div>
<div>address: Chengdu</div>
</>
),
footer: () => (
<DModalFooter>
<d-button>取消</d-button>
<d-button>确认</d-button>
</DModalFooter>
),
}}
</DModal>
);
},
});
await wait(100);
await nextTick();
visible.value = true;
await wait(100);
await nextTick();
const modalFooter = document.querySelector(ns.e('footer'));
expect(modalFooter?.children[0].className).toContain(buttonNoDotNs.b());
expect(modalFooter?.children[1].className).toContain(buttonNoDotNs.b());
expect(modalFooter?.childElementCount).toBe(2);
wrapper.unmount();
});
it('before-close', async () => {
const visible = ref(false);
const beforeClose = jest.fn();
const wrapper = mount({
setup() {
return () => (
<DModal v-model={visible.value} title="Start Snapshot Version" before-close={beforeClose}>
{{
default: () => (
<>
<div>name: Tom</div>
<div>age: 20</div>
<div>address: Chengdu</div>
</>
),
}}
</DModal>
);
},
});
await wait(100);
await nextTick();
visible.value = true;
await wait(100);
await nextTick();
const btnClose = document.querySelector('.btn-close');
await btnClose?.dispatchEvent(new Event('click'));
expect(beforeClose).toBeCalled();
wrapper.unmount();
});
it.todo('props lock-scroll work well.');
it('props close-on-click-overlay work well.', async () => {
const visible = ref(false);
const closeClickOverlay = ref(true);
const wrapper = mount({
setup() {
return () => (
<DModal v-model={visible.value} title="Start Snapshot Version" close-on-click-overlay={closeClickOverlay.value}>
{{
default: () => (
<>
<div>name: Tom</div>
<div>age: 20</div>
<div>address: Chengdu</div>
</>
),
}}
</DModal>
);
},
});
await wait(100);
await nextTick();
visible.value = true;
await wait(100);
await nextTick();
let overlay = document.querySelector(ns.e('overlay'));
await overlay?.dispatchEvent(new Event('click'));
await wait(100);
await nextTick();
expect(document.querySelector(ns.b())).toBeFalsy();
closeClickOverlay.value = false;
visible.value = true;
await wait(100);
await nextTick();
overlay = document.querySelector(ns.e('container'));
await overlay?.dispatchEvent(new Event('click'));
await wait(100);
await nextTick();
expect(document.querySelector(ns.b())).toBeTruthy();
wrapper.unmount();
});
it('props escapable work well.', async () => {
const visible = ref(false);
const wrapper = mount({
setup() {
return () => (
<DModal v-model={visible.value} title="Start Snapshot Version">
{{
default: () => (
<>
<div>name: Tom</div>
<div>age: 20</div>
<div>address: Chengdu</div>
</>
),
}}
</DModal>
);
},
});
await wait(100);
await nextTick();
visible.value = true;
await wait(100);
await nextTick();
await window.dispatchEvent(new KeyboardEvent('keydown', { code: 'Escape' }));
await wait(100);
await nextTick();
expect(document.querySelector(ns.b())).toBeFalsy();
wrapper.unmount();
});
it('autofocus work well.', async () => {
const visible = ref(false);
const wrapper = mount({
setup() {
return () => (
<DModal v-model={visible.value} title="Start Snapshot Version">
{{
default: () => (
<>
<div>name: Tom</div>
<div>age: 20</div>
<div>address: Chengdu</div>
</>
),
footer: () => (
<DModalFooter>
{/* 给取消按钮加click事件 */}
<d-button class="btn-cancel" autofocus onClick={(visible.value = false)}>
取消
</d-button>
<d-button>确认</d-button>
</DModalFooter>
),
}}
</DModal>
);
},
});
await wait(100);
await nextTick();
visible.value = true;
await wait(100);
await nextTick();
const btnConfirm = document.querySelector('.btn-cancel');
await btnConfirm?.dispatchEvent(new KeyboardEvent('keydown', { code: 'Enter' }));
await wait(100);
await nextTick();
expect(document.querySelector(ns.b())).toBeFalsy();
wrapper.unmount();
});
});