Compare commits
13 Commits
main
...
issue/9362
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
228abb8604 | ||
|
|
04a8079d1e | ||
|
|
4650090436 | ||
|
|
18d322282c | ||
|
|
6557c448bd | ||
|
|
d30ca6cebc | ||
|
|
61361af8d8 | ||
|
|
56f07da5d9 | ||
|
|
769b3a77f4 | ||
|
|
29f75b8891 | ||
|
|
08483b4f57 | ||
|
|
5bd7dea91d | ||
|
|
398f74f377 |
218
frontend/src/components/ValueGraph/__tests__/ValueGraph.test.tsx
Normal file
218
frontend/src/components/ValueGraph/__tests__/ValueGraph.test.tsx
Normal file
@@ -0,0 +1,218 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import ValueGraph from '../index';
|
||||
import { getBackgroundColorAndThresholdCheck } from '../utils';
|
||||
|
||||
// Mock ResizeObserver
|
||||
class ResizeObserverMock {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
observe(): void {}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
unobserve(): void {}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
disconnect(): void {}
|
||||
}
|
||||
|
||||
global.ResizeObserver = (ResizeObserverMock as unknown) as typeof ResizeObserver;
|
||||
|
||||
// Mock the utils module
|
||||
jest.mock('../utils', () => ({
|
||||
getBackgroundColorAndThresholdCheck: jest.fn(() => ({
|
||||
threshold: {} as any,
|
||||
isConflictingThresholds: false,
|
||||
})),
|
||||
}));
|
||||
|
||||
const mockGetBackgroundColorAndThresholdCheck = getBackgroundColorAndThresholdCheck as jest.MockedFunction<
|
||||
typeof getBackgroundColorAndThresholdCheck
|
||||
>;
|
||||
|
||||
const TEST_ID_VALUE_GRAPH_TEXT = 'value-graph-text';
|
||||
const TEST_ID_VALUE_GRAPH_PREFIX_UNIT = 'value-graph-prefix-unit';
|
||||
const TEST_ID_VALUE_GRAPH_SUFFIX_UNIT = 'value-graph-suffix-unit';
|
||||
|
||||
describe('ValueGraph', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders the numeric value correctly', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="42" rawValue={42} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('42');
|
||||
});
|
||||
|
||||
it('renders value with suffix unit', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="42ms" rawValue={42} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('42');
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_SUFFIX_UNIT)).toHaveTextContent('ms');
|
||||
});
|
||||
|
||||
it('renders value with prefix unit', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="$100" rawValue={100} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('100');
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_PREFIX_UNIT)).toHaveTextContent('$');
|
||||
});
|
||||
|
||||
it('renders value with both prefix and suffix units', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="$100USD" rawValue={100} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('100');
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_PREFIX_UNIT)).toHaveTextContent('$');
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_SUFFIX_UNIT)).toHaveTextContent('USD');
|
||||
});
|
||||
|
||||
it('renders value with K suffix', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="1.5K" rawValue={1500} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('1.5K');
|
||||
});
|
||||
|
||||
it('applies text color when threshold format is Text', () => {
|
||||
mockGetBackgroundColorAndThresholdCheck.mockReturnValue({
|
||||
threshold: {
|
||||
thresholdFormat: 'Text',
|
||||
thresholdColor: 'red',
|
||||
} as any,
|
||||
isConflictingThresholds: false,
|
||||
});
|
||||
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="42" rawValue={42} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
|
||||
it('applies background color when threshold format is Background', () => {
|
||||
mockGetBackgroundColorAndThresholdCheck.mockReturnValue({
|
||||
threshold: {
|
||||
thresholdFormat: 'Background',
|
||||
thresholdColor: 'blue',
|
||||
} as any,
|
||||
isConflictingThresholds: false,
|
||||
});
|
||||
|
||||
const { container } = render(
|
||||
<ValueGraph value="42" rawValue={42} thresholds={[]} />,
|
||||
);
|
||||
|
||||
const containerElement = container.querySelector('.value-graph-container');
|
||||
expect(containerElement).toHaveStyle({ backgroundColor: 'blue' });
|
||||
});
|
||||
|
||||
it('displays conflicting thresholds indicator when multiple thresholds match', () => {
|
||||
mockGetBackgroundColorAndThresholdCheck.mockReturnValue({
|
||||
threshold: {
|
||||
thresholdFormat: 'Text',
|
||||
thresholdColor: 'red',
|
||||
} as any,
|
||||
isConflictingThresholds: true,
|
||||
});
|
||||
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="42" rawValue={42} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId('conflicting-thresholds')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not display conflicting thresholds indicator when no conflict', () => {
|
||||
mockGetBackgroundColorAndThresholdCheck.mockReturnValue({
|
||||
threshold: {} as any,
|
||||
isConflictingThresholds: false,
|
||||
});
|
||||
|
||||
render(<ValueGraph value="42" rawValue={42} thresholds={[]} />);
|
||||
|
||||
expect(
|
||||
screen.queryByTestId('conflicting-thresholds'),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('applies text color to units when threshold format is Text', () => {
|
||||
mockGetBackgroundColorAndThresholdCheck.mockReturnValue({
|
||||
threshold: {
|
||||
thresholdFormat: 'Text',
|
||||
thresholdColor: 'green',
|
||||
} as any,
|
||||
isConflictingThresholds: false,
|
||||
});
|
||||
|
||||
render(<ValueGraph value="42ms" rawValue={42} thresholds={[]} />);
|
||||
|
||||
const unitElement = screen.getByText('ms');
|
||||
expect(unitElement).toHaveStyle({ color: 'green' });
|
||||
});
|
||||
|
||||
it('renders decimal values correctly', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="42.5" rawValue={42.5} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('42.5');
|
||||
});
|
||||
|
||||
it('handles values with M suffix', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="1.2M" rawValue={1200000} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('1.2M');
|
||||
});
|
||||
|
||||
it('handles values with B suffix', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="2.3B" rawValue={2300000000} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('2.3B');
|
||||
});
|
||||
|
||||
it('handles scientific notation values', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="1e-9" rawValue={1e-9} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('1e-9');
|
||||
});
|
||||
|
||||
it('handles scientific notation with suffix unit', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="1e-9%" rawValue={1e-9} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('1e-9');
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_SUFFIX_UNIT)).toHaveTextContent('%');
|
||||
});
|
||||
|
||||
it('handles scientific notation with uppercase E', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="1E-9" rawValue={1e-9} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('1E-9');
|
||||
});
|
||||
|
||||
it('handles scientific notation with positive exponent', () => {
|
||||
const { getByTestId } = render(
|
||||
<ValueGraph value="1e+9" rawValue={1e9} thresholds={[]} />,
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID_VALUE_GRAPH_TEXT)).toHaveTextContent('1e+9');
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import './ValueGraph.styles.scss';
|
||||
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||
import { Tooltip, Typography } from 'antd';
|
||||
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { getBackgroundColorAndThresholdCheck } from './utils';
|
||||
@@ -17,10 +17,16 @@ function ValueGraph({
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [fontSize, setFontSize] = useState('2.5vw');
|
||||
|
||||
// Parse value to separate number and unit (assuming unit is at the end)
|
||||
const matches = value.match(/([\d.]+[KMB]?)(.*)$/);
|
||||
const numericValue = matches?.[1] || value;
|
||||
const unit = matches?.[2]?.trim() || '';
|
||||
const { numericValue, prefixUnit, suffixUnit } = useMemo(() => {
|
||||
const matches = value.match(
|
||||
/^([^\d.]*)?([\d.]+(?:[eE][+-]?[\d]+)?[KMB]?)([^\d.]*)?$/,
|
||||
);
|
||||
return {
|
||||
numericValue: matches?.[2] || value,
|
||||
prefixUnit: matches?.[1]?.trim() || '',
|
||||
suffixUnit: matches?.[3]?.trim() || '',
|
||||
};
|
||||
}, [value]);
|
||||
|
||||
// Adjust font size based on container size
|
||||
useEffect(() => {
|
||||
@@ -65,8 +71,24 @@ function ValueGraph({
|
||||
}}
|
||||
>
|
||||
<div className="value-text-container">
|
||||
{prefixUnit && (
|
||||
<Typography.Text
|
||||
className="value-graph-unit"
|
||||
data-testid="value-graph-prefix-unit"
|
||||
style={{
|
||||
color:
|
||||
threshold.thresholdFormat === 'Text'
|
||||
? threshold.thresholdColor
|
||||
: undefined,
|
||||
fontSize: `calc(${fontSize} * 0.7)`,
|
||||
}}
|
||||
>
|
||||
{prefixUnit}
|
||||
</Typography.Text>
|
||||
)}
|
||||
<Typography.Text
|
||||
className="value-graph-text"
|
||||
data-testid="value-graph-text"
|
||||
style={{
|
||||
color:
|
||||
threshold.thresholdFormat === 'Text'
|
||||
@@ -77,9 +99,10 @@ function ValueGraph({
|
||||
>
|
||||
{numericValue}
|
||||
</Typography.Text>
|
||||
{unit && (
|
||||
{suffixUnit && (
|
||||
<Typography.Text
|
||||
className="value-graph-unit"
|
||||
data-testid="value-graph-suffix-unit"
|
||||
style={{
|
||||
color:
|
||||
threshold.thresholdFormat === 'Text'
|
||||
@@ -88,7 +111,7 @@ function ValueGraph({
|
||||
fontSize: `calc(${fontSize} * 0.7)`,
|
||||
}}
|
||||
>
|
||||
{unit}
|
||||
{suffixUnit}
|
||||
</Typography.Text>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -501,7 +501,7 @@ function NewWidget({
|
||||
stackedBarChart: selectedWidget?.stackedBarChart || false,
|
||||
yAxisUnit: selectedWidget?.yAxisUnit,
|
||||
decimalPrecision:
|
||||
selectedWidget?.decimalPrecision || PrecisionOptionsEnum.TWO,
|
||||
selectedWidget?.decimalPrecision ?? PrecisionOptionsEnum.TWO,
|
||||
panelTypes: graphType,
|
||||
query: adjustedQueryForV5,
|
||||
thresholds: selectedWidget?.thresholds,
|
||||
@@ -532,7 +532,7 @@ function NewWidget({
|
||||
stackedBarChart: selectedWidget?.stackedBarChart || false,
|
||||
yAxisUnit: selectedWidget?.yAxisUnit,
|
||||
decimalPrecision:
|
||||
selectedWidget?.decimalPrecision || PrecisionOptionsEnum.TWO,
|
||||
selectedWidget?.decimalPrecision ?? PrecisionOptionsEnum.TWO,
|
||||
panelTypes: graphType,
|
||||
query: adjustedQueryForV5,
|
||||
thresholds: selectedWidget?.thresholds,
|
||||
|
||||
@@ -49,12 +49,14 @@ exports[`Value panel wrappper tests should render tooltip when there are conflic
|
||||
>
|
||||
<span
|
||||
class="ant-typography value-graph-text css-dev-only-do-not-override-2i2tap"
|
||||
data-testid="value-graph-text"
|
||||
style="color: Blue; font-size: 16px;"
|
||||
>
|
||||
295.43
|
||||
</span>
|
||||
<span
|
||||
class="ant-typography value-graph-unit css-dev-only-do-not-override-2i2tap"
|
||||
data-testid="value-graph-suffix-unit"
|
||||
style="color: Blue; font-size: calc(16px * 0.7);"
|
||||
>
|
||||
ms
|
||||
|
||||
Reference in New Issue
Block a user