diff --git a/packages/core-components/src/components/CopyTextButton/CopyTextButton.test.tsx b/packages/core-components/src/components/CopyTextButton/CopyTextButton.test.tsx
index 9e3a94ee45..b84d3919e8 100644
--- a/packages/core-components/src/components/CopyTextButton/CopyTextButton.test.tsx
+++ b/packages/core-components/src/components/CopyTextButton/CopyTextButton.test.tsx
@@ -19,12 +19,9 @@ import { fireEvent } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { renderInTestApp } from '@backstage/test-utils';
import { CopyTextButton } from './CopyTextButton';
-import { ApiRegistry, ApiProvider } from '@backstage/core-app-api';
+import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { errorApiRef, ErrorApi } from '@backstage/core-plugin-api';
-// should we add this to dev dependencies?
-// (already a dependency of react-use)
-// eslint-disable-next-line import/no-extraneous-dependencies
-import copy from 'copy-to-clipboard';
+import { useCopyToClipboard } from 'react-use';
jest.mock('popper.js', () => {
const PopperJS = jest.requireActual('popper.js');
@@ -37,6 +34,17 @@ jest.mock('popper.js', () => {
};
});
+jest.mock('react-use', () => {
+ const original = jest.requireActual('react-use');
+
+ return {
+ ...original,
+ useCopyToClipboard: jest
+ .fn()
+ .mockImplementation(original.useCopyToClipboard),
+ };
+});
+
const props = {
text: 'mockText',
tooltipDelay: 2,
@@ -47,29 +55,30 @@ const apiRegistry = ApiRegistry.from([
[
errorApiRef,
{
- post(error) {
- throw error;
- },
+ post: jest.fn(),
error$: jest.fn(),
} as ErrorApi,
],
]);
-jest.mock('copy-to-clipboard', () => jest.fn());
-
describe('', () => {
it('renders without exploding', async () => {
- const { getByTestId } = await renderInTestApp(
+ const { getByTitle, queryByText } = await renderInTestApp(
,
);
- expect(getByTestId('copy-button')).toBeInTheDocument();
+ expect(getByTitle('mockTooltip')).toBeInTheDocument();
+ expect(queryByText('mockTooltip')).not.toBeInTheDocument();
});
- it('displays tooltip on click', async () => {
+ it('displays tooltip and copy the text on click', async () => {
jest.useFakeTimers();
- document.execCommand = jest.fn();
+
+ const spy = useCopyToClipboard as jest.Mock;
+ const copy = jest.fn();
+ spy.mockReturnValue([{}, copy]);
+
const rendered = await renderInTestApp(
@@ -84,4 +93,18 @@ describe('', () => {
rendered.getByText('mockTooltip');
jest.useRealTimers();
});
+
+ it('reports copy errors', async () => {
+ const spy = useCopyToClipboard as jest.Mock;
+
+ const error = new Error('just an error');
+ spy.mockReturnValue([{ error }, jest.fn()]);
+
+ await renderInTestApp(
+
+
+ ,
+ );
+ expect(apiRegistry.get(errorApiRef)?.post).toHaveBeenCalledWith(error);
+ });
});
diff --git a/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx b/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx
index b7120f6ad3..cc0ecaf76f 100644
--- a/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx
+++ b/packages/core-components/src/components/CopyTextButton/CopyTextButton.tsx
@@ -14,10 +14,11 @@
* limitations under the License.
*/
+import { errorApiRef, useApi } from '@backstage/core-plugin-api';
import { IconButton, Tooltip } from '@material-ui/core';
import CopyIcon from '@material-ui/icons/FileCopy';
import PropTypes from 'prop-types';
-import React, { MouseEventHandler, useState } from 'react';
+import React, { MouseEventHandler, useEffect, useState } from 'react';
import { useCopyToClipboard } from 'react-use';
/**
@@ -51,8 +52,15 @@ export const CopyTextButton = (props: Props) => {
...defaultProps,
...props,
};
+ const errorApi = useApi(errorApiRef);
const [open, setOpen] = useState(false);
- const [, copyToClipboard] = useCopyToClipboard();
+ const [{ error }, copyToClipboard] = useCopyToClipboard();
+
+ useEffect(() => {
+ if (error) {
+ errorApi.post(error);
+ }
+ }, [error, errorApi]);
const handleCopyClick: MouseEventHandler = e => {
e.stopPropagation();
@@ -71,7 +79,7 @@ export const CopyTextButton = (props: Props) => {
open={open}
>
-
+
>