Skip to content

Commit

Permalink
[Security Solution][Resolver] Replace copy-to-clipboard with native n…
Browse files Browse the repository at this point in the history
…avigator.clipboard (elastic#80193)
  • Loading branch information
michaelolo24 authored Oct 13, 2020
1 parent 6ab4be5 commit 5bf7966
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { createMemoryHistory, History as HistoryPackageHistoryInterface } from 'history';
import copy from 'copy-to-clipboard';
import { noAncestorsTwoChildrenWithRelatedEventsOnOrigin } from '../data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin';
import { Simulator } from '../test_utilities/simulator';
// Extend jest with a custom matcher
Expand All @@ -14,10 +13,6 @@ import { urlSearch } from '../test_utilities/url_search';
// the resolver component instance ID, used by the react code to distinguish piece of global state from those used by other resolver instances
const resolverComponentInstanceID = 'resolverComponentInstanceID';

jest.mock('copy-to-clipboard', () => {
return jest.fn();
});

describe(`Resolver: when analyzing a tree with no ancestors and two children and two related registry event on the origin, and when the component instance ID is ${resolverComponentInstanceID}`, () => {
/**
* Get (or lazily create and get) the simulator.
Expand Down Expand Up @@ -121,8 +116,8 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children and

copyableFields?.map((copyableField) => {
copyableField.simulate('mouseenter');
simulator().testSubject('clipboard').last().simulate('click');
expect(copy).toHaveBeenLastCalledWith(copyableField.text(), expect.any(Object));
simulator().testSubject('resolver:panel:clipboard').last().simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(copyableField.text());
copyableField.simulate('mouseleave');
});
});
Expand Down Expand Up @@ -179,8 +174,8 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children and

copyableFields?.map((copyableField) => {
copyableField.simulate('mouseenter');
simulator().testSubject('clipboard').last().simulate('click');
expect(copy).toHaveBeenLastCalledWith(copyableField.text(), expect.any(Object));
simulator().testSubject('resolver:panel:clipboard').last().simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(copyableField.text());
copyableField.simulate('mouseleave');
});
});
Expand Down Expand Up @@ -288,8 +283,8 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children and

copyableFields?.map((copyableField) => {
copyableField.simulate('mouseenter');
simulator().testSubject('clipboard').last().simulate('click');
expect(copy).toHaveBeenLastCalledWith(copyableField.text(), expect.any(Object));
simulator().testSubject('resolver:panel:clipboard').last().simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(copyableField.text());
copyableField.simulate('mouseleave');
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

/* eslint-disable react/display-name */

import { EuiToolTip, EuiPopover } from '@elastic/eui';
import { EuiToolTip, EuiButtonIcon, EuiPopover } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import styled from 'styled-components';
import React, { memo, useState } from 'react';
import { WithCopyToClipboard } from '../../../common/lib/clipboard/with_copy_to_clipboard';
import React, { memo, useState, useCallback } from 'react';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { useColors } from '../use_colors';
import { StyledPanel } from '../styles';

Expand Down Expand Up @@ -43,8 +43,10 @@ export const CopyablePanelField = memo(
({ textToCopy, content }: { textToCopy: string; content: JSX.Element | string }) => {
const { linkColor, copyableFieldBackground } = useColors();
const [isOpen, setIsOpen] = useState(false);
const toasts = useKibana().services.notifications?.toasts;

const onMouseEnter = () => setIsOpen(true);
const onMouseLeave = () => setIsOpen(false);

const ButtonContent = memo(() => (
<StyledCopyableField
Expand All @@ -57,7 +59,22 @@ export const CopyablePanelField = memo(
</StyledCopyableField>
));

const onMouseLeave = () => setIsOpen(false);
const onClick = useCallback(
async (event: React.MouseEvent<HTMLButtonElement>) => {
try {
await navigator.clipboard.writeText(textToCopy);
} catch (error) {
if (toasts) {
toasts.addError(error, {
title: i18n.translate('xpack.securitySolution.resolver.panel.copyFailureTitle', {
defaultMessage: 'Copy Failure',
}),
});
}
}
},
[textToCopy, toasts]
);

return (
<div onMouseLeave={onMouseLeave}>
Expand All @@ -74,10 +91,14 @@ export const CopyablePanelField = memo(
defaultMessage: 'Copy to Clipboard',
})}
>
<WithCopyToClipboard
data-test-subj="resolver:panel:copy-to-clipboard"
text={textToCopy}
titleSummary={textToCopy}
<EuiButtonIcon
aria-label={i18n.translate('xpack.securitySolution.resolver.panel.copyToClipboard', {
defaultMessage: 'Copy to Clipboard',
})}
color="text"
data-test-subj="resolver:panel:clipboard"
iconType="copyClipboard"
onClick={onClick}
/>
</EuiToolTip>
</EuiPopover>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ export const sideEffectSimulatorFactory: () => SideEffectSimulator = () => {
return contentRectForElement(this);
});

/**
* Mock the global writeText method as it is not available in jsDOM and alows us to track what was copied
*/
const MockClipboard: Clipboard = {
writeText: jest.fn(),
readText: jest.fn(),
addEventListener: jest.fn(),
dispatchEvent: jest.fn(),
removeEventListener: jest.fn(),
};
// @ts-ignore navigator doesn't natively exist on global
global.navigator.clipboard = MockClipboard;
/**
* A mock implementation of `ResizeObserver` that works with our fake `getBoundingClientRect` and `simulateElementResize`
*/
Expand Down

0 comments on commit 5bf7966

Please sign in to comment.