Skip to content

Commit

Permalink
Fix table strings and add unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Chenyang Ji <cyji@amazon.com>
  • Loading branch information
ansjcy committed Nov 6, 2024
1 parent dcda4b8 commit 2dfcb84
Show file tree
Hide file tree
Showing 5 changed files with 250 additions and 18 deletions.
6 changes: 3 additions & 3 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ export const LATENCY = 'Latency';
export const CPU_TIME = 'CPU Time';
export const MEMORY_USAGE = 'Memory Usage';
export const INDICES = 'Indices';
export const SEARCH_TYPE = 'Search type';
export const NODE_ID = 'Coordinator node ID';
export const TOTAL_SHARDS = 'Total shards';
export const SEARCH_TYPE = 'Search Type';
export const NODE_ID = 'Coordinator Node ID';
export const TOTAL_SHARDS = 'Total Shards';
24 changes: 12 additions & 12 deletions public/components/__snapshots__/app.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
>
<span
class="euiFilterButton__textShift"
data-text="Search type"
title="Search type"
data-text="Search Type"
title="Search Type"
>
Search type
Search Type
</span>
</span>
</span>
Expand Down Expand Up @@ -215,10 +215,10 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
>
<span
class="euiFilterButton__textShift"
data-text="Coordinator node ID"
title="Coordinator node ID"
data-text="Coordinator Node ID"
title="Coordinator Node ID"
>
Coordinator node ID
Coordinator Node ID
</span>
</span>
</span>
Expand Down Expand Up @@ -566,9 +566,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
>
<span
class="euiTableCellContent__text"
title="Search type"
title="Search Type"
>
Search type
Search Type
</span>
</span>
</button>
Expand All @@ -591,9 +591,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
>
<span
class="euiTableCellContent__text"
title="Coordinator node ID"
title="Coordinator Node ID"
>
Coordinator node ID
Coordinator Node ID
</span>
</span>
</button>
Expand All @@ -616,9 +616,9 @@ exports[`<QueryInsightsDashboardsApp /> spec renders the component 1`] = `
>
<span
class="euiTableCellContent__text"
title="Total shards"
title="Total Shards"
>
Total shards
Total Shards
</span>
</span>
</button>
Expand Down
128 changes: 128 additions & 0 deletions public/pages/Configuration/Configuration.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { MemoryRouter } from 'react-router-dom';
import Configuration from './Configuration';

const mockConfigInfo = jest.fn();
const mockCoreStart = {
chrome: {
setBreadcrumbs: jest.fn(),
},
};

const defaultLatencySettings = {
isEnabled: true,
currTopN: '5',
currWindowSize: '10',
currTimeUnit: 'MINUTES',
};
const defaultCpuSettings = {
isEnabled: false,
currTopN: '10',
currWindowSize: '1',
currTimeUnit: 'HOURS',
};
const defaultMemorySettings = {
isEnabled: false,
currTopN: '15',
currWindowSize: '2',
currTimeUnit: 'HOURS',
};

const renderConfiguration = (overrides = {}) => {
render(
<MemoryRouter>
<Configuration
latencySettings={{ ...defaultLatencySettings, ...overrides }}
cpuSettings={defaultCpuSettings}
memorySettings={defaultMemorySettings}
configInfo={mockConfigInfo}
// @ts-ignore
core={mockCoreStart}
/>
</MemoryRouter>
);
};

const getWindowSizeConfigurations = () => screen.getAllByRole('combobox');
const getTopNSizeConfiguration = () => screen.getByRole('spinbutton');
const getEnableToggle = () => screen.getByRole('switch');

describe('Configuration Component', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('renders with default settings', () => {
renderConfiguration();
// main header
expect(
screen.getByRole('heading', { name: /Top n queries monitoring configuration settings/i })
).toBeInTheDocument();
// section headers
expect(screen.getByRole('heading', { name: /Metric Type/i })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: /Enabled/i })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: /Value of N/i })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: /Window size/i })).toBeInTheDocument();
// Check values for window size configurations
const selectBoxes = getWindowSizeConfigurations();
expect(selectBoxes[0]).toHaveValue('latency');
expect(selectBoxes[1]).toHaveValue('10');
expect(selectBoxes[2]).toHaveValue('MINUTES');
// Check the value for top n size configurations
expect(getTopNSizeConfiguration()).toHaveValue(5);
// Check the value for enabled switch
const enableBox = getEnableToggle();
expect(enableBox).toBeInTheDocument();
expect(enableBox).toBeChecked();
});

it('updates state when toggling metrics and enables Save button when changes are made', () => {
renderConfiguration();
// before toggling the metric
expect(getWindowSizeConfigurations()[0]).toHaveValue('latency');
expect(getEnableToggle()).toBeChecked();
// toggle the metric
fireEvent.change(getWindowSizeConfigurations()[0], { target: { value: 'cpu' } });
// after toggling the metric
expect(getWindowSizeConfigurations()[0]).toHaveValue('cpu');
// the enabled box should be disabled by default based on our configuration
const cpuEnableBox = getEnableToggle();
expect(cpuEnableBox).toBeInTheDocument();
expect(cpuEnableBox).not.toBeChecked();

fireEvent.click(getEnableToggle());
expect(getEnableToggle()).toBeChecked();
expect(screen.getByText('Save')).toBeEnabled();
});

it('validates topNSize and windowSize inputs and disables Save button for invalid input', () => {
renderConfiguration();
fireEvent.change(getTopNSizeConfiguration(), { target: { value: '101' } });
expect(screen.queryByText('Save')).not.toBeInTheDocument();
fireEvent.change(getWindowSizeConfigurations()[1], { target: { value: '999' } });
expect(screen.queryByText('Save')).not.toBeInTheDocument();
});

it('calls configInfo and navigates on Save button click', async () => {
renderConfiguration();
fireEvent.change(getTopNSizeConfiguration(), { target: { value: '7' } });
fireEvent.click(screen.getByText('Save'));
await waitFor(() => {
expect(mockConfigInfo).toHaveBeenCalledWith(false, true, 'latency', '7', '10', 'MINUTES');
});
});

it('resets state on Cancel button click', async () => {
renderConfiguration();
fireEvent.change(getTopNSizeConfiguration(), { target: { value: '7' } });
fireEvent.click(screen.getByText('Cancel'));
expect(getTopNSizeConfiguration()).toHaveValue(5); // Resets to initial value
});
});
106 changes: 106 additions & 0 deletions public/pages/QueryInsights/QueryInsights.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import QueryInsights from './QueryInsights';
import { MemoryRouter } from 'react-router-dom';

// Mock functions and data
const mockOnTimeChange = jest.fn();
const mockCore = {
chrome: {
setBreadcrumbs: jest.fn(),
},
};

// TODO: change to use MockQueries once https://github.com/opensearch-project/query-insights-dashboards/pull/21/files is merged
const sampleQueries = [
{
timestamp: 1633046400000,
measurements: {},
indices: ['index1', 'index2'],
search_type: 'QUERY_THEN_FETCH',
node_id: 'node_1',
total_shards: 5,
source: {},
labels: {},
phase_latency_map: {},
task_resource_usages: [],
},
{
timestamp: 1633132800000,
measurements: {},
indices: ['index3'],
search_type: 'DFS_QUERY_THEN_FETCH',
node_id: 'node_2',
total_shards: 3,
source: {},
labels: {},
phase_latency_map: {},
task_resource_usages: [],
},
];

const renderQueryInsights = () => {
render(
<MemoryRouter>
<QueryInsights
queries={sampleQueries}
loading={false}
onTimeChange={mockOnTimeChange}
recentlyUsedRanges={[]}
currStart="now-15m"
currEnd="now"
// @ts-ignore
core={mockCore}
/>
</MemoryRouter>
);
};

describe('QueryInsights Component', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('renders the table with the correct columns and data', () => {
renderQueryInsights();

// Check that the table and columns render correctly
expect(document.querySelector('span[title="Timestamp"]')).toBeInTheDocument();
expect(document.querySelector('span[title="Latency"]')).toBeInTheDocument();
expect(document.querySelector('span[title="CPU Time"]')).toBeInTheDocument();
expect(document.querySelector('span[title="Memory Usage"]')).toBeInTheDocument();
expect(document.querySelector('span[title="Indices"]')).toBeInTheDocument();
expect(document.querySelector('span[title="Search Type"]')).toBeInTheDocument();
expect(document.querySelector('span[title="Coordinator Node ID"]')).toBeInTheDocument();
expect(document.querySelector('span[title="Total Shards"]')).toBeInTheDocument();
// TODO add tests for the values
});

it('calls setBreadcrumbs on mount', () => {
renderQueryInsights();
expect(mockCore.chrome.setBreadcrumbs).toHaveBeenCalledWith([
{
text: 'Query insights',
href: '/queryInsights',
onClick: expect.any(Function),
},
]);
});

it('triggers onTimeChange when the date picker changes', () => {
renderQueryInsights();

// Find the date picker update button
const updateButton = screen.getByRole('button', { name: /Refresh/i });
fireEvent.click(updateButton);

// Verify the onTimeChange callback is triggered
expect(mockOnTimeChange).toHaveBeenCalled();
});
});
4 changes: 1 addition & 3 deletions types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { ISearchSource } from 'src/plugins/data/public';

export interface SearchQueryRecord {
timestamp: number;
measurements: {
Expand All @@ -14,7 +12,7 @@ export interface SearchQueryRecord {
};
total_shards: number;
node_id: string;
source: ISearchSource;
source: Record<string, any>;
labels: Record<string, string>;
search_type: string;
indices: string[];
Expand Down

0 comments on commit 2dfcb84

Please sign in to comment.