[Infra] Send Host View Total Host Count Retrieved event on every query submission in hosts inventory (#202691)

## Summary

Fixes https://github.com/elastic/kibana/issues/202441

This PR reintroduces the `Host View Total Host Count Retrieved` event,
which was unintentionally removed in the past. It has been added back to
the same position in the code as previously

|Scenario|Event|
|-|-|
|Page load|![Screenshot 2024-12-03 at 12 37
28](https://github.com/user-attachments/assets/8a12d713-219b-4c1f-a08e-7b475634b4fc)|
|Query|![Screenshot 2024-12-03 at 12 40
12](https://github.com/user-attachments/assets/501a8a81-b0b0-46a6-a470-dceeba791c01)|
|Filter|![Screenshot 2024-12-03 at 12 40
56](https://github.com/user-attachments/assets/586f2176-b05b-4571-b3d8-f3f9cb803249)|
This commit is contained in:
Irene Blanco 2024-12-04 12:41:44 +01:00 committed by GitHub
parent 140f80d533
commit 51ef0e7034
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 159 additions and 2 deletions

View file

@ -0,0 +1,144 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { renderHook } from '@testing-library/react';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import * as useKibanaContextForPluginHook from '../../../../hooks/use_kibana';
import * as useUnifiedSearchHooks from './use_unified_search';
import { useHostCount } from './use_host_count';
jest.mock('../../../../hooks/use_fetcher');
jest.mock('../../../../hooks/use_kibana');
jest.mock('./use_unified_search');
describe('useHostCount', () => {
const useKibanaContextForPluginMock = useKibanaContextForPlugin as jest.MockedFunction<
typeof useKibanaContextForPlugin
>;
const telemetryMock = { reportHostsViewTotalHostCountRetrieved: jest.fn() };
useKibanaContextForPluginMock.mockReturnValue({
services: { telemetry: telemetryMock },
} as unknown as ReturnType<typeof useKibanaContextForPluginHook.useKibanaContextForPlugin>);
const useUnifiedSearchContextMock =
useUnifiedSearchHooks.useUnifiedSearchContext as jest.MockedFunction<
typeof useUnifiedSearchHooks.useUnifiedSearchContext
>;
const mockUseUnifiedContext = (searchCriteria: any) => {
useUnifiedSearchContextMock.mockReturnValue({
buildQuery: jest.fn(() => 'query'),
parsedDateRange: { from: '', to: '' },
searchCriteria,
} as unknown as ReturnType<typeof useUnifiedSearchHooks.useUnifiedSearchContext>);
};
describe('when data is fetched', () => {
const fetcherDataMock = { count: 10 };
beforeAll(() => {
(useFetcher as jest.Mock).mockReturnValue({
data: fetcherDataMock,
status: 'success',
error: null,
});
});
afterEach(() => {
jest.clearAllMocks();
});
describe('and there is no filters or query applied', () => {
it('should call reportHostsViewTotalHostCountRetrieved with the correct data', async () => {
mockUseUnifiedContext({
query: { query: null },
filters: [],
panelFilters: [],
});
await renderHook(() => useHostCount());
expect(telemetryMock.reportHostsViewTotalHostCountRetrieved).toHaveBeenCalledWith({
total: fetcherDataMock.count,
with_query: false,
with_filters: false,
});
});
});
describe('and query is applied', () => {
it('should call reportHostsViewTotalHostCountRetrieved with the correct data', async () => {
mockUseUnifiedContext({ query: { query: 'test' }, filters: [], panelFilters: [] });
await renderHook(() => useHostCount());
expect(telemetryMock.reportHostsViewTotalHostCountRetrieved).toHaveBeenCalledWith({
total: fetcherDataMock.count,
with_query: true,
with_filters: false,
});
});
});
describe('and filters are applied', () => {
it('should call reportHostsViewTotalHostCountRetrieved with the correct data', async () => {
mockUseUnifiedContext({
query: { query: null },
filters: [{ filter: 'filter' }],
panelFilters: [],
});
await renderHook(() => useHostCount());
expect(telemetryMock.reportHostsViewTotalHostCountRetrieved).toHaveBeenCalledWith({
total: fetcherDataMock.count,
with_query: false,
with_filters: true,
});
});
});
describe('and panel filters are applied', () => {
it('should call reportHostsViewTotalHostCountRetrieved with the correct data', async () => {
mockUseUnifiedContext({
query: { query: null },
filters: [{ filter: 'filter' }],
panelFilters: [{ filter: 'filter' }],
});
await renderHook(() => useHostCount());
expect(telemetryMock.reportHostsViewTotalHostCountRetrieved).toHaveBeenCalledWith({
total: fetcherDataMock.count,
with_query: false,
with_filters: true,
});
});
});
});
describe('when data is fetched with error', () => {
beforeAll(() => {
(useFetcher as jest.Mock).mockReturnValue({
data: {},
status: 'error',
error: 'error',
});
});
it('should NOT call reportHostsViewTotalHostCountRetrieved ', async () => {
mockUseUnifiedContext(null);
await renderHook(() => useHostCount());
expect(telemetryMock.reportHostsViewTotalHostCountRetrieved).not.toHaveBeenCalled();
});
});
});

View file

@ -7,13 +7,16 @@
import createContainer from 'constate';
import { decodeOrThrow } from '@kbn/io-ts-utils';
import { useMemo } from 'react';
import { useMemo, useEffect } from 'react';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { GetInfraAssetCountResponsePayloadRT } from '../../../../../common/http_api';
import { isPending, useFetcher } from '../../../../hooks/use_fetcher';
import { useUnifiedSearchContext } from './use_unified_search';
export const useHostCount = () => {
const { buildQuery, parsedDateRange } = useUnifiedSearchContext();
const { buildQuery, parsedDateRange, searchCriteria } = useUnifiedSearchContext();
const { services } = useKibanaContextForPlugin();
const { telemetry } = services;
const payload = useMemo(
() =>
@ -37,6 +40,16 @@ export const useHostCount = () => {
[payload]
);
useEffect(() => {
if (data && !error) {
telemetry.reportHostsViewTotalHostCountRetrieved({
total: data.count ?? 0,
with_query: !!searchCriteria.query.query,
with_filters: searchCriteria.filters.length > 0 || searchCriteria.panelFilters.length > 0,
});
}
}, [data, error, payload, searchCriteria, telemetry]);
return {
errors: error,
loading: isPending(status),