From ef8b50c19ebbc8a347b6376c2cbed44f4962c56e Mon Sep 17 00:00:00 2001 From: Vikrant Gupta Date: Mon, 22 Jul 2024 21:10:48 +0530 Subject: [PATCH] chore: addition of jest test cases for dashboards panels (#5506) * chore: added value panel wrapper jest tests * chore: added column units and legends test for table panel wrapper --- frontend/src/components/ValueGraph/index.tsx | 5 +- .../__tests__/TablePanelWrapper.test.tsx | 31 ++ .../__tests__/ValuePanelWrapper.test.tsx | 38 ++ .../TablePanelWrapper.test.tsx.snap | 389 ++++++++++++++++++ .../ValuePanelWrapper.test.tsx.snap | 76 ++++ .../__tests__/tablePanelWrapperHelper.ts | 286 +++++++++++++ .../__tests__/valuePanelWrapperHelper.ts | 267 ++++++++++++ 7 files changed, 1091 insertions(+), 1 deletion(-) create mode 100644 frontend/src/container/PanelWrapper/__tests__/TablePanelWrapper.test.tsx create mode 100644 frontend/src/container/PanelWrapper/__tests__/ValuePanelWrapper.test.tsx create mode 100644 frontend/src/container/PanelWrapper/__tests__/__snapshots__/TablePanelWrapper.test.tsx.snap create mode 100644 frontend/src/container/PanelWrapper/__tests__/__snapshots__/ValuePanelWrapper.test.tsx.snap create mode 100644 frontend/src/container/PanelWrapper/__tests__/tablePanelWrapperHelper.ts create mode 100644 frontend/src/container/PanelWrapper/__tests__/valuePanelWrapperHelper.ts diff --git a/frontend/src/components/ValueGraph/index.tsx b/frontend/src/components/ValueGraph/index.tsx index 6f2eaa8de1..f0ee1e08d1 100644 --- a/frontend/src/components/ValueGraph/index.tsx +++ b/frontend/src/components/ValueGraph/index.tsx @@ -49,7 +49,10 @@ function ValueGraph({ } > - + )} diff --git a/frontend/src/container/PanelWrapper/__tests__/TablePanelWrapper.test.tsx b/frontend/src/container/PanelWrapper/__tests__/TablePanelWrapper.test.tsx new file mode 100644 index 0000000000..0c2389dead --- /dev/null +++ b/frontend/src/container/PanelWrapper/__tests__/TablePanelWrapper.test.tsx @@ -0,0 +1,31 @@ +import { render } from 'tests/test-utils'; +import { Widgets } from 'types/api/dashboard/getAll'; + +import TablePanelWrapper from '../TablePanelWrapper'; +import { + tablePanelQueryResponse, + tablePanelWidgetQuery, +} from './tablePanelWrapperHelper'; + +describe('Table panel wrappper tests', () => { + it('table should render fine with the query response and column units', () => { + const { container, getByText } = render( + {}} + />, + ); + // checking the overall rendering of the table + expect(container).toMatchSnapshot(); + + // the first row of the table should have the latency value with units + expect(getByText('4.35 s')).toBeInTheDocument(); + + // the rows should have optimised value for human readability + expect(getByText('31.3 ms')).toBeInTheDocument(); + + // the applied legend should appear as the column header + expect(getByText('latency-per-service')).toBeInTheDocument(); + }); +}); diff --git a/frontend/src/container/PanelWrapper/__tests__/ValuePanelWrapper.test.tsx b/frontend/src/container/PanelWrapper/__tests__/ValuePanelWrapper.test.tsx new file mode 100644 index 0000000000..519083cd0b --- /dev/null +++ b/frontend/src/container/PanelWrapper/__tests__/ValuePanelWrapper.test.tsx @@ -0,0 +1,38 @@ +import { render } from 'tests/test-utils'; +import { Widgets } from 'types/api/dashboard/getAll'; + +import ValuePanelWrapper from '../ValuePanelWrapper'; +import { + thresholds, + valuePanelQueryResponse, + valuePanelWidget, +} from './valuePanelWrapperHelper'; + +describe('Value panel wrappper tests', () => { + it('should render value panel correctly with yaxis unit', () => { + const { getByText } = render( + {}} + />, + ); + + // selected y axis unit as miliseconds (ms) + expect(getByText('295 ms')).toBeInTheDocument(); + }); + + it('should render tooltip when there are conflicting thresholds', () => { + const { getByTestId, container } = render( + {}} + />, + ); + + expect(getByTestId('conflicting-thresholds')).toBeInTheDocument(); + // added snapshot test here for checking the thresholds color being applied properly + expect(container).toMatchSnapshot(); + }); +}); diff --git a/frontend/src/container/PanelWrapper/__tests__/__snapshots__/TablePanelWrapper.test.tsx.snap b/frontend/src/container/PanelWrapper/__tests__/__snapshots__/TablePanelWrapper.test.tsx.snap new file mode 100644 index 0000000000..d37ccf5841 --- /dev/null +++ b/frontend/src/container/PanelWrapper/__tests__/__snapshots__/TablePanelWrapper.test.tsx.snap @@ -0,0 +1,389 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Table panel wrappper tests table should render fine with the query response and column units 1`] = ` +.c1 { + position: absolute; + right: -0.313rem; + bottom: 0; + z-index: 1; + width: 0.625rem; + height: 100%; + cursor: col-resize; +} + +.c0 { + height: 95%; + overflow: hidden; +} + +.c0 .ant-table-wrapper { + height: 100%; +} + +.c0 .ant-spin-nested-loading { + height: 100%; +} + +.c0 .ant-spin-container { + height: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} + +.c0 .ant-table { + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + overflow: auto; +} + +.c0 .ant-table > .ant-table-container > .ant-table-content > table { + min-width: 99% !important; +} + +
+ +
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + service_name + + + + +
+ +
+
+ + latency-per-service + + + + +
+ +
+
+ demo-app +
+
+
+ 4.35 s +
+
+
+ customer +
+
+
+ 431 ms +
+
+
+ mysql +
+
+
+ 431 ms +
+
+
+ frontend +
+
+
+ 287 ms +
+
+
+ driver +
+
+
+ 230 ms +
+
+
+ route +
+
+
+ 66.4 ms +
+
+
+ redis +
+
+
+ 31.3 ms +
+
+
+
+
+
+
+
+
+
+
+`; diff --git a/frontend/src/container/PanelWrapper/__tests__/__snapshots__/ValuePanelWrapper.test.tsx.snap b/frontend/src/container/PanelWrapper/__tests__/__snapshots__/ValuePanelWrapper.test.tsx.snap new file mode 100644 index 0000000000..435a7cb08d --- /dev/null +++ b/frontend/src/container/PanelWrapper/__tests__/__snapshots__/ValuePanelWrapper.test.tsx.snap @@ -0,0 +1,76 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Value panel wrappper tests should render tooltip when there are conflicting thresholds 1`] = ` +.c1 { + height: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} + +.c0 { + text-align: center; + padding-top: 1rem; +} + +
+ +
+
+
+
+
+ + 295 ms + +
+ + + +
+
+
+
+`; diff --git a/frontend/src/container/PanelWrapper/__tests__/tablePanelWrapperHelper.ts b/frontend/src/container/PanelWrapper/__tests__/tablePanelWrapperHelper.ts new file mode 100644 index 0000000000..c6be13c200 --- /dev/null +++ b/frontend/src/container/PanelWrapper/__tests__/tablePanelWrapperHelper.ts @@ -0,0 +1,286 @@ +export const tablePanelWidgetQuery = { + id: '727533b0-7718-4f99-a1db-a1875649325c', + title: '', + description: '', + isStacked: false, + nullZeroValues: 'zero', + opacity: '1', + panelTypes: 'table', + query: { + clickhouse_sql: [ + { + name: 'A', + legend: '', + disabled: false, + query: '', + }, + ], + promql: [ + { + name: 'A', + query: '', + legend: '', + disabled: false, + }, + ], + builder: { + queryData: [ + { + dataSource: 'metrics', + queryName: 'A', + aggregateOperator: 'count', + aggregateAttribute: { + key: 'signoz_latency', + dataType: 'float64', + type: 'ExponentialHistogram', + isColumn: true, + isJSON: false, + id: 'signoz_latency--float64--ExponentialHistogram--true', + }, + timeAggregation: '', + spaceAggregation: 'p90', + functions: [], + filters: { + items: [], + op: 'AND', + }, + expression: 'A', + disabled: false, + stepInterval: 60, + having: [], + limit: null, + orderBy: [], + groupBy: [ + { + key: 'service_name', + dataType: 'string', + type: 'tag', + isColumn: false, + isJSON: false, + id: 'service_name--string--tag--false', + }, + ], + legend: 'latency-per-service', + reduceTo: 'avg', + }, + ], + queryFormulas: [], + }, + id: '7feafec2-a450-4b5a-8897-260c1a9fe1e4', + queryType: 'builder', + }, + timePreferance: 'GLOBAL_TIME', + softMax: null, + softMin: null, + selectedLogFields: [ + { + dataType: 'string', + type: '', + name: 'body', + }, + { + dataType: 'string', + type: '', + name: 'timestamp', + }, + ], + selectedTracesFields: [ + { + key: 'serviceName', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'serviceName--string--tag--true', + }, + { + key: 'name', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'name--string--tag--true', + }, + { + key: 'durationNano', + dataType: 'float64', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'durationNano--float64--tag--true', + }, + { + key: 'httpMethod', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'httpMethod--string--tag--true', + }, + { + key: 'responseStatusCode', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'responseStatusCode--string--tag--true', + }, + ], + yAxisUnit: 'none', + thresholds: [], + fillSpans: false, + columnUnits: { + A: 'ms', + }, + bucketCount: 30, + stackedBarChart: false, + bucketWidth: 0, + mergeAllActiveQueries: false, +}; + +export const tablePanelQueryResponse = { + status: 'success', + isLoading: false, + isSuccess: true, + isError: false, + isIdle: false, + data: { + statusCode: 200, + error: null, + message: 'success', + payload: { + status: 'success', + data: { + resultType: '', + result: [ + { + table: { + columns: [ + { + name: 'service_name', + queryName: '', + isValueColumn: false, + }, + { + name: 'A', + queryName: 'A', + isValueColumn: true, + }, + ], + rows: [ + { + data: { + A: 4353.81, + service_name: 'demo-app', + }, + }, + { + data: { + A: 431.25, + service_name: 'customer', + }, + }, + { + data: { + A: 431.25, + service_name: 'mysql', + }, + }, + { + data: { + A: 287.11, + service_name: 'frontend', + }, + }, + { + data: { + A: 230.02, + service_name: 'driver', + }, + }, + { + data: { + A: 66.37, + service_name: 'route', + }, + }, + { + data: { + A: 31.3, + service_name: 'redis', + }, + }, + ], + }, + }, + ], + }, + }, + params: { + start: 1721207225000, + end: 1721207525000, + step: 60, + variables: {}, + formatForWeb: true, + compositeQuery: { + queryType: 'builder', + panelType: 'table', + fillGaps: false, + builderQueries: { + A: { + dataSource: 'metrics', + queryName: 'A', + aggregateOperator: 'count', + aggregateAttribute: { + key: 'signoz_latency', + dataType: 'float64', + type: 'ExponentialHistogram', + isColumn: true, + isJSON: false, + id: 'signoz_latency--float64--ExponentialHistogram--true', + }, + timeAggregation: '', + spaceAggregation: 'p90', + functions: [], + filters: { + items: [], + op: 'AND', + }, + expression: 'A', + disabled: false, + stepInterval: 60, + having: [], + limit: null, + orderBy: [], + groupBy: [ + { + key: 'service_name', + dataType: 'string', + type: 'tag', + isColumn: false, + isJSON: false, + id: 'service_name--string--tag--false', + }, + ], + legend: '', + reduceTo: 'avg', + }, + }, + }, + }, + }, + dataUpdatedAt: 1721207526018, + error: null, + errorUpdatedAt: 0, + failureCount: 0, + errorUpdateCount: 0, + isFetched: true, + isFetchedAfterMount: true, + isFetching: false, + isRefetching: false, + isLoadingError: false, + isPlaceholderData: false, + isPreviousData: false, + isRefetchError: false, + isStale: true, +}; diff --git a/frontend/src/container/PanelWrapper/__tests__/valuePanelWrapperHelper.ts b/frontend/src/container/PanelWrapper/__tests__/valuePanelWrapperHelper.ts new file mode 100644 index 0000000000..1376feac06 --- /dev/null +++ b/frontend/src/container/PanelWrapper/__tests__/valuePanelWrapperHelper.ts @@ -0,0 +1,267 @@ +export const valuePanelWidget = { + id: 'b8b93086-ef01-47bf-9044-1e7abd583be4', + title: 'signoz latency in ms', + description: '', + isStacked: false, + nullZeroValues: 'zero', + opacity: '1', + panelTypes: 'value', + query: { + clickhouse_sql: [ + { + name: 'A', + legend: '', + disabled: false, + query: '', + }, + ], + promql: [ + { + name: 'A', + query: '', + legend: '', + disabled: false, + }, + ], + builder: { + queryData: [ + { + dataSource: 'metrics', + queryName: 'A', + aggregateOperator: 'count', + aggregateAttribute: { + key: 'signoz_latency', + dataType: 'float64', + type: 'ExponentialHistogram', + isColumn: true, + isJSON: false, + id: 'signoz_latency--float64--ExponentialHistogram--true', + }, + timeAggregation: '', + spaceAggregation: 'p90', + functions: [], + filters: { + items: [], + op: 'AND', + }, + expression: 'A', + disabled: false, + stepInterval: 60, + having: [], + limit: null, + orderBy: [], + groupBy: [], + legend: '', + reduceTo: 'avg', + }, + ], + queryFormulas: [], + }, + id: '3bec289c-49c3-4d7e-98bb-84d47c79909c', + queryType: 'builder', + }, + timePreferance: 'GLOBAL_TIME', + softMax: null, + softMin: null, + selectedLogFields: [ + { + dataType: 'string', + type: '', + name: 'body', + }, + { + dataType: 'string', + type: '', + name: 'timestamp', + }, + ], + selectedTracesFields: [ + { + key: 'serviceName', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'serviceName--string--tag--true', + }, + { + key: 'name', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'name--string--tag--true', + }, + { + key: 'durationNano', + dataType: 'float64', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'durationNano--float64--tag--true', + }, + { + key: 'httpMethod', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'httpMethod--string--tag--true', + }, + { + key: 'responseStatusCode', + dataType: 'string', + type: 'tag', + isColumn: true, + isJSON: false, + id: 'responseStatusCode--string--tag--true', + }, + ], + yAxisUnit: 'ms', + thresholds: [], + fillSpans: false, + columnUnits: {}, + bucketCount: 30, + stackedBarChart: false, + bucketWidth: 0, + mergeAllActiveQueries: false, +}; + +export const thresholds = [ + { + index: '8eb16a3a-b4f1-47c8-943a-4b1786884583', + isEditEnabled: false, + thresholdColor: 'Blue', + thresholdFormat: 'Text', + thresholdOperator: '>', + thresholdUnit: 'none', + thresholdValue: 100, + keyIndex: 1, + selectedGraph: 'value', + thresholdTableOptions: '', + thresholdLabel: '', + }, + { + index: 'eb9c1186-ad7d-42dd-8e7f-3913a321d7cf', + isEditEnabled: false, + thresholdColor: 'Red', + thresholdFormat: 'Text', + thresholdOperator: '>', + thresholdUnit: 'none', + thresholdValue: 0, + keyIndex: 0, + selectedGraph: 'value', + thresholdTableOptions: '', + thresholdLabel: '', + }, +]; + +export const valuePanelQueryResponse = { + status: 'success', + isLoading: false, + isSuccess: true, + isError: false, + isIdle: false, + data: { + statusCode: 200, + error: null, + message: 'success', + payload: { + data: { + result: [ + { + metric: { + A: 'A', + }, + values: [[0, '295.4299833508185']], + queryName: 'A', + legend: 'A', + }, + ], + resultType: '', + newResult: { + status: 'success', + data: { + resultType: '', + result: [ + { + queryName: 'A', + series: [ + { + labels: { + A: 'A', + }, + labelsArray: null, + values: [ + { + timestamp: 0, + value: '295.4299833508185', + }, + ], + }, + ], + }, + ], + }, + }, + }, + }, + params: { + start: 1721203451000, + end: 1721203751000, + step: 60, + variables: {}, + formatForWeb: false, + compositeQuery: { + queryType: 'builder', + panelType: 'value', + fillGaps: false, + builderQueries: { + A: { + dataSource: 'metrics', + queryName: 'A', + aggregateOperator: 'count', + aggregateAttribute: { + key: 'signoz_latency', + dataType: 'float64', + type: 'ExponentialHistogram', + isColumn: true, + isJSON: false, + id: 'signoz_latency--float64--ExponentialHistogram--true', + }, + timeAggregation: '', + spaceAggregation: 'p90', + functions: [], + filters: { + items: [], + op: 'AND', + }, + expression: 'A', + disabled: false, + stepInterval: 60, + having: [], + limit: null, + orderBy: [], + groupBy: [], + legend: '', + reduceTo: 'avg', + }, + }, + }, + }, + }, + dataUpdatedAt: 1721203751775, + error: null, + errorUpdatedAt: 0, + failureCount: 0, + errorUpdateCount: 0, + isFetched: true, + isFetchedAfterMount: true, + isFetching: false, + isRefetching: false, + isLoadingError: false, + isPlaceholderData: false, + isPreviousData: false, + isRefetchError: false, + isStale: true, +};