/* eslint-disable jsx-a11y/control-has-associated-label */ import React, { useEffect } from 'react'; import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs'; import message from '..'; import { act, fireEvent, render } from '../../../tests/utils'; import ConfigProvider from '../../config-provider'; import { triggerMotionEnd } from './util'; describe('message.hooks', () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.useRealTimers(); }); it('should work', () => { const Context = React.createContext('light'); const Demo: React.FC = () => { const [api, holder] = message.useMessage(); return ( {holder} ); }; const { container } = render(); fireEvent.click(container.querySelector('button')!); expect(document.querySelectorAll('.my-test-message-notice')).toHaveLength(1); expect(document.querySelector('.hook-test-result')!.textContent).toEqual('bamboo'); }); it('should work with success', () => { const Context = React.createContext('light'); const Demo: React.FC = () => { const [api, holder] = message.useMessage(); return ( {holder} ); }; const { container } = render(); fireEvent.click(container.querySelector('button')!); expect(document.querySelectorAll('.my-test-message-notice')).toHaveLength(1); expect(document.querySelectorAll('.anticon-check-circle')).toHaveLength(1); expect(document.querySelector('.hook-test-result')!.textContent).toEqual('bamboo'); }); it('should work with onClose', (done) => { const Demo = () => { const [api, holder] = message.useMessage(); return ( <> {holder} ); }; const { container } = render(); fireEvent.click(container.querySelector('button')!); triggerMotionEnd(); }); it('should work with close promise', (done) => { const Demo = () => { const [api, holder] = message.useMessage(); return ( <> {holder} ); }; const { container } = render(); fireEvent.click(container.querySelector('button')!); triggerMotionEnd(); }); it('should work with hide', async () => { let hide: VoidFunction; const Demo = () => { const [api, holder] = message.useMessage(); return ( {holder} ); }; const { container } = render(); fireEvent.click(container.querySelector('button')!); expect(document.querySelectorAll('.my-test-message-notice')).toHaveLength(1); act(() => { hide!(); }); await triggerMotionEnd('.my-test-message-move-up-leave'); expect(document.querySelectorAll('.my-test-message-notice')).toHaveLength(0); }); it('should be same hook', () => { let cacheAPI: any; const Demo: React.FC = () => { const [, forceUpdate] = React.useState([]); const [api] = message.useMessage(); React.useEffect(() => { if (!cacheAPI) { cacheAPI = api; } else { expect(cacheAPI).toBe(api); } forceUpdate([]); }, [api]); return null; }; render(); }); it("should use ConfigProvider's getPopupContainer as message container", () => { const containerId = 'container'; const div = document.createElement('div'); div.id = containerId; document.body.appendChild(div); const getPopupContainer = () => div; const Demo = () => { const [api, holder] = message.useMessage(); return ( {holder} ); }; const { container } = render(); fireEvent.click(container.querySelector('button')!); expect(div.querySelectorAll('.my-test-message-notice')).toHaveLength(1); expect(div.querySelectorAll('.anticon-check-circle')).toHaveLength(1); expect(div.querySelector('.hook-content')!.textContent).toEqual('happy'); expect(document.querySelectorAll(`#${containerId}`)).toHaveLength(1); }); it('warning if user call update in render', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const Demo = () => { const [api, holder] = message.useMessage(); const calledRef = React.useRef(false); if (!calledRef.current) { api.info({ content:
, }); calledRef.current = true; } return holder; }; render(); expect(document.querySelector('.bamboo')).toBeFalsy(); expect(errorSpy).toHaveBeenCalledWith( 'Warning: [antd: Message] You are calling notice in render which will break in React 18 concurrent mode. Please trigger in effect instead.', ); errorSpy.mockRestore(); }); it('not export style in SSR', () => { const cache = createCache(); const Demo = () => { const [, holder] = message.useMessage(); return {holder}; }; render(); const styleText = extractStyle(cache, true); expect(styleText).not.toContain('.ant-message'); }); it('component fontSize should work', () => { const Demo = () => { const [api, holder] = message.useMessage(); useEffect(() => { api.info({ content:
, className: 'fontSize', }); }, []); return ( {holder} ); }; render(); const msg = document.querySelector('.fontSize'); expect(msg).toBeTruthy(); expect(msg).toHaveStyle({ fontSize: '20px', }); }); });