Skip to content

Commit

Permalink
Merge branch 'main' into xlsx
Browse files Browse the repository at this point in the history
Signed-off-by: Rupal Mahajan <[email protected]>
  • Loading branch information
rupal-bq authored Mar 4, 2024
2 parents 815ed4c + a9c0c95 commit b8f3448
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 69 deletions.
33 changes: 17 additions & 16 deletions .cypress/integration/04-download.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@ describe('Cypress', () => {
);

cy.wait(12500);
cy.get('#landingPageOnDemandDownload').click({ force: true });
cy.get('body').then($body => {
if ($body.find('#downloadInProgressLoadingModal').length > 0) {
return;
}
else {
assert(false);
}
})
cy.get('[id="landingPageOnDemandDownload"]')
.contains('CSV')
.click({ force: true });
cy.get('.euiToastHeader__title')
.contains('Successfully downloaded report')
.should('exist');
});

it('Download pdf from in-context menu', () => {
Expand All @@ -33,7 +30,7 @@ describe('Cypress', () => {
// click Reporting in-context menu
cy.get('#downloadReport > span:nth-child(1) > span:nth-child(1)').click({ force: true });

// download PDF
// download PDF
cy.get('#generatePDF > span:nth-child(1) > span:nth-child(2)').click({ force: true });

cy.get('#reportGenerationProgressModal');
Expand All @@ -59,7 +56,7 @@ describe('Cypress', () => {
cy.wait(5000);

// open saved search list
cy.get('button.euiButtonEmpty:nth-child(3) > span:nth-child(1) > span:nth-child(1)').click({ force: true });
cy.get('[data-test-subj="discoverOpenButton"]').click({ force: true });
cy.wait(5000);

// click first entry
Expand All @@ -72,7 +69,7 @@ describe('Cypress', () => {
});

it('Download from Report definition details page', () => {
// create an on-demand report definition
// create an on-demand report definition

cy.visit(`${Cypress.env('opensearchDashboards')}/app/reports-dashboards#/`);
cy.location('pathname', { timeout: 60000 }).should(
Expand All @@ -81,14 +78,18 @@ describe('Cypress', () => {
);
cy.wait(10000);

cy.get('tr.euiTableRow-isSelectable:nth-child(1) > td:nth-child(1) > div:nth-child(2) > button:nth-child(1)').first().click();
cy.get('tr.euiTableRow-isSelectable:nth-child(1) > td:nth-child(1) > div:nth-child(2) > button:nth-child(1)').first().click();

cy.url().should('include', 'report_definition_details');

cy.get('#generateReportFromDetailsButton').should('exist');
cy.wait(5000);

cy.get('#generateReportFromDetailsFileFormat').should('exist');

cy.get('#generateReportFromDetailsButton').click({ force: true });
cy.get('#generateReportFromDetailsFileFormat').click({ force: true });

cy.get('#downloadInProgressLoadingModal');
cy.get('.euiToastHeader__title')
.contains('Successfully generated report')
.should('exist');
});
});
4 changes: 2 additions & 2 deletions .github/workflows/cypress-e2e-reporting-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:

- name: Boodstrap Opensearch Dashboards
run: |
yarn osd bootstrap
yarn osd bootstrap --single-version=loose
working-directory: OpenSearch-Dashboards

- name: Run Opensearch Dashboards with Dashboards Reporting Plugin Installed
Expand Down Expand Up @@ -150,7 +150,7 @@ jobs:

- name: Run Cypress tests
run: |
yarn cypress:run --browser chrome --headless --spec '.cypress/integration/*'
yarn cypress:run --browser chrome --headless
working-directory: OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}

- name: Capture failure screenshots
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
cd ./OpenSearch-Dashboards/
su `id -un 1000` -c "source $NVM_DIR/nvm.sh && nvm use && node -v && yarn -v &&
cd ./plugins/${{ env.PLUGIN_NAME }} &&
whoami && yarn osd bootstrap && yarn test --coverage"
whoami && yarn osd bootstrap --single-version=loose && yarn test --coverage"
- name: Upload coverage
uses: codecov/codecov-action@v1
Expand Down Expand Up @@ -113,7 +113,7 @@ jobs:
with:
timeout_minutes: 30
max_attempts: 3
command: yarn osd bootstrap
command: yarn osd bootstrap --single-version=loose

- name: Test
uses: nick-fields/retry@v1
Expand Down Expand Up @@ -171,7 +171,7 @@ jobs:
with:
timeout_minutes: 30
max_attempts: 3
command: yarn osd bootstrap
command: yarn osd bootstrap --single-version=loose

- name: Test
uses: nick-fields/retry@v1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ftr-e2e-reporting-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:

- name: Boodstrap Opensearch Dashboards
run: |
yarn osd bootstrap
yarn osd bootstrap --single-version=loose
working-directory: OpenSearch-Dashboards

- name: Run Opensearch Dashboards with Dashboards Reporting Plugin Installed
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Bootstrap the plugin
working-directory: OpenSearch-Dashboards/plugins/${{ env.PLUGIN_NAME }}
run: yarn osd bootstrap
run: yarn osd bootstrap --single-version=loose

- name: Get list of changed files using GitHub Action
uses: lots0logs/[email protected]
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/verify-binary-installation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: 'Install Dashboards with Plugin via Binary'

on: [push, pull_request]
env:
OPENSEARCH_VERSION: '3.0.0'
CI: 1
# avoid warnings like "tput: No value for $TERM and no -T specified"
TERM: xterm

jobs:
verify-binary-installation:
name: Run binary installation
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
# TODO: add windows support when OSD core is stable on windows
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Branch
uses: actions/checkout@v3

- name: Set env
run: |
opensearch_version=$(node -p "require('./opensearch_dashboards.json').opensearchDashboardsVersion")
plugin_version=$(node -p "require('./opensearch_dashboards.json').version")
echo "OPENSEARCH_VERSION=$opensearch_version" >> $GITHUB_ENV
echo "PLUGIN_VERSION=$plugin_version" >> $GITHUB_ENV
shell: bash

- name: Run Opensearch
uses: derek-ho/start-opensearch@v2
with:
opensearch-version: ${{ env.OPENSEARCH_VERSION }}
security-enabled: false

- name: Run Dashboard
id: setup-dashboards
uses: derek-ho/setup-opensearch-dashboards@v2
with:
plugin_name: dashboards-reporting
built_plugin_name: reportsDashboards
built_plugin_suffix: ${{ env.OPENSEARCH_VERSION }}
install_zip: true

- name: Start the binary
run: |
nohup ./bin/opensearch-dashboards &
working-directory: ${{ steps.setup-dashboards.outputs.dashboards-binary-directory }}
shell: bash

- name: Health check
run: |
timeout 300 bash -c 'while [[ "$(curl http://localhost:5601/api/status | jq -r '.status.overall.state')" != "green" ]]; do sleep 5; done'
shell: bash
2 changes: 1 addition & 1 deletion DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ another JDK installation, e.g. `RUNTIME_JAVA_HOME=/usr/lib/jvm/jdk-8`.
cd plugins
git clone https://github.com/opensearch-project/dashboards-reporting.git
```
1. Run `yarn osd bootstrap` inside `OpenSearch-Dashboards/plugins/dashboards-reporting`.
1. Run `yarn osd bootstrap --single-version=loose` inside `OpenSearch-Dashboards/plugins/dashboards-reporting`.

Ultimately, your directory structure should look like this:

Expand Down
2 changes: 1 addition & 1 deletion public/components/context_menu/context_menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ const checkURLParams = async () => {

const isDiscoverNavMenu = (navMenu) => {
return (
navMenu[0].children.length === 5 &&
(navMenu[0].children.length === 5 || navMenu[0].children.length === 6) &&
($('[data-test-subj="breadcrumb first"]').prop('title') === 'Discover' ||
$('[data-test-subj="breadcrumb first last"]').prop('title') ===
'Discover')
Expand Down
8 changes: 4 additions & 4 deletions server/routes/utils/dataReportHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ export const getOpenSearchData = (
.tz(timezone)
.format(dateFormat);
} else if (
fieldDateValue.length !== 0 &&
fieldDateValue instanceof Array
dateValue.length !== 0 &&
dateValue instanceof Array
) {
fieldDateValue.forEach((element, index) => {
data._source[keys][index] = moment
Expand All @@ -168,8 +168,8 @@ export const getOpenSearchData = (
moment.utc(fieldDateValue).tz(timezone).format(dateFormat)
);
} else if (
fieldDateValue.length !== 0 &&
fieldDateValue instanceof Array
dateValue.length !== 0 &&
dateValue instanceof Array
) {
let tempArray: string[] = [];
fieldDateValue.forEach((index) => {
Expand Down
40 changes: 26 additions & 14 deletions server/utils/__tests__/validationHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@

import { ReportDefinitionSchemaType, ReportSchemaType } from '../../model';
import {
DELIVERY_TYPE,
FORMAT,
REPORT_TYPE,
TRIGGER_TYPE,
} from '../../routes/utils/constants';
import { isValidRelativeUrl, validateReport, validateReportDefinition } from '../validationHelper';
import {
isValidRelativeUrl,
regexDuration,
validateReport,
validateReportDefinition,
} from '../validationHelper';

const SAMPLE_SAVED_OBJECT_ID = '3ba638e0-b894-11e8-a6d9-e546fe2bba5f';
const createReportDefinitionInput: ReportDefinitionSchemaType = {
Expand All @@ -31,7 +35,7 @@ const createReportDefinitionInput: ReportDefinitionSchemaType = {
configIds: [],
title: 'title',
textDescription: 'text description',
htmlDescription: 'html description'
htmlDescription: 'html description',
},
trigger: {
trigger_type: TRIGGER_TYPE.onDemand,
Expand Down Expand Up @@ -63,12 +67,12 @@ const createReportDefinitionNotebookLegacyInput: ReportDefinitionSchemaType = {
configIds: [],
title: 'title',
textDescription: 'text description',
htmlDescription: 'html description'
htmlDescription: 'html description',
},
trigger: {
trigger_type: TRIGGER_TYPE.onDemand,
},
}
};

const createReportDefinitionNotebookInput: ReportDefinitionSchemaType = {
report_params: {
Expand All @@ -88,12 +92,12 @@ const createReportDefinitionNotebookInput: ReportDefinitionSchemaType = {
configIds: [],
title: 'title',
textDescription: 'text description',
htmlDescription: 'html description'
htmlDescription: 'html description',
},
trigger: {
trigger_type: TRIGGER_TYPE.onDemand,
},
}
};

const createReportDefinitionNotebookPostNavBarInput: ReportDefinitionSchemaType = {
report_params: {
Expand All @@ -113,12 +117,12 @@ const createReportDefinitionNotebookPostNavBarInput: ReportDefinitionSchemaType
configIds: [],
title: 'title',
textDescription: 'text description',
htmlDescription: 'html description'
htmlDescription: 'html description',
},
trigger: {
trigger_type: TRIGGER_TYPE.onDemand,
},
}
};

describe('test input validation', () => {
test('create report with correct saved object id', async () => {
Expand Down Expand Up @@ -189,7 +193,7 @@ describe('test input validation', () => {
});

test('validation against query_url', async () => {
const urls: [string, boolean][] = [
const urls: Array<[string, boolean]> = [
['/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=', true],
[
'/_plugin/kibana/app/dashboards#/view/7adfa750-4c81-11e8-b3d7-01146121b73d?_g=',
Expand Down Expand Up @@ -223,15 +227,23 @@ describe('test input validation', () => {
'/app/data-explorer/discover?security_tenant=private#/view/571aaf70-4c88-11e8-b3d7-01146121b73d',
true,
],
[
'/app/discoverLegacy#/view/571aaf70-4c88-11e8-b3d7-01146121b73d',
true,
],
['/app/discoverLegacy#/view/571aaf70-4c88-11e8-b3d7-01146121b73d', true],
];
expect(urls.map((url) => isValidRelativeUrl(url[0]))).toEqual(
urls.map((url) => url[1])
);
});

test('validate ISO 8601 durations', () => {
const durations: Array<[string, boolean]> = [
['PT30M', true],
['PT-30M', true],
['PT-2H-30M', true],
];
expect(
durations.map((duration) => regexDuration.test(duration[0]))
).toEqual(durations.map((duration) => duration[1]));
});
});

// TODO: merge this with other mock clients used in testing, to create some mock helpers file
Expand Down
13 changes: 6 additions & 7 deletions server/utils/validationHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { RequestParams } from '@elastic/elasticsearch';
import { RequestParams } from '@opensearch-project/opensearch';
import path from 'path';
import { ILegacyScopedClusterClient } from '../../../../src/core/server';
import {
Expand All @@ -15,7 +15,7 @@ import {
import { REPORT_TYPE } from '../../server/routes/utils/constants';

export const isValidRelativeUrl = (relativeUrl: string) => {
let normalizedRelativeUrl = relativeUrl
let normalizedRelativeUrl = relativeUrl;
if (
!relativeUrl.includes('observability#/notebooks') &&
!relativeUrl.includes('notebooks-dashboards')
Expand All @@ -34,15 +34,15 @@ export const isValidRelativeUrl = (relativeUrl: string) => {
* moment.js isValid() API fails to validate time duration, so use regex
* https://github.com/moment/moment/issues/1805
**/
export const regexDuration = /^(-?)P(?=\d|T\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)([DW]))?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/;
export const regexDuration = /^([-+]?)P(?=\d|T[-+]?\d)(?:([-+]?\d+)Y)?(?:([-+]?\d+)M)?(?:([-+]?\d+)([DW]))?(?:T(?:([-+]?\d+)H)?(?:([-+]?\d+)M)?(?:([-+]?\d+(?:\.\d+)?)S)?)?$/;
export const regexEmailAddress = /\S+@\S+\.\S+/;
export const regexReportName = /^[\w\-\s\(\)\[\]\,\_\-+]+$/;
export const regexRelativeUrl = /^\/(_plugin\/kibana\/|_dashboards\/)?app\/(dashboards|visualize|discover|discoverLegacy|data-explorer\/discover\/?|observability-dashboards|observability-notebooks|notebooks-dashboards\?view=output_only(&security_tenant=.+)?)(\?security_tenant=.+)?#\/(notebooks\/|view\/|edit\/)?[^\/]+$/;

export const validateReport = async (
client: ILegacyScopedClusterClient,
report: ReportSchemaType,
basePath: String
basePath: string
) => {
report.query_url = report.query_url.replace(basePath, '');
report.report_definition.report_params.core_params.base_url = report.report_definition.report_params.core_params.base_url.replace(
Expand All @@ -66,7 +66,7 @@ export const validateReport = async (
export const validateReportDefinition = async (
client: ILegacyScopedClusterClient,
reportDefinition: ReportDefinitionSchemaType,
basePath: String
basePath: string
) => {
reportDefinition.report_params.core_params.base_url = reportDefinition.report_params.core_params.base_url.replace(
basePath,
Expand Down Expand Up @@ -115,8 +115,7 @@ const validateSavedObject = async (
if (getType(source) === 'notebook') {
// no backend check for notebooks because we would just be checking against the notebooks api again
exist = true;
}
else {
} else {
savedObjectId = `${getType(source)}:${getId(url)}`;
const params: RequestParams.Exists = {
index: '.kibana',
Expand Down
Loading

0 comments on commit b8f3448

Please sign in to comment.