Skip to content

Commit

Permalink
moved helper functions to separate files, cleaned up other tests
Browse files Browse the repository at this point in the history
Signed-off-by: Amit Galitzky <[email protected]>
  • Loading branch information
amitgalitz committed Jun 1, 2023
1 parent ea7055b commit 803e1cb
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,28 @@ describe('ConfirmUnlinkDetectorModal spec', () => {
getByText(
'Removing association unlinks test-detector-1 detector from the visualization but does not delete it. The detector association can be restored.'
);
expect(container).toMatchSnapshot();
});
test('should call onConfirm() when closing', async () => {
const { container, getByText, getByTestId } = render(
<ConfirmUnlinkDetectorModal {...ConfirmUnlinkDetectorModalProps} />
);
getByText('Remove association?');
await waitFor(() => {});
userEvent.click(getByTestId('confirmUnlinkButton'));
await waitFor(() => {});
expect(ConfirmUnlinkDetectorModalProps.onConfirm).toHaveBeenCalled();
});
test('should call onConfirm() when closing', async () => {
const { container, getByText, getByTestId } = render(
<ConfirmUnlinkDetectorModal {...ConfirmUnlinkDetectorModalProps} />
);
getByText('Remove association?');
await waitFor(() => {});
userEvent.click(getByTestId('confirmUnlinkButton'));
await waitFor(() => {});
expect(ConfirmUnlinkDetectorModalProps.onConfirm).toHaveBeenCalled();
});
test('should call onHide() when closing', async () => {
const { getByTestId } = render(
<ConfirmUnlinkDetectorModal {...ConfirmUnlinkDetectorModalProps} />
);
await waitFor(() => {});
userEvent.click(getByTestId('cancelUnlinkButton'));
await waitFor(() => {});
expect(ConfirmUnlinkDetectorModalProps.onHide).toHaveBeenCalled();
});
});

This file was deleted.

47 changes: 22 additions & 25 deletions public/expressions/__tests__/overlay_anomalies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
*/

