Skip to content

Commit 17d5a23

Browse files
sbelasticfkanout
andauthored
Hide log rate analysis when there is no data and tests (#241004)
## Summary Closes #185866 ### Before: <img width="1595" height="839" alt="image" src="https://github.com/user-attachments/assets/3597aacc-5fe2-4b87-9cc5-bf7722290411" /> ### After: <img width="1591" height="774" alt="image" src="https://github.com/user-attachments/assets/47d2f147-fcf8-439f-be3d-32ff971d822b" /> ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [ ] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels. ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... ## Run unit tests - `yarn test:jest x-pack/solutions/observability/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.test.tsx` --------- Co-authored-by: Faisal Kanout <[email protected]>
1 parent 89254a9 commit 17d5a23

File tree

2 files changed

+92
-19
lines changed

2 files changed

+92
-19
lines changed

x-pack/solutions/observability/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.test.tsx

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import React from 'react';
99
import { chartPluginMock } from '@kbn/charts-plugin/public/mocks';
10-
import { coreMock as mockCoreMock } from '@kbn/core/public/mocks';
10+
import { coreMock } from '@kbn/core/public/mocks';
1111
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
1212
import { ALERT_RULE_PARAMETERS } from '@kbn/rule-data-utils';
1313
import type { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common';
@@ -51,27 +51,46 @@ jest.mock('../../../rule_condition_chart/rule_condition_chart', () => ({
5151
RuleConditionChart: jest.fn(() => <div data-test-subj="RuleConditionChart" />),
5252
}));
5353

54-
jest.mock('../../../../utils/kibana_react', () => ({
55-
useKibana: () => ({
56-
services: {
57-
...mockCoreMock.createStart(),
58-
charts: mockedChartStartContract,
59-
aiops: {
60-
EmbeddableChangePointChart: jest.fn(),
54+
jest.mock('./log_rate_analysis', () => ({
55+
LogRateAnalysis: jest.fn(() => <div data-test-subj="LogRateAnalysis" />),
56+
}));
57+
58+
const mockServices = {
59+
...coreMock.createStart(),
60+
charts: mockedChartStartContract,
61+
aiops: {
62+
EmbeddableChangePointChart: jest.fn(),
63+
},
64+
data: {
65+
search: {
66+
searchSource: {
67+
create: jest.fn().mockResolvedValue({
68+
getField: jest.fn().mockReturnValue({ id: 'test-index' }),
69+
}),
6170
},
62-
data: {
63-
search: jest.fn(),
71+
},
72+
},
73+
share: {
74+
url: {
75+
locators: {
76+
get: jest
77+
.fn()
78+
.mockReturnValue({ getRedirectUrl: jest.fn().mockReturnValue('/view-in-app-url') }),
6479
},
65-
share: {
66-
url: {
67-
locators: {
68-
get: jest
69-
.fn()
70-
.mockReturnValue({ getRedirectUrl: jest.fn().mockReturnValue('/view-in-app-url') }),
71-
},
72-
},
80+
},
81+
},
82+
application: {
83+
capabilities: {
84+
aiops: {
85+
enabled: false,
7386
},
7487
},
88+
},
89+
};
90+
91+
jest.mock('../../../../utils/kibana_react', () => ({
92+
useKibana: () => ({
93+
services: mockServices,
7594
}),
7695
}));
7796

@@ -146,4 +165,54 @@ describe('AlertDetailsAppSection', () => {
146165
'Equation result for min (system.memory.used.pct) + min (system.memory.used.pct) + min (system.memory.used.pct)'
147166
);
148167
});
168+
169+
it('should not render LogRateAnalysis when aiops is disabled', () => {
170+
const result = renderComponent();
171+
expect(result.queryByTestId('LogRateAnalysis')).not.toBeInTheDocument();
172+
});
173+
174+
it('should not render LogRateAnalysis when aiops is disabled and has evaluation values', () => {
175+
const result = renderComponent({}, {
176+
'kibana.alert.evaluation.values': [2500, 5],
177+
} as Object);
178+
expect(result.queryByTestId('LogRateAnalysis')).not.toBeInTheDocument();
179+
});
180+
181+
it('should render LogRateAnalysis when aiops is enabled and has evaluation values', () => {
182+
mockServices.application.capabilities.aiops.enabled = true;
183+
const result = renderComponent({}, {
184+
'kibana.alert.evaluation.values': [2500, 5],
185+
} as Object);
186+
expect(result.getByTestId('LogRateAnalysis')).toBeTruthy();
187+
});
188+
189+
it('should not render LogRateAnalysis when hasEvaluationValues is false', () => {
190+
mockServices.application.capabilities.aiops.enabled = true;
191+
const result = renderComponent({}, {
192+
'kibana.alert.evaluation.values': [null, null],
193+
} as Object);
194+
expect(result.queryByTestId('LogRateAnalysis')).not.toBeInTheDocument();
195+
});
196+
197+
it('should render LogRateAnalysis when hasEvaluationValues has some null but also some values', () => {
198+
mockServices.application.capabilities.aiops.enabled = true;
199+
const result = renderComponent({}, {
200+
'kibana.alert.evaluation.values': [null, 5],
201+
} as Object);
202+
expect(result.getByTestId('LogRateAnalysis')).toBeTruthy();
203+
});
204+
205+
it('should render LogRateAnalysis even when criteria array is empty if conditions are met', () => {
206+
mockServices.application.capabilities.aiops.enabled = true;
207+
const result = renderComponent({}, {
208+
[ALERT_RULE_PARAMETERS]: {
209+
...buildCustomThresholdRule().params,
210+
criteria: [],
211+
} as Object,
212+
'kibana.alert.evaluation.values': [2500, 5],
213+
} as Object);
214+
// Even with empty criteria, it renders the container and LogRateAnalysis if aiops is enabled
215+
expect(result.queryByTestId('thresholdAlertOverviewSection')).toBeInTheDocument();
216+
expect(result.queryByTestId('LogRateAnalysis')).toBeInTheDocument();
217+
});
149218
});

x-pack/solutions/observability/plugins/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ export default function AlertDetailsAppSection({ alert }: AppSectionProps) {
6464
const alertEnd = alert.fields[ALERT_END];
6565
const groups = alert.fields[ALERT_GROUP];
6666
const additionalFilters = useMemo(() => getGroupFilters(groups), [groups]);
67+
const hasEvaluationValues: boolean =
68+
alert.fields[ALERT_EVALUATION_VALUES]?.some((value) => value != null) ?? false;
6769

6870
const chartTitleAndTooltip: Array<{ title: string; tooltip: string }> = [];
6971

@@ -180,7 +182,9 @@ export default function AlertDetailsAppSection({ alert }: AppSectionProps) {
180182
</EuiFlexItem>
181183
);
182184
})}
183-
{aiopsEnabled && <LogRateAnalysis alert={alert} dataView={dataView} services={services} />}
185+
{aiopsEnabled && hasEvaluationValues && (
186+
<LogRateAnalysis alert={alert} dataView={dataView} services={services} />
187+
)}
184188
</EuiFlexGroup>
185189
);
186190
}

0 commit comments

Comments
 (0)