From ed0d3ddd9ec7879e0c5341f82286c5eedd0489db Mon Sep 17 00:00:00 2001 From: Ashwin P Chandran Date: Wed, 23 Aug 2023 23:14:51 +0000 Subject: [PATCH] minor fixes before merge to main Signed-off-by: Ashwin P Chandran --- .github/workflows/build_and_test_workflow.yml | 4 +- .github/workflows/cypress_workflow.yml | 4 +- README.md | 2 +- .../dashboard_listing.test.tsx | 237 ++++++++---------- 4 files changed, 104 insertions(+), 143 deletions(-) diff --git a/.github/workflows/build_and_test_workflow.yml b/.github/workflows/build_and_test_workflow.yml index cdbbca8a84ec..57c7f60ba58c 100644 --- a/.github/workflows/build_and_test_workflow.yml +++ b/.github/workflows/build_and_test_workflow.yml @@ -3,10 +3,10 @@ name: Build and test -# trigger on every commit push and PR for all branches except pushes for backport branches and feature branches +# trigger on every commit push and PR for all branches except pushes for backport branches on: push: - branches: ['**', '!backport/**', '!feature/**'] + branches: ['**', '!backport/**'] paths-ignore: - '**/*.md' - 'docs/**' diff --git a/.github/workflows/cypress_workflow.yml b/.github/workflows/cypress_workflow.yml index 1c15ad3f18ed..5e78785f9b88 100644 --- a/.github/workflows/cypress_workflow.yml +++ b/.github/workflows/cypress_workflow.yml @@ -1,9 +1,9 @@ name: Run cypress tests -# trigger on every PR for all branches except feature branches +# trigger on every PR for all branches on: pull_request: - branches: [ '**', '!feature/**' ] + branches: [ '**' ] paths-ignore: - '**/*.md' diff --git a/README.md b/README.md index c7b6d09e1f3d..5bafaf4c7c1a 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ Copyright OpenSearch Contributors. See [NOTICE](NOTICE.txt) for details. [codecov-badge]: https://codecov.io/gh/opensearch-project/OpenSearch-Dashboards/branch/main/graphs/badge.svg [codecov-link]: https://app.codecov.io/gh/opensearch-project/OpenSearch-Dashboards [link-checker-badge]: https://github.com/opensearch-project/OpenSearch-Dashboards/actions/workflows/links_checker.yml/badge.svg -[link-checker-link]: https://github.com/opensearch-project/OpenSearch-Dashboards/actions/workflows/links_checker.yml \ No newline at end of file +[link-checker-link]: https://github.com/opensearch-project/OpenSearch-Dashboards/actions/workflows/links_checker.yml diff --git a/src/plugins/dashboard/public/application/components/dashboard_listing/dashboard_listing.test.tsx b/src/plugins/dashboard/public/application/components/dashboard_listing/dashboard_listing.test.tsx index 3d9c8404be5e..edbd0298876b 100644 --- a/src/plugins/dashboard/public/application/components/dashboard_listing/dashboard_listing.test.tsx +++ b/src/plugins/dashboard/public/application/components/dashboard_listing/dashboard_listing.test.tsx @@ -9,28 +9,6 @@ * GitHub history for details. */ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// TODO: -// Rewrite the dashboard listing tests for the new component -// https://github.com/opensearch-project/OpenSearch-Dashboards/issues/4051 jest.mock( 'lodash', () => ({ @@ -46,63 +24,85 @@ jest.mock( { virtual: true } ); +let mockURLsearch = + '?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))'; + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useLocation: () => ({ + search: mockURLsearch, + pathname: '', + hash: '', + state: undefined, + }), +})); + import React from 'react'; -import { shallow } from 'enzyme'; +import { mount } from 'enzyme'; import { DashboardListing } from './dashboard_listing'; - -const find = (num: number) => { - const hits = []; - for (let i = 0; i < num; i++) { - hits.push({ - id: `dashboard${i}`, - title: `dashboard${i} title`, - description: `dashboard${i} desc`, - }); - } - return Promise.resolve({ - total: num, - hits, - }); -}; - -test.skip('renders empty page in before initial fetch to avoid flickering', () => { - const component = shallow( - {}} - createItem={() => {}} - editItem={() => {}} - viewItem={() => {}} - dashboardItemCreatorClickHandler={() => {}} - dashboardItemCreators={() => []} - initialPageSize={10} - listingLimit={1000} - hideWriteControls={false} - core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }} - /> +import { createDashboardServicesMock } from '../../utils/mocks'; +import { OpenSearchDashboardsContextProvider } from 'src/plugins/opensearch_dashboards_react/public'; +import { I18nProvider } from '@osd/i18n/react'; +import { IOsdUrlStateStorage } from 'src/plugins/opensearch_dashboards_utils/public'; + +function wrapDashboardListingInContext(mockServices: any) { + const osdUrlStateStorage = ({ + set: jest.fn(), + get: jest.fn(() => ({ linked: false })), + flush: jest.fn(), + } as unknown) as IOsdUrlStateStorage; + const services = { + ...mockServices, + osdUrlStateStorage, + dashboardProviders: () => { + return { + dashboard: { + appId: '1', + savedObjectsName: 'dashboardSavedObjects', + viewUrlPathFn: jest.fn(), + editUrlPathFn: jest.fn(), + }, + }; + }, + }; + + return ( + + + + + ); - expect(component).toMatchSnapshot(); -}); +} + +describe('dashboard listing', () => { + let mockServices: any; + + beforeEach(() => { + mockServices = createDashboardServicesMock(); + mockServices.savedObjectsClient.find = () => { + const hits: any[] = []; + for (let i = 0; i < 2; i++) { + hits.push({ + type: `dashboard`, + id: `dashboard${i}`, + attributes: { + title: `dashboard${i}`, + description: `dashboard${i} desc`, + }, + }); + } + return Promise.resolve({ + savedObjects: hits, + }); + }; + mockServices.dashboardConfig.getHideWriteControls = () => false; + mockServices.savedObjectsPublic.settings.getListingLimit = () => 100; + }); -describe.skip('after fetch', () => { - test('initialFilter', async () => { - const component = shallow( - {}} - createItem={() => {}} - editItem={() => {}} - viewItem={() => {}} - dashboardItemCreatorClickHandler={() => {}} - dashboardItemCreators={() => []} - listingLimit={1000} - hideWriteControls={false} - initialPageSize={10} - initialFilter="my dashboard" - core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }} - /> - ); + test('renders table rows', async () => { + const component = mount(wrapDashboardListingInContext(mockServices)); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); @@ -112,22 +112,16 @@ describe.skip('after fetch', () => { expect(component).toMatchSnapshot(); }); - test('renders table rows', async () => { - const component = shallow( - {}} - createItem={() => {}} - editItem={() => {}} - viewItem={() => {}} - dashboardItemCreatorClickHandler={() => {}} - dashboardItemCreators={() => []} - listingLimit={1000} - initialPageSize={10} - hideWriteControls={false} - core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }} - /> - ); + test('renders call to action when no dashboards exist', async () => { + // savedObjectsClient.find() needs to find no dashboard + mockServices.savedObjectsClient.find = () => { + const hits: any[] = []; + return Promise.resolve({ + total: 0, + hits, + }); + }; + const component = mount(wrapDashboardListingInContext(mockServices)); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); @@ -137,22 +131,12 @@ describe.skip('after fetch', () => { expect(component).toMatchSnapshot(); }); - test('renders call to action when no dashboards exist', async () => { - const component = shallow( - {}} - createItem={() => {}} - editItem={() => {}} - viewItem={() => {}} - dashboardItemCreatorClickHandler={() => {}} - dashboardItemCreators={() => []} - listingLimit={1} - initialPageSize={10} - hideWriteControls={false} - core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }} - /> - ); + test('hideWriteControls', async () => { + // dashboardConfig.getHideWriteControls() to true + mockServices.dashboardConfig.getHideWriteControls = () => { + return true; + }; + const component = mount(wrapDashboardListingInContext(mockServices)); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); @@ -162,22 +146,10 @@ describe.skip('after fetch', () => { expect(component).toMatchSnapshot(); }); - test('hideWriteControls', async () => { - const component = shallow( - {}} - createItem={() => {}} - editItem={() => {}} - viewItem={() => {}} - dashboardItemCreatorClickHandler={() => {}} - dashboardItemCreators={() => []} - listingLimit={1} - initialPageSize={10} - hideWriteControls={true} - core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }} - /> - ); + test('renders warning when listingLimit is exceeded', async () => { + mockServices.savedObjectsPublic.settings.getListingLimit = () => 1; + + const component = mount(wrapDashboardListingInContext(mockServices)); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve)); @@ -187,22 +159,11 @@ describe.skip('after fetch', () => { expect(component).toMatchSnapshot(); }); - test('renders warning when listingLimit is exceeded', async () => { - const component = shallow( - {}} - createItem={() => {}} - editItem={() => {}} - viewItem={() => {}} - dashboardItemCreatorClickHandler={() => {}} - dashboardItemCreators={() => []} - listingLimit={1} - initialPageSize={10} - hideWriteControls={false} - core={{ notifications: { toasts: {} }, uiSettings: { get: jest.fn(() => 10) } }} - /> - ); + test('render table listing with initial filters from URL', async () => { + mockURLsearch = + '?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&filter=dashboard'; + + const component = mount(wrapDashboardListingInContext(mockServices)); // Ensure all promises resolve await new Promise((resolve) => process.nextTick(resolve));