Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Clearing up all jest errors and warnings #91740

Merged
merged 5 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
*/

import {
EuiMarkdownEditorUiPlugin,
getDefaultEuiMarkdownParsingPlugins,
getDefaultEuiMarkdownProcessingPlugins,
getDefaultEuiMarkdownUiPlugins,
} from '@elastic/eui';

import * as timelineMarkdownPlugin from './timeline';

export const uiPlugins = [timelineMarkdownPlugin.plugin];
const uiPlugins: EuiMarkdownEditorUiPlugin[] = getDefaultEuiMarkdownUiPlugins();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clears up 195 instances of the following warning:

Deprecation warning: uiPlugins passed to EuiMarkdownEditor does not include the tooltip plugin, which has been added for you. This automatic inclusion has been deprecated and will be removed in the future, see https://github.com/elastic/eui/pull/4383

Deprecation, no ones fault but @chandlerprall ;)

uiPlugins.push(timelineMarkdownPlugin.plugin);
export { uiPlugins };
export const parsingPlugins = getDefaultEuiMarkdownParsingPlugins();
export const processingPlugins = getDefaultEuiMarkdownProcessingPlugins();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,16 @@ describe('QueryBar ', () => {
await waitFor(() => getByTestId('queryInput')); // check for presence of query input
return mount(Component);
};
let abortSpy: jest.SpyInstance;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is in a few spots. Clears up an error thrown by SearchBar:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in QueryStringInputUI (created by EnhancedType)
in EnhancedType (created by QueryBarTopRow)
in div (created by EuiFlexItem)
in EuiFlexItem (created by QueryBarTopRow)
in div (created by EuiFlexGroup)
in EuiFlexGroup (created by QueryBarTopRow)
in QueryBarTopRow (created by SearchBarUI)
in div (created by SearchBarUI)
in SearchBarUI (created by EnhancedType)
in EnhancedType (created by InjectIntl(EnhancedType))
in InjectIntl(EnhancedType) (created by WrappedSearchBar)
in Suspense (created by WrappedSearchBar)
in WrappedSearchBar (created by EnhancedType)
in EnhancedType (created by InjectIntl(EnhancedType))
in InjectIntl(EnhancedType)
in Unknown (created by Proxy)
in Provider (created by App)
in App (created by ErrorBoundary)
in ErrorBoundary (created by DragDropContext)
in DragDropContext (created by TestProvidersComponent)
in ThemeProvider (created by TestProvidersComponent)
in Provider (created by TestProvidersComponent)
in ApolloProvider (created by TestProvidersComponent)
in Provider
in Unknown (created by TestProvidersComponent)
in PseudoLocaleWrapper (created by I18nProvider)
in IntlProvider (created by I18nProvider)
in I18nProvider (created by TestProvidersComponent)
in TestProvidersComponent (created by Proxy)
in Proxy

138 |
139 |     if (!currentAbortController.signal.aborted) {
> 140 |       this.setState({
    |            ^
    141 |         indexPatterns: [...objectPatterns, ...objectPatternsFromStrings],
  142 |       });
  143 |

beforeAll(() => {
const mockAbort = new AbortController();
mockAbort.abort();
abortSpy = jest.spyOn(window, 'AbortController').mockImplementation(() => mockAbort);
});

afterAll(() => {
abortSpy.mockRestore();
});
beforeEach(() => {
mockOnChangeQuery.mockClear();
mockOnSubmitQuery.mockClear();
Expand Down Expand Up @@ -264,7 +273,6 @@ describe('QueryBar ', () => {
const onChangedQueryRef = searchBarProps.onQueryChange;
const onSubmitQueryRef = searchBarProps.onQuerySubmit;
const onSavedQueryRef = searchBarProps.onSavedQueryUpdated;

wrapper.setProps({ onSavedQuery: jest.fn() });
wrapper.update();

Expand Down Expand Up @@ -294,22 +302,21 @@ describe('QueryBar ', () => {
onSavedQuery={mockOnSavedQuery}
/>
);
await waitFor(() => {
const isSavedQueryPopoverOpen = () =>
wrapper.find('EuiPopover[id="savedQueryPopover"]').prop('isOpen');
const isSavedQueryPopoverOpen = () =>
wrapper.find('EuiPopover[id="savedQueryPopover"]').prop('isOpen');

expect(isSavedQueryPopoverOpen()).toBeFalsy();
expect(isSavedQueryPopoverOpen()).toBeFalsy();

wrapper
.find('button[data-test-subj="saved-query-management-popover-button"]')
.simulate('click');
wrapper
.find('button[data-test-subj="saved-query-management-popover-button"]')
.simulate('click');

await waitFor(() => {
expect(isSavedQueryPopoverOpen()).toBeTruthy();
});
wrapper.find('button[data-test-subj="saved-query-management-save-button"]').simulate('click');

wrapper
.find('button[data-test-subj="saved-query-management-save-button"]')
.simulate('click');

await waitFor(() => {
expect(isSavedQueryPopoverOpen()).toBeFalsy();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ import { useAllExceptionLists } from './use_all_exception_lists';
jest.mock('../../../../../../common/lib/kibana');
jest.mock('./use_all_exception_lists');
jest.mock('../../../../../../shared_imports');
jest.mock('@kbn/i18n/react', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also present a few times. Here are the errors we clear up:

      console.error
      [React Intl] Error formatting relative time.
      RangeError: The date value provided to IntlRelativeFormat#format() is not in valid range.

      at defaultErrorHandler (node_modules/react-intl/lib/index.js:525:13)
      at formatRelative (node_modules/react-intl/lib/index.js:748:5)
      at FormattedRelative.render (node_modules/react-intl/lib/index.js:1354:31)
      at finishClassComponent (node_modules/react-dom/cjs/react-dom.development.js:18470:31)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:18423:24)
      at beginWork$1 (node_modules/react-dom/cjs/react-dom.development.js:20186:16)
      at beginWork$$1 (node_modules/react-dom/cjs/react-dom.development.js:25756:14)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:24698:12)
      console.warn
      Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.

      * Move data fetching code or side effects to componentDidUpdate.
      * If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state
      * Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.

      Please update the following components: FormattedRelative

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for doing all of this! Just a quick question so I understand a bit better...isn't FormattedRelative implemented in the module already? What do we get by mocking it specifically here?

Copy link
Contributor Author

@stephmilovic stephmilovic Feb 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean implemented in the module? Just mocking this component since we are not responsible for it, we are not testing anything to do with it, and it is causing errors in jest tests.

const originalModule = jest.requireActual('@kbn/i18n/react');
const FormattedRelative = jest.fn().mockImplementation(() => '20 hours ago');

return {
...originalModule,
FormattedRelative,
};
});
describe('ExceptionListsTable', () => {
const exceptionList1 = getExceptionListSchemaMock();
const exceptionList2 = { ...getExceptionListSchemaMock(), list_id: 'not_endpoint_list', id: '2' };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ describe('when on the list page', () => {
let store: AppContextTestRender['store'];
let coreStart: AppContextTestRender['coreStart'];
let middlewareSpy: AppContextTestRender['middlewareSpy'];
let abortSpy: jest.SpyInstance;
beforeAll(() => {
const mockAbort = new AbortController();
mockAbort.abort();
abortSpy = jest.spyOn(window, 'AbortController').mockImplementation(() => mockAbort);
});

afterAll(() => {
abortSpy.mockRestore();
});
beforeEach(() => {
const mockedContext = createAppRootMockRenderer();
({ history, store, coreStart, middlewareSpy } = mockedContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
*/

import React, { memo } from 'react';
import { EuiCard, EuiIcon, EuiTextColor, EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import {
EuiCard,
EuiIcon,
EuiTextColor,
EuiLink,
EuiFlexGroup,
EuiFlexItem,
EuiText,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import styled from 'styled-components';
import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -42,8 +50,10 @@ export const LockedPolicyCard = memo(() => {
</strong>
</h3>
}
description={
<EuiFlexGroup className="lockedCardDescription" direction="column" gutterSize="none">
description={false}
stephmilovic marked this conversation as resolved.
Show resolved Hide resolved
>
<EuiFlexGroup className="lockedCardDescription" direction="column" gutterSize="none">
<EuiText>
<EuiFlexItem>
<h4>
<EuiTextColor color="subdued">
Expand All @@ -59,7 +69,7 @@ export const LockedPolicyCard = memo(() => {
<FormattedMessage
id="xpack.securitySolution.endpoint.policy.details.lockedCard"
defaultMessage="To turn on Ransomware protection, you must upgrade your license to Platinum, start a
free 30-day trial, or spin up a {cloudDeploymentLink} on AWS, GCP, or Azure."
free 30-day trial, or spin up a {cloudDeploymentLink} on AWS, GCP, or Azure."
values={{
cloudDeploymentLink: (
<EuiLink href="https://www.elastic.co/cloud/" target="_blank">
Expand All @@ -73,9 +83,9 @@ export const LockedPolicyCard = memo(() => {
/>
</p>
</EuiFlexItem>
</EuiFlexGroup>
}
/>
</EuiText>
</EuiFlexGroup>
</EuiCard>
</LockedPolicyDiv>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@ jest.mock('../../../containers/kpis', () => ({
}));
const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>;
jest.mock('../../../../common/lib/kibana');
jest.mock('@kbn/i18n/react', () => {
const originalModule = jest.requireActual('@kbn/i18n/react');
const FormattedRelative = jest.fn().mockImplementation(() => '20 hours ago');

return {
...originalModule,
FormattedRelative,
};
});
const mockUseTimelineKpiResponse = {
processCount: 1,
userCount: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import { cloneDeep, getOr, omit } from 'lodash/fp';
import { Dispatch } from 'redux';
import ApolloClient from 'apollo-client';

import {
mockTimelineResults,
mockTimelineResult,
mockTimelineModel,
} from '../../../common/mock/timeline_results';
import { mockTimelineResults, mockTimelineResult, mockTimelineModel } from '../../../common/mock';
import { timelineDefaults } from '../../store/timeline/defaults';
import { setTimelineRangeDatePicker as dispatchSetTimelineRangeDatePicker } from '../../../common/store/inputs/actions';
import {
Expand All @@ -37,7 +33,7 @@ import {
formatTimelineResultToModel,
} from './helpers';
import { OpenTimelineResult, DispatchUpdateTimeline } from './types';
import { KueryFilterQueryKind } from '../../../common/store/model';
import { KueryFilterQueryKind } from '../../../common/store';
import { Note } from '../../../common/lib/note';
import moment from 'moment';
import sinon from 'sinon';
Expand Down Expand Up @@ -1275,7 +1271,7 @@ describe('helpers', () => {

describe('update a timeline', () => {
const updateIsLoading = jest.fn();
const updateTimeline = jest.fn();
const updateTimeline = jest.fn().mockImplementation(() => jest.fn());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clears the following type error:

(node:38240) UnhandledPromiseRejectionWarning: TypeError: updateTimeline(...) is not a function
(Use `node --trace-warnings ...` to show where the warning was created)
(node:38240) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:38240) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

const selectedTimeline = { ...mockSelectedTimeline };
const apolloClient = {
query: (jest.fn().mockResolvedValue(selectedTimeline) as unknown) as ApolloClient<{}>,
Expand Down Expand Up @@ -1316,6 +1312,7 @@ describe('helpers', () => {
args.duplicate,
args.timelineType
);

expect(updateTimeline).toBeCalledWith({
timeline: {
...timeline,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ import { createStore, State } from '../../../common/store';
import { DetailsPanel } from './index';
import { TimelineExpandedDetail, TimelineTabs } from '../../../../common/types/timeline';
import { FlowTarget } from '../../../../common/search_strategy/security_solution/network';
jest.mock('react-apollo', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clears up the following warning:

      console.warn
      Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.

      * Move data fetching code or side effects to componentDidUpdate.
      * If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state
      * Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.

      Please update the following components: Query

const original = jest.requireActual('react-apollo');
return {
...original,
// eslint-disable-next-line react/display-name
Query: () => <></>,
};
});

describe('Details Panel Component', () => {
const state: State = { ...mockGlobalState };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,15 @@ jest.mock('../../containers/index', () => ({

jest.mock('../../../common/lib/kibana');
jest.mock('../../../common/components/url_state/normalize_time_range.ts');
jest.mock('@kbn/i18n/react', () => {
const originalModule = jest.requireActual('@kbn/i18n/react');
const FormattedRelative = jest.fn().mockImplementation(() => '20 hours ago');

return {
...originalModule,
FormattedRelative,
};
});
const mockUseResizeObserver: jest.Mock = useResizeObserver as jest.Mock;
jest.mock('use-resize-observer/polyfilled');
mockUseResizeObserver.mockImplementation(() => ({}));
Expand Down