From 91e1bc1e7418bf15ca2eb0e6e5499032c0110c0e Mon Sep 17 00:00:00 2001 From: Jialiang Liang Date: Tue, 10 Dec 2024 16:03:26 -0800 Subject: [PATCH 1/6] Use HTTP service instead of fetch Signed-off-by: Jialiang Liang --- .../create/create_acceleration.tsx | 1 + .../selectors/preview_sql_defintion.tsx | 23 +++++-------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx index 556e6a1a690c..d13956cd25cf 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx @@ -277,6 +277,7 @@ export const CreateAcceleration = ({ resetFlyout={resetFlyout} notifications={notifications} application={application} + http={http} /> diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx index 382d47a61a96..4486aa3e01ae 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx @@ -13,7 +13,7 @@ import { EuiText, } from '@elastic/eui'; import React, { useEffect, useState } from 'react'; -import { ApplicationStart, NotificationsStart } from 'opensearch-dashboards/public'; +import { ApplicationStart, NotificationsStart, HttpStart } from 'opensearch-dashboards/public'; import { queryWorkbenchPluginCheck, queryWorkbenchPluginID, @@ -28,6 +28,7 @@ interface PreviewSQLDefinitionProps { resetFlyout: () => void; notifications: NotificationsStart; application: ApplicationStart; + http: HttpStart; } export const PreviewSQLDefinition = ({ @@ -36,6 +37,7 @@ export const PreviewSQLDefinition = ({ resetFlyout, notifications, application, + http, }: PreviewSQLDefinitionProps) => { const [isPreviewStale, setIsPreviewStale] = useState(false); const [isPreviewTriggered, setIsPreviewTriggered] = useState(false); @@ -60,23 +62,10 @@ export const PreviewSQLDefinition = ({ }; const checkIfSQLWorkbenchPluginIsInstalled = () => { - fetch('/api/status', { - headers: { - 'Content-Type': 'application/json', - 'osd-xsrf': 'true', - 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6', - pragma: 'no-cache', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - }, - method: 'GET', - referrerPolicy: 'strict-origin-when-cross-origin', - mode: 'cors', - credentials: 'include', - }) + http + .get('/api/status') .then(function (response) { - return response.json(); + return response; }) .then((data) => { for (let i = 0; i < data.status.statuses.length; ++i) { From a6bc98d0ac390b529c1e2ef00ab5d6953863eaa7 Mon Sep 17 00:00:00 2001 From: Jialiang Liang Date: Tue, 7 Jan 2025 10:57:23 -0800 Subject: [PATCH 2/6] resolve comments Signed-off-by: Jialiang Liang --- .../acceleration_creation/selectors/preview_sql_defintion.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx index 4486aa3e01ae..3914cc4d9b44 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx @@ -64,9 +64,6 @@ export const PreviewSQLDefinition = ({ const checkIfSQLWorkbenchPluginIsInstalled = () => { http .get('/api/status') - .then(function (response) { - return response; - }) .then((data) => { for (let i = 0; i < data.status.statuses.length; ++i) { if (data.status.statuses[i].id.includes(queryWorkbenchPluginCheck)) { From 02b206785dc943ee1180efc55f2a5cfe81a50412 Mon Sep 17 00:00:00 2001 From: Jialiang Liang Date: Tue, 7 Jan 2025 20:47:55 -0800 Subject: [PATCH 3/6] Add mock for addDanger() Signed-off-by: Jialiang Liang --- .../acceleration_creation/create/create_acceleration.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.test.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.test.tsx index f2acd4afa9e3..c444ea4089e5 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.test.tsx +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.test.tsx @@ -26,6 +26,7 @@ const mockNotifications = { toasts: { addWarning: jest.fn(), addSuccess: jest.fn(), + addDanger: jest.fn(), }, }; From bb3a5cdd564dccae2d64f9d8ac94626f7885f9ca Mon Sep 17 00:00:00 2001 From: Jialiang Liang Date: Wed, 8 Jan 2025 16:21:55 -0800 Subject: [PATCH 4/6] Add unit test for sql definition preview Signed-off-by: Jialiang Liang --- .../preview_sql_defintion.test.tsx.snap | 386 ++++++++++++++++++ .../selectors/preview_sql_defintion.test.tsx | 167 ++++++++ .../selectors/preview_sql_defintion.tsx | 2 +- 3 files changed, 554 insertions(+), 1 deletion(-) create mode 100644 src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_defintion.test.tsx.snap create mode 100644 src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.test.tsx diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_defintion.test.tsx.snap b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_defintion.test.tsx.snap new file mode 100644 index 000000000000..4ac998ac3ac2 --- /dev/null +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_defintion.test.tsx.snap @@ -0,0 +1,386 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PreviewSQLDefinition renders component correctly 1`] = ` + + +

+ Preview SQL definition +

+ + } + id="accordion1" + initialIsOpen={false} + isLoading={false} + isLoadingMessage={false} + paddingSize="l" + > +
+
+ +
+
+ +
+
+ +
+ +
+ + + + + +
+
+ +
+ + + + + +
+
+
+
+ +
+ + + +
+
+                      
+                    
+
+
+
+
+
+ +
+
+ + +`; + +exports[`PreviewSQLDefinition renders correctly 1`] = ` + + +

+ Preview SQL definition +

+ + } + id="accordion1" + initialIsOpen={false} + isLoading={false} + isLoadingMessage={false} + paddingSize="l" + > + + + + Generate preview + + + + + + +
+
+`; diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.test.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.test.tsx new file mode 100644 index 000000000000..8d4c9d159554 --- /dev/null +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.test.tsx @@ -0,0 +1,167 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { PreviewSQLDefinition } from './preview_sql_defintion'; +import { EuiButton } from '@elastic/eui'; +import { coreMock } from './../../../../../../../core/public/mocks'; +import { formValidator, hasError } from '../create/utils'; + +jest.mock('../visual_editors/query_builder', () => ({ + accelerationQueryBuilder: jest.fn(() => 'mocked SQL query'), +})); + +jest.mock('../create/utils', () => ({ + formValidator: jest.fn(() => ({})), + hasError: jest.fn(() => false), +})); + +describe('PreviewSQLDefinition', () => { + const mockCoreStart = coreMock.createStart(); + const mockAccelerationFormData = { + dataSource: 'test_source', + formErrors: {}, + }; + + const mockSetAccelerationFormData = jest.fn(); + const mockResetFlyout = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + mockCoreStart.http.get.mockResolvedValue({ + status: { + statuses: [{ id: 'plugin:queryWorkbenchDashboards' }], + }, + }); + }); + + const mountComponent = async () => { + const wrapper = mount( + + ); + + await act(async () => { + await Promise.resolve(); + }); + wrapper.update(); + + return wrapper; + }; + + test('renders component correctly', async () => { + const wrapper = await mountComponent(); + expect(wrapper).toMatchSnapshot(); + }); + + test('opens SQL Workbench when button is clicked', async () => { + const wrapper = await mountComponent(); + + const button = wrapper.findWhere( + (node) => node.type() === EuiButton && node.prop('data-test-subj') === 'workbenchButton' + ); + + expect(button.exists()).toBe(true); + expect(button.length).toBe(1); + + await act(async () => { + button.prop('onClick')(); + await Promise.resolve(); + }); + + expect(mockCoreStart.application.navigateToApp).toHaveBeenCalledWith(expect.any(String), { + path: '#/test_source', + state: { + language: 'sql', + queryToRun: 'mocked SQL query', + }, + }); + expect(mockResetFlyout).toHaveBeenCalled(); + }); + + test('displays error toast if SQL Workbench plugin check fails', async () => { + mockCoreStart.http.get.mockRejectedValueOnce(new Error('Error checking plugin')); + + await mountComponent(); + + expect(mockCoreStart.notifications.toasts.addDanger).toHaveBeenCalledWith( + 'Error checking Query Workbench Plugin Installation status.' + ); + }); + + test('shows update preview button when form data changes', async () => { + const wrapper = await mountComponent(); + + const previewButton = wrapper.findWhere( + (node) => node.type() === EuiButton && node.text().includes('Generate preview') + ); + + await act(async () => { + previewButton.prop('onClick')(); + await Promise.resolve(); + }); + + await act(async () => { + wrapper.setProps({ + accelerationFormData: { ...mockAccelerationFormData, dataSource: 'new_source' }, + }); + await Promise.resolve(); + }); + wrapper.update(); + + const updateButton = wrapper.findWhere( + (node) => node.type() === EuiButton && node.text().includes('Update preview') + ); + + expect(updateButton.exists()).toBe(true); + }); + + test('validates form before opening SQL Workbench', async () => { + // Mock form validation to return errors + (formValidator as jest.Mock).mockReturnValueOnce({ someField: 'error' }); + (hasError as jest.Mock).mockReturnValueOnce(true); + + const wrapper = await mountComponent(); + + const button = wrapper.findWhere( + (node) => node.type() === EuiButton && node.prop('data-test-subj') === 'workbenchButton' + ); + + await act(async () => { + button.prop('onClick')(); + await Promise.resolve(); + }); + + expect(mockCoreStart.application.navigateToApp).not.toHaveBeenCalled(); + expect(mockSetAccelerationFormData).toHaveBeenCalledWith({ + ...mockAccelerationFormData, + formErrors: { someField: 'error' }, + }); + }); + + test('hides SQL Workbench button when plugin is not installed', async () => { + mockCoreStart.http.get.mockResolvedValueOnce({ + status: { + statuses: [{ id: 'some-other-plugin' }], + }, + }); + + const wrapper = await mountComponent(); + + const button = wrapper.findWhere( + (node) => node.type() === EuiButton && node.prop('data-test-subj') === 'workbenchButton' + ); + + expect(button.exists()).toBe(false); + }); +}); diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx index 3914cc4d9b44..20e9af8e8412 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx @@ -94,7 +94,7 @@ export const PreviewSQLDefinition = ({ }; const queryWorkbenchButton = sqlWorkbenchPLuginExists ? ( - + Edit in Query Workbench ) : ( From 124a8e32b46366a93a5f81bd2f718a2f8b49dc7d Mon Sep 17 00:00:00 2001 From: Jialiang Liang Date: Wed, 8 Jan 2025 16:31:16 -0800 Subject: [PATCH 5/6] Fix the typo of class title O_o Signed-off-by: Jialiang Liang --- .../acceleration_creation/create/create_acceleration.tsx | 2 +- ...sql_defintion.test.tsx => preview_sql_definition.test.tsx} | 4 ++-- .../{preview_sql_defintion.tsx => preview_sql_definition.tsx} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/{preview_sql_defintion.test.tsx => preview_sql_definition.test.tsx} (97%) rename src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/{preview_sql_defintion.tsx => preview_sql_definition.tsx} (100%) diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx index d13956cd25cf..bb30898b6668 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/create/create_acceleration.tsx @@ -36,7 +36,7 @@ import { CatalogCacheManager } from '../../../../../framework/catalog_cache/cach import { IndexAdvancedSettings } from '../selectors/index_advanced_settings'; import { IndexSettingOptions } from '../selectors/index_setting_options'; import { IndexTypeSelector } from '../selectors/index_type_selector'; -import { PreviewSQLDefinition } from '../selectors/preview_sql_defintion'; +import { PreviewSQLDefinition } from '../selectors/preview_sql_definition'; import { AccelerationDataSourceSelector } from '../selectors/source_selector'; import { QueryVisualEditor } from '../visual_editors/query_visual_editor'; import { CreateAccelerationButton } from './create_acceleration_button'; diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.test.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_definition.test.tsx similarity index 97% rename from src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.test.tsx rename to src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_definition.test.tsx index 8d4c9d159554..c7d626cde10f 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.test.tsx +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_definition.test.tsx @@ -6,9 +6,9 @@ import React from 'react'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; -import { PreviewSQLDefinition } from './preview_sql_defintion'; +import { PreviewSQLDefinition } from './preview_sql_definition'; import { EuiButton } from '@elastic/eui'; -import { coreMock } from './../../../../../../../core/public/mocks'; +import { coreMock } from '../../../../../../../core/public/mocks'; import { formValidator, hasError } from '../create/utils'; jest.mock('../visual_editors/query_builder', () => ({ diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_definition.tsx similarity index 100% rename from src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_defintion.tsx rename to src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/preview_sql_definition.tsx From 63f83783b1ddfb45ee2adc0709b596888c66067c Mon Sep 17 00:00:00 2001 From: Jialiang Liang Date: Wed, 8 Jan 2025 17:33:31 -0800 Subject: [PATCH 6/6] Fix the snapshot issue Signed-off-by: Jialiang Liang --- ...p => preview_sql_definition.test.tsx.snap} | 47 ------------------- 1 file changed, 47 deletions(-) rename src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/{preview_sql_defintion.test.tsx.snap => preview_sql_definition.test.tsx.snap} (92%) diff --git a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_defintion.test.tsx.snap b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_definition.test.tsx.snap similarity index 92% rename from src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_defintion.test.tsx.snap rename to src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_definition.test.tsx.snap index 4ac998ac3ac2..2e81bf73d5bd 100644 --- a/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_defintion.test.tsx.snap +++ b/src/plugins/data_source_management/public/components/direct_query_data_sources_components/acceleration_creation/selectors/__snapshots__/preview_sql_definition.test.tsx.snap @@ -337,50 +337,3 @@ exports[`PreviewSQLDefinition renders component correctly 1`] = ` `; - -exports[`PreviewSQLDefinition renders correctly 1`] = ` - - -

- Preview SQL definition -

- - } - id="accordion1" - initialIsOpen={false} - isLoading={false} - isLoadingMessage={false} - paddingSize="l" - > - - - - Generate preview - - - - - - -
-
-`;