modal.test.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. import { Modal } from '../../index';
  2. // import toJson from 'enzyme-to-json';
  3. import { clear } from 'jest-date-mock';
  4. import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
  5. import { cssClasses } from '@douyinfe/semi-foundation/icons/constants';
  6. import { IconEyeClosed } from '@douyinfe/semi-icons';
  7. const prefixCls = cssClasses.PREFIX;
  8. function getModal(modalProps, children) {
  9. let props = modalProps ? modalProps : {};
  10. return (
  11. <Modal
  12. motion={false}
  13. {...props}
  14. >
  15. {children ? children : <p>This is content of basic modal</p>}
  16. </Modal>
  17. );
  18. }
  19. function mountToBody(component) {
  20. return mount(component, { attachTo: document.getElementById('container') });
  21. }
  22. describe('modal', () => {
  23. beforeEach(() => {
  24. // Avoid `attachTo: document.body` Warning
  25. const div = document.createElement('div');
  26. div.setAttribute('id', 'container');
  27. document.body.appendChild(div);
  28. clear();
  29. });
  30. afterEach(() => {
  31. document.body.innerHTML = '';
  32. });
  33. it('className / style / maskStyle / bodyStyle / zIndex', () => {
  34. let component = getModal({
  35. className: 'test',
  36. style: { color: 'red' },
  37. visible: true,
  38. maskStyle: { color: 'grey' },
  39. bodyStyle: { color: 'pink' },
  40. zIndex: 500,
  41. });
  42. let modal = mount(component, { attachTo: document.getElementById('container') });
  43. // let modal = mount(component, { attachTo: document.body });
  44. // test className
  45. expect(modal.exists('div.test')).toEqual(true);
  46. // test style
  47. expect(modal.find(`.${BASE_CLASS_PREFIX}-modal`)).toHaveStyle('color', 'red')
  48. // test bodyStyle
  49. expect(modal.find(`.${BASE_CLASS_PREFIX}-modal-body`)).toHaveStyle('color', 'pink');
  50. // test maskStyle
  51. expect(modal.find(`.${BASE_CLASS_PREFIX}-modal-mask`)).toHaveStyle('color', 'grey');
  52. // test zIndex
  53. expect(document.querySelector(`.${BASE_CLASS_PREFIX}-portal`).style.zIndex).toEqual("500");
  54. modal.unmount();
  55. });
  56. it('visible', (done) => {
  57. let component = getModal();
  58. let modal = mount(component, { attachTo: document.getElementById('container') });
  59. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(false);
  60. // set true
  61. modal.setProps({ visible: true });
  62. modal.update(); // 必须调用一次update
  63. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(true);
  64. expect(document.body.style.overflow).toEqual('hidden');
  65. // set false
  66. modal.setProps({ visible: false });
  67. modal.update(); // 必须调用一次update
  68. expect(document.body.style.overflow).not.toEqual('hidden');
  69. setTimeout(() => {
  70. expect(document.querySelector(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(null);
  71. done();
  72. }, 2000);
  73. });
  74. it('render basic content', () => {
  75. let com = getModal({ title: 'SemiTitle', visible: true })
  76. let modal = mount(com, { attachTo: document.getElementById('container') });
  77. // test title
  78. let sheetTitle = document.querySelector(`.${BASE_CLASS_PREFIX}-modal-title`);
  79. expect(sheetTitle.textContent).toEqual('SemiTitle');
  80. // test content
  81. let sheetContent = document.querySelector(`.${BASE_CLASS_PREFIX}-modal-body`);
  82. // the content in getModal could not be overwritten
  83. expect(sheetContent.textContent).toEqual('This is content of basic modal');
  84. modal.unmount();
  85. });
  86. it('footer / header', () => {
  87. let com = getModal({ header: (<p>This is a header</p>), footer: (<p>This is a footer</p>), visible: true })
  88. let modal = mount(com, { attachTo: document.getElementById('container') });
  89. expect(modal.find(`.${BASE_CLASS_PREFIX}-modal-content`).children().at(0).html()).toEqual('<p>This is a header</p>');
  90. expect(modal.find(`.${BASE_CLASS_PREFIX}-modal-footer`).contains(<p>This is a footer</p>)).toEqual(true);
  91. // test null
  92. modal.setProps({ header: null, footer: null });
  93. let content = modal.find(`.${BASE_CLASS_PREFIX}-modal-content`).children();
  94. expect(content.length).toEqual(1);
  95. expect(content.text()).toEqual('This is content of basic modal')
  96. modal.unmount();
  97. });
  98. it('height / width', () => {
  99. let com = getModal({ width: '413px', height: '613px', visible: true })
  100. let modal = mount(com, { attachTo: document.getElementById('container') });
  101. let dom = modal.find(`.${BASE_CLASS_PREFIX}-modal`).getDOMNode();
  102. expect(window.getComputedStyle(dom).width).toEqual('413px')
  103. expect(window.getComputedStyle(dom).height).toEqual('613px')
  104. modal.unmount();
  105. });
  106. it('size', () => {
  107. let com = getModal({ size: 'small', visible: true })
  108. let modal = mount(com, { attachTo: document.getElementById('container') });
  109. expect(modal.exists(`.${BASE_CLASS_PREFIX}-modal-small`)).toEqual(true);
  110. // test medium size
  111. modal.setProps({ size: 'medium' });
  112. expect(modal.exists(`.${BASE_CLASS_PREFIX}-modal-medium`)).toEqual(true);
  113. // test large size
  114. modal.setProps({ size: 'large' });
  115. expect(modal.exists(`.${BASE_CLASS_PREFIX}-modal-large`)).toEqual(true);
  116. // test full-width
  117. modal.setProps({ size: 'full-width' });
  118. expect(modal.exists(`.${BASE_CLASS_PREFIX}-modal-full-width`)).toEqual(true);
  119. modal.unmount();
  120. });
  121. it('closable', () => {
  122. let closeCom = getModal({ closable: true, visible: true });
  123. let nocloseCom = getModal({ closable: false, visible: true });
  124. let modal = mount(closeCom, { attachTo: document.getElementById('container') });
  125. expect(modal.exists(`.${BASE_CLASS_PREFIX}-modal-close`)).toEqual(true);
  126. modal.unmount();
  127. let notClosableSideSheet = mount(nocloseCom, { attachTo: document.getElementById('container') });
  128. expect(notClosableSideSheet.exists(`.${BASE_CLASS_PREFIX}-modal-close`)).toEqual(false);
  129. notClosableSideSheet.unmount();
  130. });
  131. it('getPopupContainer', () => {
  132. let containedcom = (
  133. <div
  134. style={{
  135. height: 320,
  136. overflow: 'hidden',
  137. position: 'relative',
  138. }}
  139. className='modal-container'
  140. >
  141. <Modal
  142. visible={true}
  143. getPopupContainer={() => document.querySelector('.modal-container')}
  144. />
  145. </div>
  146. )
  147. let wrapper = mount(containedcom, { attachTo: document.getElementById('container') });
  148. let container = document.querySelector('.modal-container').querySelector(`.${BASE_CLASS_PREFIX}-modal`);
  149. expect(wrapper.find(`div.${BASE_CLASS_PREFIX}-modal`).html()).toEqual(container.outerHTML);
  150. });
  151. it('maskClosable', () => {
  152. let onCancel = () => { };
  153. let spyOnCancel = sinon.spy(onCancel);
  154. let spyOnCancel2 = sinon.spy(onCancel);
  155. let closeCom = getModal({
  156. maskClosable: true,
  157. visible: true,
  158. onCancel: spyOnCancel
  159. });
  160. let modal = mount(closeCom, { attachTo: document.getElementById('container') });
  161. // maskClosable
  162. modal.find(`.${BASE_CLASS_PREFIX}-modal-wrap`).simulate('click');
  163. expect(spyOnCancel.calledOnce).toBe(true);
  164. modal.unmount();
  165. // mask not closable
  166. let notMaskClosableSideSheet = mount(getModal({
  167. maskClosable: false,
  168. visible: true,
  169. onCancel: spyOnCancel2
  170. }), { attachTo: document.getElementById('container') });
  171. notMaskClosableSideSheet.find(`.${BASE_CLASS_PREFIX}-modal-wrap`).simulate('click');
  172. expect(spyOnCancel2.calledOnce).toBe(false);
  173. notMaskClosableSideSheet.unmount();
  174. });
  175. it('button props: cancelText / okText / okButtonProps / cancelButtonProps / hasCancel / confirmLoading ', () => {
  176. let component = getModal({
  177. cancelText: 'cancel',
  178. okText: 'ok',
  179. okType: 'secondary',
  180. visible: true,
  181. // remove close btn to avoid selected by selector
  182. closable: false,
  183. });
  184. let modal = mount(component, { attachTo: document.getElementById('container') });
  185. let footerBtn = modal.find(`.${BASE_CLASS_PREFIX}-button`)
  186. expect(footerBtn.at(0).text()).toEqual('cancel');
  187. expect(footerBtn.at(1).text()).toEqual('ok');
  188. expect(footerBtn.at(1)).toHaveClassName(`${BASE_CLASS_PREFIX}-button-secondary`);
  189. // test passing props
  190. modal.setProps({
  191. okButtonProps: { size: 'small', type: 'warning' },
  192. cancelButtonProps: { size: 'small', disabled: true }
  193. });
  194. footerBtn = modal.find(`.${BASE_CLASS_PREFIX}-button`)
  195. expect(footerBtn.at(0)).toHaveClassName(`${BASE_CLASS_PREFIX}-button-disabled ${BASE_CLASS_PREFIX}-button-size-small`);
  196. expect(footerBtn.at(1)).toHaveClassName(`${BASE_CLASS_PREFIX}-button-warning ${BASE_CLASS_PREFIX}-button-size-small`);
  197. // ok Btn loading, no cancel
  198. modal.setProps({
  199. hasCancel: false,
  200. confirmLoading: true,
  201. });
  202. footerBtn = modal.find(`.${BASE_CLASS_PREFIX}-button`)
  203. expect(footerBtn.length).toEqual(1);
  204. expect(footerBtn.at(0)).toHaveClassName(`${BASE_CLASS_PREFIX}-button-loading`);
  205. });
  206. it('onCancel / onOk', () => {
  207. // onCancel on close btn
  208. // debugger
  209. let onCancel = () => { };
  210. let onOk = () => { };
  211. let spyOnCancel = sinon.spy(onCancel);
  212. let spyOnOk = sinon.spy(onOk);
  213. let closeCom = getModal({
  214. visible: true,
  215. onCancel: spyOnCancel,
  216. onOk: spyOnOk
  217. });
  218. let modal = mount(closeCom, { attachTo: document.getElementById('container') });
  219. let btn = modal.find(`.${BASE_CLASS_PREFIX}-button`)
  220. modal.find(`button.${BASE_CLASS_PREFIX}-modal-close`).simulate('click');
  221. btn.at(1).simulate('click');
  222. btn.at(2).simulate('click');
  223. expect(spyOnCancel.calledTwice).toBe(true);
  224. expect(spyOnOk.calledOnce).toBe(true);
  225. });
  226. it('no mask', () => {
  227. let com = getModal({
  228. mask: false,
  229. visible: true,
  230. });
  231. let modal = mount(com, { attachTo: document.getElementById('container') });
  232. expect(modal.exists(`.${BASE_CLASS_PREFIX}-modal-mask`)).toEqual(false);
  233. });
  234. it('closeIcon', () => {
  235. let com = getModal({
  236. visible: true,
  237. closeIcon: (<IconEyeClosed />)
  238. });
  239. let modal = mount(com, { attachTo: document.getElementById('container') });
  240. expect(modal.find(`.${BASE_CLASS_PREFIX}-icon-eye_closed`).length).toBe(1);
  241. });
  242. it('motion false', () => {
  243. let com = getModal({ visible: true, motion: false });
  244. let modal = mount(com, { attachTo: document.getElementById('container') });
  245. expect(modal.find(`div.${BASE_CLASS_PREFIX}-modal`)).not.toHaveStyle('transform');
  246. // visible false
  247. modal.setProps({ visible: false });
  248. modal.update(); // 必须调用一次update
  249. expect(document.querySelector(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(null);
  250. });
  251. it('centered', (done) => {
  252. let com = getModal({ centered: true, visible: true, motion: true });
  253. let modal = mount(com, { attachTo: document.getElementById('container') });
  254. setTimeout(() => {
  255. modal.update();
  256. expect(modal.find(`div.${BASE_CLASS_PREFIX}-modal-content`)).toHaveClassName(`semi-modal-content-animate-show`);
  257. done();
  258. }, 2000);
  259. });
  260. it('centered without motion', () => {
  261. let com = getModal({ centered: true, visible: true, motion: false });
  262. let modal = mount(com, { attachTo: document.getElementById('container') });
  263. expect(modal.find(`div.${BASE_CLASS_PREFIX}-modal-wrap`)).toHaveClassName(`${BASE_CLASS_PREFIX}-modal-wrap-center`)
  264. });
  265. it('keepDOM', () => {
  266. let component = getModal({ keepDOM: true });
  267. let modal = mount(component, { attachTo: document.getElementById('container') });
  268. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(false);
  269. // set true
  270. modal.setProps({ visible: true });
  271. modal.update(); // 必须调用一次update
  272. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(true);
  273. expect(document.body.style.overflow).toEqual('hidden');
  274. // set false but still exist
  275. modal.setProps({ visible: false });
  276. modal.update(); // 必须调用一次update
  277. expect(modal.state().displayNone).toEqual(true);
  278. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(true);
  279. });
  280. it('keepDOM + lazyRender=false', () => {
  281. let component = getModal({ keepDOM: true, lazyRender: false });
  282. let modal = mount(component, { attachTo: document.getElementById('container') });
  283. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(true);
  284. // set true
  285. modal.setProps({ visible: true });
  286. modal.update(); // 必须调用一次update
  287. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(true);
  288. expect(document.body.style.overflow).toEqual('hidden');
  289. // set false but still exist
  290. modal.setProps({ visible: false });
  291. modal.update(); // 必须调用一次update
  292. expect(modal.state().displayNone).toEqual(true);
  293. expect(modal.exists(`div.${BASE_CLASS_PREFIX}-modal`)).toEqual(true);
  294. });
  295. it('modal render', () => {
  296. const testClass = 'modal-render-test'
  297. let com = getModal({
  298. visible: true,
  299. modalRender: (modal) => (
  300. <div className={testClass}>
  301. {modal}
  302. </div>
  303. )
  304. });
  305. let modal = mount(com, { attachTo: document.getElementById('container') });
  306. expect(modal.exists(`div.${testClass}`)).toEqual(true);
  307. modal.unmount();
  308. });
  309. })