import { LikeOutlined, SmileOutlined } from '@ant-design/icons'; import * as copyObj from 'copy-to-clipboard'; import React from 'react'; import { fireEvent, render, waitFor, act } from '../../../tests/utils'; import Base from '../Base'; describe('Typography copy', () => { const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); afterEach(() => { errorSpy.mockReset(); }); describe('Base', () => { describe('copyable', () => { function copyTest({ name, icon, tooltips, iconClassNames = [], iconTexts = [], tooltipTexts = [], tooltipLength, }: { name: string; icon?: boolean | React.ReactNode; tooltips?: boolean | React.ReactNode; iconClassNames?: string[]; iconTexts?: string[]; tooltipTexts?: string[]; tooltipLength?: number; }) { it(name, async () => { jest.useFakeTimers(); const { container: wrapper, unmount } = render( test copy , ); if (iconClassNames[0] !== undefined) { expect(wrapper.querySelector(iconClassNames[0])).not.toBeNull(); } if (iconTexts[0] !== undefined) { expect(wrapper.querySelectorAll('.ant-typography-copy')[0].textContent).toBe( iconTexts[0], ); } fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); jest.runAllTimers(); if (tooltipTexts[0] !== undefined) { await waitFor(() => { expect(wrapper.querySelector('.ant-tooltip-inner')?.textContent).toBe( tooltipTexts[0], ); }); } if (tooltipLength !== undefined) { await waitFor(() => { expect(wrapper.querySelectorAll('.ant-tooltip-inner').length).toBe(tooltipLength); }); } fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); jest.useRealTimers(); if (iconClassNames[1] !== undefined) { expect(wrapper.querySelector(iconClassNames[1])).not.toBeNull(); } fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); fireEvent.mouseEnter(wrapper.querySelectorAll('.ant-typography-copy')[0]); if (tooltipTexts[1] !== undefined) { const expectedInner = tooltipTexts[1] === '' ? tooltipTexts[0] : tooltipTexts[1]; await waitFor(() => { expect(wrapper.querySelector('.ant-tooltip-inner')?.textContent).toBe(expectedInner); }); } if (iconTexts[1] !== undefined) { expect(wrapper.querySelectorAll('.ant-typography-copy')[0].textContent).toBe( iconTexts[1], ); } jest.useFakeTimers(); fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); act(() => { jest.runAllTimers(); }); unmount(); jest.useRealTimers(); }); } const dom = ( <> 12 ); const dom2 = ( <> 34 ); const copy = '.anticon-copy'; const check = '.anticon-check'; copyTest({ name: 'icon basic copy', iconClassNames: [copy, check], tooltipTexts: ['Copy', 'Copied'], }); copyTest({ name: 'icon true', icon: true, iconClassNames: [copy, check] }); copyTest({ name: 'icon two true', icon: [true, true], iconClassNames: [copy, check] }); copyTest({ name: 'icon false', icon: false, iconClassNames: [copy, check] }); copyTest({ name: 'icon custom text', icon: ['a', 'b'], iconTexts: ['a', 'b'] }); copyTest({ name: 'icon custom element', icon: [dom, dom2], iconTexts: ['12', '34'] }); copyTest({ name: 'icon custom icon', icon: , iconClassNames: ['.anticon-smile', check], }); copyTest({ name: 'icon custom icon2', icon: [, ], iconClassNames: ['.anticon-smile', '.anticon-like'], }); copyTest({ name: 'icon custom icon3', icon: [ <> , , ], iconClassNames: ['.anticon-smile', '.anticon-like'], }); copyTest({ name: 'icon custom icon4', icon: ( <> ), iconClassNames: ['.anticon-smile', check], }); copyTest({ name: 'icon custom icon5', icon: ( <> ), iconClassNames: ['.anticon-like', check], }); copyTest({ name: 'tooltips true', tooltips: true, tooltipLength: 1, tooltipTexts: ['Copy', 'Copied'], }); copyTest({ name: 'tooltips false', tooltips: false, tooltipLength: 0 }); copyTest({ name: 'tooltips custom text', tooltips: ['a', 'b'], tooltipLength: 1, tooltipTexts: ['a', 'b'], }); copyTest({ name: 'tooltips custom element ', tooltips: [dom, dom2], tooltipTexts: ['12', '34'], }); copyTest({ name: 'tooltips first empty', tooltips: ['', 'xxx'], tooltipLength: 0, }); copyTest({ name: 'tooltips first empty 2', tooltips: [''], tooltipLength: 0, }); copyTest({ name: 'tooltips true true', tooltips: [true, true], tooltipTexts: ['Copy', 'Copied'], }); copyTest({ name: 'tooltips true false', tooltips: [true, false], tooltipTexts: ['Copy', ''], }); copyTest({ name: 'tooltips false true', tooltips: [false, true], tooltipLength: 0, }); }); it('copy click event stopPropagation', () => { const onDivClick = jest.fn(); const { container: wrapper } = render(
test copy
, ); fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); expect(onDivClick).not.toHaveBeenCalled(); }); it('the first parameter of onCopy is the click event', () => { function onCopy(e: React.MouseEvent) { expect(e).not.toBeUndefined(); } const { container: wrapper } = render( test copy , ); fireEvent.click(wrapper.querySelectorAll('.ant-typography-copy')[0]); }); it('copy to clipboard', () => { jest.useFakeTimers(); const spy = jest.spyOn(copyObj, 'default'); const originText = 'origin text.'; const nextText = 'next text.'; const Test = () => { const [dynamicText, setDynamicText] = React.useState(originText); React.useEffect(() => { setTimeout(() => { setDynamicText(nextText); }, 500); }, []); return ( {dynamicText} ); }; const { container: wrapper } = render(); const copyBtn = wrapper.querySelectorAll('.ant-typography-copy')[0]; fireEvent.click(copyBtn); expect(spy.mock.calls[0][0]).toEqual(originText); act(() => { jest.runAllTimers(); }); spy.mockReset(); fireEvent.click(copyBtn); expect(spy.mock.calls[0][0]).toEqual(nextText); jest.useRealTimers(); }); }); });