diff --git a/cypress/integration/4_findings.spec.js b/cypress/integration/4_findings.spec.js index afcc744e3..434712148 100644 --- a/cypress/integration/4_findings.spec.js +++ b/cypress/integration/4_findings.spec.js @@ -142,9 +142,6 @@ describe('Findings', () => { }); }); - // TODO - upon reaching rules page, trigger appropriate rules detail flyout - // see github issue #124 at https://github.com/opensearch-project/security-analytics-dashboards-plugin/issues/124 - it('opens rule details flyout when rule name inside accordion drop down is clicked', () => { // filter table to show only sample_detector findings cy.get(`input[placeholder="Search findings"]`).ospSearch('sample_detector'); @@ -205,5 +202,26 @@ describe('Findings', () => { }); }); + it('shows document not found warning when the document is empty', () => { + cy.deleteIndex(indexName); + cy.reload(); + + // Wait for page to load + cy.waitForPageLoad('findings', { + contains: 'Findings', + }); + + // filter table to show only sample_detector findings + cy.get(`input[placeholder="Search findings"]`).ospSearch(indexName); + + // open Finding details flyout via finding id link. cy.wait essential, timeout insufficient. + cy.getTableFirstRow('[data-test-subj="view-details-icon"]').then(($el) => { + cy.get($el).click({ force: true }); + }); + + // Flyout should show 'Document not found' warning + cy.contains('Document not found'); + }); + after(() => cy.cleanUpTests()); }); diff --git a/public/pages/Findings/components/FindingDetailsFlyout.tsx b/public/pages/Findings/components/FindingDetailsFlyout.tsx index 948899f60..a812910b1 100644 --- a/public/pages/Findings/components/FindingDetailsFlyout.tsx +++ b/public/pages/Findings/components/FindingDetailsFlyout.tsx @@ -32,6 +32,7 @@ import { EuiTab, EuiInMemoryTable, EuiBasicTableColumn, + EuiEmptyPrompt, } from '@elastic/eui'; import { capitalizeFirstLetter, renderTime } from '../../../utils/helpers'; import { DEFAULT_EMPTY_DATA, ROUTES } from '../../../utils/constants'; @@ -254,9 +255,16 @@ export default class FindingDetailsFlyout extends Component< const docId = related_doc_ids[0]; const matchedDocuments = documents.filter((doc) => doc.id === docId); const document = matchedDocuments.length > 0 ? matchedDocuments[0].document : ''; + let formattedDocument = ''; + try { + formattedDocument = document ? JSON.stringify(JSON.parse(document), null, 2) : ''; + } catch { + // no-op + } + const { indexPatternId } = this.state; - return ( + return document ? ( <> @@ -314,10 +322,23 @@ export default class FindingDetailsFlyout extends Component< isCopyable data-test-subj={'finding-details-flyout-rule-document'} > - {JSON.stringify(JSON.parse(document), null, 2)} + {formattedDocument} + ) : ( + <> + +

Documents

+
+ + Document not found} + body={

The document that generated this finding could not be loaded.

} + /> + ); }