diff --git a/src/views/sources/__tests__/__snapshots__/addSourcesScanModal.test.tsx.snap b/src/views/sources/__tests__/__snapshots__/addSourcesScanModal.test.tsx.snap new file mode 100644 index 00000000..8a5e7efc --- /dev/null +++ b/src/views/sources/__tests__/__snapshots__/addSourcesScanModal.test.tsx.snap @@ -0,0 +1,62 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AddSourceModal should call onSubmit with the correct filtered data when "Save" is clicked: onSubmit, filtered data 1`] = ` +[ + [ + { + "name": "Test Scan", + "options": { + "enabled_extended_product_search": { + "jboss_brms": false, + "jboss_eap": false, + "jboss_fuse": false, + "jboss_ws": false, + "search_directories": undefined, + }, + "max_concurrency": "25", + }, + "sources": undefined, + }, + ], +] +`; + +exports[`AddSourceModal should have the correct title: title 1`] = ` + + Scan + +`; + +exports[`AddSourceModal should render a basic component: basic 1`] = ` + + + [Function] + + +`; diff --git a/src/views/sources/__tests__/addSourcesScanModal.test.tsx b/src/views/sources/__tests__/addSourcesScanModal.test.tsx new file mode 100644 index 00000000..99da2a23 --- /dev/null +++ b/src/views/sources/__tests__/addSourcesScanModal.test.tsx @@ -0,0 +1,47 @@ +import React, { act } from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { shallowComponent } from '../../../../config/jest.setupTests'; +import { AddSourcesScanModal } from '../addSourcesScanModal'; + +describe('AddSourceModal', () => { + let mockOnClose; + let mockOnSubmit; + + beforeEach(async () => { + await act(async () => { + mockOnClose = jest.fn(); + mockOnSubmit = jest.fn(); + await render(); + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should render a basic component', async () => { + const component = await shallowComponent(); + expect(component).toMatchSnapshot('basic'); + }); + + it('should have the correct title', () => { + const title = screen.getByText(/Scan/); + expect(title).toMatchSnapshot('title'); + }); + + it('should call onSubmit with the correct filtered data when "Save" is clicked', async () => { + const user = userEvent.setup(); + await user.type(screen.getByPlaceholderText(new RegExp('Enter a name for the scan', 'i')), 'Test Scan'); + await user.click(screen.getByText('Save')); + + expect(mockOnSubmit.mock.calls).toMatchSnapshot('onSubmit, filtered data'); + }); + + it('should call onClose', async () => { + const user = userEvent.setup(); + await user.click(screen.getByText('Cancel')); + + expect(mockOnClose).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/views/sources/addSourcesScanModal.tsx b/src/views/sources/addSourcesScanModal.tsx index 5c52f589..82aef0c2 100644 --- a/src/views/sources/addSourcesScanModal.tsx +++ b/src/views/sources/addSourcesScanModal.tsx @@ -4,7 +4,7 @@ * * @module sourcesScanModal */ -import * as React from 'react'; +import React, { useState } from 'react'; import { ActionGroup, Button, @@ -21,14 +21,20 @@ import { } from '@patternfly/react-core'; import { type SourceType } from '../../types/types'; -export interface SourcesScanModalProps { - sources: SourceType[]; - onClose: () => void; - onSubmit: (payload) => void; +interface AddSourcesScanModalProps { + isOpen: boolean; + sources?: SourceType[]; + onClose?: () => void; + onSubmit?: (payload) => void; } -const SourcesScanModal: React.FC = ({ sources, onClose, onSubmit }) => { - const [deepScans, setDeepScans] = React.useState([]); +const AddSourcesScanModal: React.FC = ({ + isOpen, + sources, + onClose = Function.prototype, + onSubmit = Function.prototype +}) => { + const [deepScans, setDeepScans] = useState([]); const onDeepScanChange = (option, checked) => { if (checked) { @@ -37,10 +43,11 @@ const SourcesScanModal: React.FC = ({ sources, onClose, o setDeepScans(deepScans.filter(o => o !== option)); } }; + const onScan = values => { const payload = { name: values['scan-name'], - sources: sources.map(s => s.id), + sources: sources?.map(s => s.id), options: { max_concurrency: values['scan-max-concurrent'], enabled_extended_product_search: { @@ -56,10 +63,10 @@ const SourcesScanModal: React.FC = ({ sources, onClose, o }; return ( - + onClose()}> s.name).join(', '), + 'scan-sources': sources?.map(s => s.name).join(', ') || '', 'scan-max-concurrent': '25' }} > @@ -139,7 +146,7 @@ const SourcesScanModal: React.FC = ({ sources, onClose, o - @@ -150,4 +157,4 @@ const SourcesScanModal: React.FC = ({ sources, onClose, o ); }; -export default SourcesScanModal; +export { AddSourcesScanModal as default, AddSourcesScanModal, type AddSourcesScanModalProps }; diff --git a/src/views/sources/viewSourcesList.tsx b/src/views/sources/viewSourcesList.tsx index f0f3b172..671e2909 100644 --- a/src/views/sources/viewSourcesList.tsx +++ b/src/views/sources/viewSourcesList.tsx @@ -49,7 +49,7 @@ import { useDeleteSourceApi, useEditSourceApi, useAddSourceApi } from '../../hoo import useQueryClientConfig from '../../queryClientConfig'; import { type Connections, type CredentialType, type Scan, type SourceType } from '../../types/types'; import AddSourceModal from './addSourceModal'; -import SourcesScanModal from './addSourcesScanModal'; +import { AddSourcesScanModal } from './addSourcesScanModal'; import { ShowConnectionsModal } from './showSourceConnectionsModal'; import { SOURCES_LIST_QUERY, useSourcesQuery } from './useSourcesQuery'; @@ -473,7 +473,8 @@ const SourcesListView: React.FunctionComponent = () => { }) } /> - setScanSelected(undefined)} onSubmit={(payload: Scan) => runScans(payload).finally(() => { @@ -481,7 +482,7 @@ const SourcesListView: React.FunctionComponent = () => { setScanSelected(undefined); }) } - sources={scanSelected ?? []} + sources={scanSelected} /> {alerts.map(({ id, variant, title }) => (