import { setClient } from '../../services';
import { httpClientMock, coreServicesMock } from '../../../test/mocks';
import { httpClientMock } from '../../../test/mocks';
import {
convertAnomaliesToPointInTimeEventsVisLayer,
getAnomalies,
getVisLayerError,
getDetectorResponse,
} from '../overlay_anomalies';
} from '../helpers';
import {
anomalyResultSummary,
noAnomaliesResultResponse,
parsedAnomalies,
selectedDetectors,
ANOMALY_RESULT_SUMMARY,
ANOMALY_RESULT_SUMMARY_DETECTOR_ID,
NO_ANOMALIES_RESULT_RESPONSE,
PARSED_ANOMALIES,
SELECTED_DETECTORS,
} from '../../pages/utils/__tests__/constants';
import {
DETECTOR_HAS_BEEN_DELETED,
Expand All @@ -31,27 +32,27 @@ describe('overlay_anomalies spec', () => {

const ADPluginResource = {
type: VIS_LAYER_PLUGIN_TYPE,
id: 'hNX8l4ABuV34PY9I1EAZ',
id: ANOMALY_RESULT_SUMMARY_DETECTOR_ID,
name: 'test-1',
urlPath: `${PLUGIN_NAME}#/detectors/hNX8l4ABuV34PY9I1EAZ/results`, //details page for detector in AD plugin
urlPath: `${PLUGIN_NAME}#/detectors/${ANOMALY_RESULT_SUMMARY_DETECTOR_ID}/results`, //details page for detector in AD plugin
};

describe('getAnomalies()', () => {
test('One anomaly', async () => {
httpClientMock.post = jest.fn().mockResolvedValue(anomalyResultSummary);
httpClientMock.post = jest.fn().mockResolvedValue(ANOMALY_RESULT_SUMMARY);
const receivedAnomalies = await getAnomalies(
'hNX8l4ABuV34PY9I1EAZ',
ANOMALY_RESULT_SUMMARY_DETECTOR_ID,
1589258564789,
1589258684789
);
expect(receivedAnomalies).toStrictEqual(parsedAnomalies);
expect(receivedAnomalies).toStrictEqual(PARSED_ANOMALIES);
});
test('No Anomalies', async () => {
httpClientMock.post = jest
.fn()
.mockResolvedValue(noAnomaliesResultResponse);
.mockResolvedValue(NO_ANOMALIES_RESULT_RESPONSE);
const receivedAnomalies = await getAnomalies(
'hNX8l4ABuV34PY9I1EAZ',
ANOMALY_RESULT_SUMMARY_DETECTOR_ID,
1589258564789,
1589258684789
);
Expand All @@ -60,7 +61,7 @@ describe('overlay_anomalies spec', () => {
test('Failed response', async () => {
httpClientMock.post = jest.fn().mockResolvedValue({ ok: false });
const receivedAnomalies = await getAnomalies(
'hNX8l4ABuV34PY9I1EAZ',
ANOMALY_RESULT_SUMMARY_DETECTOR_ID,
1589258564789,
1589258684789
);
Expand All @@ -71,21 +72,21 @@ describe('overlay_anomalies spec', () => {
test('get detector', async () => {
httpClientMock.get = jest
.fn()
.mockResolvedValue({ ok: true, response: selectedDetectors[0] });
.mockResolvedValue({ ok: true, response: SELECTED_DETECTORS[0] });
const receivedAnomalies = await getDetectorResponse(
'gtU2l4ABuV34PY9ITTdm'
);
expect(receivedAnomalies).toStrictEqual({
ok: true,
response: selectedDetectors[0],
response: SELECTED_DETECTORS[0],
});
});
});
describe('convertAnomaliesToPointInTimeEventsVisLayer()', () => {
test('convert anomalies to PointInTimeEventsVisLayer', async () => {
const expectedTimeStamp =
parsedAnomalies[0].startTime +
(parsedAnomalies[0].endTime - parsedAnomalies[0].startTime) / 2;
PARSED_ANOMALIES[0].startTime +
(PARSED_ANOMALIES[0].endTime - PARSED_ANOMALIES[0].startTime) / 2;
const expectedPointInTimeEventsVisLayer = {
events: [
{
Expand All @@ -95,17 +96,16 @@ describe('overlay_anomalies spec', () => {
],
originPlugin: 'anomalyDetectionDashboards',
pluginResource: {
id: 'hNX8l4ABuV34PY9I1EAZ',
id: ANOMALY_RESULT_SUMMARY_DETECTOR_ID,
name: 'test-1',
type: 'Anomaly Detectors',
urlPath:
'anomaly-detection-dashboards#/detectors/hNX8l4ABuV34PY9I1EAZ/results',
urlPath: `anomaly-detection-dashboards#/detectors/${ANOMALY_RESULT_SUMMARY_DETECTOR_ID}/results`,
},
type: 'PointInTimeEvents',
};
const pointInTimeEventsVisLayer =
await convertAnomaliesToPointInTimeEventsVisLayer(
parsedAnomalies,
PARSED_ANOMALIES,
ADPluginResource
);
expect(pointInTimeEventsVisLayer).toStrictEqual(
Expand All @@ -123,7 +123,6 @@ describe('overlay_anomalies spec', () => {
message: error.message,
};
const visLayerError = await getVisLayerError(error);
console.log('receivedError: ' + JSON.stringify(visLayerError));
expect(visLayerError).toStrictEqual(expectedVisLayerError);
});
test('get no permission ErrorVisLayer', async () => {
Expand All @@ -135,7 +134,6 @@ describe('overlay_anomalies spec', () => {
message: error.message,
};
const visLayerError = await getVisLayerError(error);
console.log('recievedError: ' + JSON.stringify(visLayerError));
expect(visLayerError).toStrictEqual(expectedVisLayerError);
});
test('get fetch issue ErrorVisLayer', async () => {
Expand All @@ -145,7 +143,6 @@ describe('overlay_anomalies spec', () => {
message: error.message,
};
const visLayerError = await getVisLayerError(error);
console.log('recievedError: ' + JSON.stringify(visLayerError));
expect(visLayerError).toStrictEqual(expectedVisLayerError);
});
});
Expand Down
127 changes: 127 additions & 0 deletions public/expressions/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import {
getAnomalySummaryQuery,
parsePureAnomalies,
} from '../pages/utils/anomalyResultUtils';
import { AD_NODE_API } from '../../utils/constants';
import { AnomalyData } from '../models/interfaces';
import { getClient } from '../services';
import {
PluginResource,
PointInTimeEventsVisLayer,
VisLayerError,
VisLayerErrorTypes,
VisLayerTypes,
} from '../../../../src/plugins/vis_augmenter/public';
import {
DETECTOR_HAS_BEEN_DELETED,
ORIGIN_PLUGIN_VIS_LAYER,
} from './constants';
import {
DOES_NOT_HAVE_PERMISSIONS_KEY_WORD,
NO_PERMISSIONS_KEY_WORD,
} from '../../server/utils/helpers';
import { get } from 'lodash';

// This gets all the needed anomalies for the given detector ID and time range
export const getAnomalies = async (
detectorId: string,
startTime: number,
endTime: number
): Promise<AnomalyData[]> => {
const anomalySummaryQuery = getAnomalySummaryQuery(
startTime,
endTime,
detectorId,
undefined,
false
);

const anomalySummaryResponse = await getClient().post(
`..${AD_NODE_API.DETECTOR}/results/_search`,
{
body: JSON.stringify(anomalySummaryQuery),
}
);

return parsePureAnomalies(anomalySummaryResponse);
};

export const getDetectorResponse = async (detectorId: string) => {
const resp = await getClient().get(`..${AD_NODE_API.DETECTOR}/${detectorId}`);
return resp;
};

// This takes anomalies and returns them as vis layer of type PointInTimeEvents
export const convertAnomaliesToPointInTimeEventsVisLayer = (
anomalies: AnomalyData[],
ADPluginResource: PluginResource
): PointInTimeEventsVisLayer => {
const events = anomalies.map((anomaly: AnomalyData) => {
return {
timestamp: anomaly.startTime + (anomaly.endTime - anomaly.startTime) / 2,
metadata: {},
};
});
return {
originPlugin: ORIGIN_PLUGIN_VIS_LAYER,
type: VisLayerTypes.PointInTimeEvents,
pluginResource: ADPluginResource,
events: events,
} as PointInTimeEventsVisLayer;
};

const checkIfPermissionErrors = (error): boolean => {
return typeof error === 'string'
? error.includes(NO_PERMISSIONS_KEY_WORD) ||
error.includes(DOES_NOT_HAVE_PERMISSIONS_KEY_WORD)
: get(error, 'message', '').includes(NO_PERMISSIONS_KEY_WORD) ||
get(error, 'message', '').includes(DOES_NOT_HAVE_PERMISSIONS_KEY_WORD);
};

const checkIfDeletionErrors = (error): boolean => {
return typeof error === 'string'
? error.includes(DETECTOR_HAS_BEEN_DELETED)
: get(error, 'message', '').includes(DETECTOR_HAS_BEEN_DELETED);
};

//Helps convert any possible errors into either permission, deletion or fetch related failures
export const getVisLayerError = (error): VisLayerError => {
let visLayerError: VisLayerError = {} as VisLayerError;
if (checkIfPermissionErrors(error)) {
visLayerError = {
type: VisLayerErrorTypes.PERMISSIONS_FAILURE,
message:
error === 'string'
? error
: error instanceof Error
? get(error, 'message', '')
: '',
};
} else if (checkIfDeletionErrors(error)) {
visLayerError = {
type: VisLayerErrorTypes.RESOURCE_DELETED,
message:
error === 'string'
? error
: error instanceof Error
? get(error, 'message', '')
: '',
};
} else {
visLayerError = {
type: VisLayerErrorTypes.FETCH_FAILURE,
message:
error === 'string'
? error
: error instanceof Error
? get(error, 'message', '')
: '',
};
}
return visLayerError;
};
Loading

0 comments on commit 803e1cb

Please sign in to comment.