Skip to content

Commit 2dfcb84

Browse files
committed
Fix table strings and add unit tests
Signed-off-by: Chenyang Ji <[email protected]>
1 parent dcda4b8 commit 2dfcb84

File tree

5 files changed

+250
-18
lines changed

5 files changed

+250
-18
lines changed

common/constants.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ export const LATENCY = 'Latency';
88
export const CPU_TIME = 'CPU Time';
99
export const MEMORY_USAGE = 'Memory Usage';
1010
export const INDICES = 'Indices';
11-
export const SEARCH_TYPE = 'Search type';
12-
export const NODE_ID = 'Coordinator node ID';
13-
export const TOTAL_SHARDS = 'Total shards';
11+
export const SEARCH_TYPE = 'Search Type';
12+
export const NODE_ID = 'Coordinator Node ID';
13+
export const TOTAL_SHARDS = 'Total Shards';

public/components/__snapshots__/app.test.tsx.snap

+12-12
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,10 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
172172
>
173173
<span
174174
class="euiFilterButton__textShift"
175-
data-text="Search type"
176-
title="Search type"
175+
data-text="Search Type"
176+
title="Search Type"
177177
>
178-
Search type
178+
Search Type
179179
</span>
180180
</span>
181181
</span>
@@ -215,10 +215,10 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
215215
>
216216
<span
217217
class="euiFilterButton__textShift"
218-
data-text="Coordinator node ID"
219-
title="Coordinator node ID"
218+
data-text="Coordinator Node ID"
219+
title="Coordinator Node ID"
220220
>
221-
Coordinator node ID
221+
Coordinator Node ID
222222
</span>
223223
</span>
224224
</span>
@@ -566,9 +566,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
566566
>
567567
<span
568568
class="euiTableCellContent__text"
569-
title="Search type"
569+
title="Search Type"
570570
>
571-
Search type
571+
Search Type
572572
</span>
573573
</span>
574574
</button>
@@ -591,9 +591,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
591591
>
592592
<span
593593
class="euiTableCellContent__text"
594-
title="Coordinator node ID"
594+
title="Coordinator Node ID"
595595
>
596-
Coordinator node ID
596+
Coordinator Node ID
597597
</span>
598598
</span>
599599
</button>
@@ -616,9 +616,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
616616
>
617617
<span
618618
class="euiTableCellContent__text"
619-
title="Total shards"
619+
title="Total Shards"
620620
>
621-
Total shards
621+
Total Shards
622622
</span>
623623
</span>
624624
</button>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import React from 'react';
7+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
8+
import '@testing-library/jest-dom/extend-expect';
9+
import { MemoryRouter } from 'react-router-dom';
10+
import Configuration from './Configuration';
11+
12+
const mockConfigInfo = jest.fn();
13+
const mockCoreStart = {
14+
chrome: {
15+
setBreadcrumbs: jest.fn(),
16+
},
17+
};
18+
19+
const defaultLatencySettings = {
20+
isEnabled: true,
21+
currTopN: '5',
22+
currWindowSize: '10',
23+
currTimeUnit: 'MINUTES',
24+
};
25+
const defaultCpuSettings = {
26+
isEnabled: false,
27+
currTopN: '10',
28+
currWindowSize: '1',
29+
currTimeUnit: 'HOURS',
30+
};
31+
const defaultMemorySettings = {
32+
isEnabled: false,
33+
currTopN: '15',
34+
currWindowSize: '2',
35+
currTimeUnit: 'HOURS',
36+
};
37+
38+
const renderConfiguration = (overrides = {}) => {
39+
render(
40+
<MemoryRouter>
41+
<Configuration
42+
latencySettings={{ ...defaultLatencySettings, ...overrides }}
43+
cpuSettings={defaultCpuSettings}
44+
memorySettings={defaultMemorySettings}
45+
configInfo={mockConfigInfo}
46+
// @ts-ignore
47+
core={mockCoreStart}
48+
/>
49+
</MemoryRouter>
50+
);
51+
};
52+
53+
const getWindowSizeConfigurations = () => screen.getAllByRole('combobox');
54+
const getTopNSizeConfiguration = () => screen.getByRole('spinbutton');
55+
const getEnableToggle = () => screen.getByRole('switch');
56+
57+
describe('Configuration Component', () => {
58+
beforeEach(() => {
59+
jest.clearAllMocks();
60+
});
61+
62+
it('renders with default settings', () => {
63+
renderConfiguration();
64+
// main header
65+
expect(
66+
screen.getByRole('heading', { name: /Top n queries monitoring configuration settings/i })
67+
).toBeInTheDocument();
68+
// section headers
69+
expect(screen.getByRole('heading', { name: /Metric Type/i })).toBeInTheDocument();
70+
expect(screen.getByRole('heading', { name: /Enabled/i })).toBeInTheDocument();
71+
expect(screen.getByRole('heading', { name: /Value of N/i })).toBeInTheDocument();
72+
expect(screen.getByRole('heading', { name: /Window size/i })).toBeInTheDocument();
73+
// Check values for window size configurations
74+
const selectBoxes = getWindowSizeConfigurations();
75+
expect(selectBoxes[0]).toHaveValue('latency');
76+
expect(selectBoxes[1]).toHaveValue('10');
77+
expect(selectBoxes[2]).toHaveValue('MINUTES');
78+
// Check the value for top n size configurations
79+
expect(getTopNSizeConfiguration()).toHaveValue(5);
80+
// Check the value for enabled switch
81+
const enableBox = getEnableToggle();
82+
expect(enableBox).toBeInTheDocument();
83+
expect(enableBox).toBeChecked();
84+
});
85+
86+
it('updates state when toggling metrics and enables Save button when changes are made', () => {
87+
renderConfiguration();
88+
// before toggling the metric
89+
expect(getWindowSizeConfigurations()[0]).toHaveValue('latency');
90+
expect(getEnableToggle()).toBeChecked();
91+
// toggle the metric
92+
fireEvent.change(getWindowSizeConfigurations()[0], { target: { value: 'cpu' } });
93+
// after toggling the metric
94+
expect(getWindowSizeConfigurations()[0]).toHaveValue('cpu');
95+
// the enabled box should be disabled by default based on our configuration
96+
const cpuEnableBox = getEnableToggle();
97+
expect(cpuEnableBox).toBeInTheDocument();
98+
expect(cpuEnableBox).not.toBeChecked();
99+
100+
fireEvent.click(getEnableToggle());
101+
expect(getEnableToggle()).toBeChecked();
102+
expect(screen.getByText('Save')).toBeEnabled();
103+
});
104+
105+
it('validates topNSize and windowSize inputs and disables Save button for invalid input', () => {
106+
renderConfiguration();
107+
fireEvent.change(getTopNSizeConfiguration(), { target: { value: '101' } });
108+
expect(screen.queryByText('Save')).not.toBeInTheDocument();
109+
fireEvent.change(getWindowSizeConfigurations()[1], { target: { value: '999' } });
110+
expect(screen.queryByText('Save')).not.toBeInTheDocument();
111+
});
112+
113+
it('calls configInfo and navigates on Save button click', async () => {
114+
renderConfiguration();
115+
fireEvent.change(getTopNSizeConfiguration(), { target: { value: '7' } });
116+
fireEvent.click(screen.getByText('Save'));
117+
await waitFor(() => {
118+
expect(mockConfigInfo).toHaveBeenCalledWith(false, true, 'latency', '7', '10', 'MINUTES');
119+
});
120+
});
121+
122+
it('resets state on Cancel button click', async () => {
123+
renderConfiguration();
124+
fireEvent.change(getTopNSizeConfiguration(), { target: { value: '7' } });
125+
fireEvent.click(screen.getByText('Cancel'));
126+
expect(getTopNSizeConfiguration()).toHaveValue(5); // Resets to initial value
127+
});
128+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import React from 'react';
7+
import { render, screen, fireEvent } from '@testing-library/react';
8+
import '@testing-library/jest-dom/extend-expect';
9+
import QueryInsights from './QueryInsights';
10+
import { MemoryRouter } from 'react-router-dom';
11+
12+
// Mock functions and data
13+
const mockOnTimeChange = jest.fn();
14+
const mockCore = {
15+
chrome: {
16+
setBreadcrumbs: jest.fn(),
17+
},
18+
};
19+
20+
// TODO: change to use MockQueries once https://github.com/opensearch-project/query-insights-dashboards/pull/21/files is merged
21+
const sampleQueries = [
22+
{
23+
timestamp: 1633046400000,
24+
measurements: {},
25+
indices: ['index1', 'index2'],
26+
search_type: 'QUERY_THEN_FETCH',
27+
node_id: 'node_1',
28+
total_shards: 5,
29+
source: {},
30+
labels: {},
31+
phase_latency_map: {},
32+
task_resource_usages: [],
33+
},
34+
{
35+
timestamp: 1633132800000,
36+
measurements: {},
37+
indices: ['index3'],
38+
search_type: 'DFS_QUERY_THEN_FETCH',
39+
node_id: 'node_2',
40+
total_shards: 3,
41+
source: {},
42+
labels: {},
43+
phase_latency_map: {},
44+
task_resource_usages: [],
45+
},
46+
];
47+
48+
const renderQueryInsights = () => {
49+
render(
50+
<MemoryRouter>
51+
<QueryInsights
52+
queries={sampleQueries}
53+
loading={false}
54+
onTimeChange={mockOnTimeChange}
55+
recentlyUsedRanges={[]}
56+
currStart="now-15m"
57+
currEnd="now"
58+
// @ts-ignore
59+
core={mockCore}
60+
/>
61+
</MemoryRouter>
62+
);
63+
};
64+
65+
describe('QueryInsights Component', () => {
66+
beforeEach(() => {
67+
jest.clearAllMocks();
68+
});
69+
70+
it('renders the table with the correct columns and data', () => {
71+
renderQueryInsights();
72+
73+
// Check that the table and columns render correctly
74+
expect(document.querySelector('span[title="Timestamp"]')).toBeInTheDocument();
75+
expect(document.querySelector('span[title="Latency"]')).toBeInTheDocument();
76+
expect(document.querySelector('span[title="CPU Time"]')).toBeInTheDocument();
77+
expect(document.querySelector('span[title="Memory Usage"]')).toBeInTheDocument();
78+
expect(document.querySelector('span[title="Indices"]')).toBeInTheDocument();
79+
expect(document.querySelector('span[title="Search Type"]')).toBeInTheDocument();
80+
expect(document.querySelector('span[title="Coordinator Node ID"]')).toBeInTheDocument();
81+
expect(document.querySelector('span[title="Total Shards"]')).toBeInTheDocument();
82+
// TODO add tests for the values
83+
});
84+
85+
it('calls setBreadcrumbs on mount', () => {
86+
renderQueryInsights();
87+
expect(mockCore.chrome.setBreadcrumbs).toHaveBeenCalledWith([
88+
{
89+
text: 'Query insights',
90+
href: '/queryInsights',
91+
onClick: expect.any(Function),
92+
},
93+
]);
94+
});
95+
96+
it('triggers onTimeChange when the date picker changes', () => {
97+
renderQueryInsights();
98+
99+
// Find the date picker update button
100+
const updateButton = screen.getByRole('button', { name: /Refresh/i });
101+
fireEvent.click(updateButton);
102+
103+
// Verify the onTimeChange callback is triggered
104+
expect(mockOnTimeChange).toHaveBeenCalled();
105+
});
106+
});

types/types.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import { ISearchSource } from 'src/plugins/data/public';
7-
86
export interface SearchQueryRecord {
97
timestamp: number;
108
measurements: {
@@ -14,7 +12,7 @@ export interface SearchQueryRecord {
1412
};
1513
total_shards: number;
1614
node_id: string;
17-
source: ISearchSource;
15+
source: Record<string, any>;
1816
labels: Record<string, string>;
1917
search_type: string;
2018
indices: string[];

0 commit comments

Comments
 (0)