Skip to content

Commit

Permalink
Expanded functionality tests for New Workflow and Workflow List compo…
Browse files Browse the repository at this point in the history
…nents.

Signed-off-by: saimedhi <[email protected]>
  • Loading branch information
saimedhi committed Sep 18, 2024
1 parent 68a152d commit 6bee312
Show file tree
Hide file tree
Showing 10 changed files with 279 additions and 26 deletions.
2 changes: 1 addition & 1 deletion public/pages/workflow_detail/workflow_detail.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const renderWithRouter = (

return {
...render(
<Provider store={mockStore(workflowId, workflowName, workflowType)}>
<Provider store={mockStore([workflowId, workflowName, workflowType])}>
<Router history={history}>
<Switch>
<Route
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ export function ImportWorkflowModal(props: ImportWorkflowModalProps) {
</EuiFlexGroup>
</EuiModalBody>
<EuiModalFooter>
<EuiSmallButtonEmpty onClick={() => onModalClose()}>
<EuiSmallButtonEmpty
onClick={() => onModalClose()}
data-testid="cancelImportButton"
>
Cancel
</EuiSmallButtonEmpty>
<EuiSmallButton
Expand Down
65 changes: 60 additions & 5 deletions public/pages/workflows/new_workflow/new_workflow.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
*/

import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom';
import { Provider } from 'react-redux';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { store } from '../../../store';
import { NewWorkflow } from './new_workflow';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import configureStore from 'redux-mock-store';
import * as ReactReduxHooks from '../../../store/store';
import '@testing-library/jest-dom';
import { loadPresetTemplates } from '../../../../test/utils';
import { INITIAL_ML_STATE } from '../../../../public/store';

jest.mock('../../../services', () => {
const { mockCoreServices } = require('../../../../test');
Expand All @@ -19,6 +23,18 @@ jest.mock('../../../services', () => {
};
});

const mockStore = configureStore([]);
const initialState = {
ml: INITIAL_ML_STATE,
presets: {
loading: false,
presetWorkflows: loadPresetTemplates(),
},
};
const store = mockStore(initialState);

const mockDispatch = jest.fn();

const renderWithRouter = () =>
render(
<Provider store={store}>
Expand All @@ -31,8 +47,47 @@ const renderWithRouter = () =>
);

describe('NewWorkflow', () => {
test('renders the search bar', () => {
const { getByPlaceholderText } = renderWithRouter();
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(ReactReduxHooks, 'useAppDispatch').mockReturnValue(mockDispatch);
});

test('renders the preset workflow templates', () => {
const { getByPlaceholderText, getAllByText } = renderWithRouter();
expect(getByPlaceholderText('Search')).toBeInTheDocument();
expect(getAllByText('Custom')).toHaveLength(1);
expect(getAllByText('Hybrid Search')).toHaveLength(1);
expect(getAllByText('Multimodal Search')).toHaveLength(1);
expect(getAllByText('Semantic Search')).toHaveLength(1);
});

test('renders the quick configure for preset workflow templates', async () => {
const {
getAllByTestId,
getAllByText,
getByTestId,
queryByText,
} = renderWithRouter();

// Click the first "Go" button on the templates and test Quick Configure.
const goButtons = getAllByTestId('goButton');
userEvent.click(goButtons[0]);
await waitFor(() =>
expect(getAllByText('Quick configure')).toHaveLength(1)
);

// Verify that the create button is present in the Quick Configure pop-up.
expect(getByTestId('quickConfigureCreateButton')).toBeInTheDocument();

// Click the "Cancel" button in the Quick Configure pop-up.
const quickConfigureCancelButton = getByTestId(
'quickConfigureCancelButton'
);
userEvent.click(quickConfigureCancelButton);

// Ensure the quick configure pop-up is closed after canceling.
await waitFor(() =>
expect(queryByText('quickConfigureCreateButton')).toBeNull()
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ export function QuickConfigureModal(props: QuickConfigureModalProps) {
/>
</EuiModalBody>
<EuiModalFooter>
<EuiSmallButtonEmpty onClick={() => props.onClose()}>
<EuiSmallButtonEmpty
onClick={() => props.onClose()}
data-testid="quickConfigureCancelButton"
>
Cancel
</EuiSmallButtonEmpty>
<EuiSmallButton
Expand Down Expand Up @@ -166,6 +169,7 @@ export function QuickConfigureModal(props: QuickConfigureModalProps) {
console.error(err);
});
}}
data-testid="quickConfigureCreateButton"
fill={true}
color="primary"
>
Expand Down
1 change: 1 addition & 0 deletions public/pages/workflows/new_workflow/use_case.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function UseCase(props: UseCaseProps) {
onClick={() => {
setIsNameModalOpen(true);
}}
data-testid="goButton"
>
Go
</EuiSmallButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ export function DeleteWorkflowModal(props: DeleteWorkflowModalProps) {
</EuiFlexGroup>
</EuiModalBody>
<EuiModalFooter>
<EuiSmallButtonEmpty onClick={() => props.clearDeleteState()}>
<EuiSmallButtonEmpty
onClick={() => props.clearDeleteState()}
data-testid="cancelDeleteWorkflowButton"
>
{' '}
Cancel
</EuiSmallButtonEmpty>
Expand Down Expand Up @@ -135,6 +138,7 @@ export function DeleteWorkflowModal(props: DeleteWorkflowModalProps) {
setIsDeleting(false);
props.clearDeleteState();
}}
data-testid="deleteWorkflowButton"
fill={true}
color="danger"
>
Expand Down
140 changes: 138 additions & 2 deletions public/pages/workflows/workflow_list/workflow_list.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
*/

import React from 'react';
import { render } from '@testing-library/react';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
import { Provider } from 'react-redux';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { store } from '../../../store';
import { WorkflowList } from './workflow_list';
import { mockStore } from '../../../../test/utils';
import { WORKFLOW_TYPE } from '../../../../common';
import configureStore from 'redux-mock-store';

jest.mock('../../../services', () => {
const { mockCoreServices } = require('../../../../test');
Expand All @@ -18,6 +22,33 @@ jest.mock('../../../services', () => {
};
});

const workflows = new Array(20).fill(null).map((_, index) => ({
id: `workflow_id_${index}`,
name: `workflow_name_${index}`,
type: Object.values(WORKFLOW_TYPE)[
Math.floor(Math.random() * Object.values(WORKFLOW_TYPE).length)
],
}));
const workflowSet: [
string,
string,
WORKFLOW_TYPE
][] = workflows.map(({ id, name, type }): [string, string, WORKFLOW_TYPE] => [
id,
name,
type,
]);

const mockStore1 = configureStore([]);
const initialState = {
workflows: {
loading: false,
errorMessage: '',
workflows: mockStore(...workflowSet).getState().workflows.workflows,
},
};
const store = mockStore1(initialState);

const renderWithRouter = () =>
render(
<Provider store={store}>
Expand All @@ -33,5 +64,110 @@ describe('WorkflowList', () => {
test('renders the page', () => {
const { getAllByText } = renderWithRouter();
expect(getAllByText('Manage existing workflows').length).toBeGreaterThan(0);
expect(getAllByText('Name').length).toBeGreaterThan(0);
expect(getAllByText('Type').length).toBeGreaterThan(0);
expect(getAllByText('Last saved').length).toBeGreaterThan(0);
expect(getAllByText('Actions').length).toBeGreaterThan(0);
expect(getAllByText('workflow_name_0').length).toBeGreaterThan(0);
});

test('sorting functionality', async () => {
const { container, getAllByText, queryByText } = renderWithRouter();
expect(getAllByText('workflow_name_0').length).toBeGreaterThan(0);

const sortButtons = container.querySelectorAll(
'[data-test-subj="tableHeaderSortButton"]'
);

// Sort workflows list by Name
expect(sortButtons[0]).toBeInTheDocument();
userEvent.click(sortButtons[0]!);
await new Promise((resolve) => setTimeout(resolve, 200));
expect(queryByText('workflow_name_19')).toBeInTheDocument();
expect(queryByText('workflow_name_0')).toBeNull();
userEvent.click(sortButtons[0]!);
await new Promise((resolve) => setTimeout(resolve, 200));
expect(queryByText('workflow_name_0')).toBeInTheDocument();
expect(queryByText('workflow_name_9')).toBeInTheDocument();
expect(queryByText('workflow_name_10')).toBeNull();
expect(queryByText('workflow_name_19')).toBeNull();

// Sort workflows list by Type
expect(sortButtons[1]).toBeInTheDocument();
userEvent.click(sortButtons[1]!);

await waitFor(() => {
expect(getAllByText('Custom').length).toBeGreaterThan(0); // Ensures at least one 'Custom' element is present
expect(queryByText('Unknown')).toBeNull();
});
userEvent.click(sortButtons[1]!);
await waitFor(() => {
expect(queryByText('Unknown')).toBeNull();
expect(getAllByText('Custom').length).toBeGreaterThan(0);
});
});

test('pagination functionality', async () => {
const { container, getByText, queryByText } = renderWithRouter();

// Rows per page 10
const rowsPerPageButton = container.querySelector(
'[data-test-subj="tablePaginationPopoverButton"]'
) as HTMLButtonElement;
expect(rowsPerPageButton).toHaveTextContent('Rows per page: 10');

// Default view 10 items per page
expect(getByText('workflow_name_0')).toBeInTheDocument();
//expect(queryByText('workflow_name_11')).toBeNull();
expect(queryByText('workflow_name_19')).toBeNull();

//Navigate to next page
const nextButton = container.querySelector(
'[data-test-subj="pagination-button-next"]'
) as HTMLButtonElement;
//console.log('nextButton printed', nextButton);

userEvent.click(nextButton);

// Check if item from the next page is visible
await waitFor(() => {
expect(getByText('workflow_name_19')).toBeInTheDocument();
expect(queryByText('workflow_name_0')).toBeNull();
});

// Navigate to previous page
const previousButton = container.querySelector(
'[data-test-subj="pagination-button-previous"]'
) as HTMLButtonElement;

userEvent.click(previousButton);

// Check if item from the previous page is visible
await waitFor(() => {
expect(getByText('workflow_name_0')).toBeInTheDocument();
expect(queryByText('workflow_name_19')).toBeNull();
});
});
test('delete action functionality', async () => {
const { getByText, getByTestId, getAllByLabelText } = renderWithRouter();
const deleteButtons = getAllByLabelText('Delete');
userEvent.click(deleteButtons[0]);
await waitFor(() => {
expect(getByText('Delete associated resources')).toBeInTheDocument();
});
expect(getByTestId('deleteWorkflowButton')).toBeInTheDocument();
const cancelDeleteWorkflowButton = getByTestId(
'cancelDeleteWorkflowButton'
);
expect(cancelDeleteWorkflowButton).toBeInTheDocument();
userEvent.click(cancelDeleteWorkflowButton);
});
test('view resources functionality', async () => {
const { getByText, getAllByLabelText } = renderWithRouter();
const viewResourcesButtons = getAllByLabelText('View resources');
userEvent.click(viewResourcesButtons[0]);
await waitFor(() => {
expect(getByText('No existing resources found')).toBeInTheDocument();
});
});
});
32 changes: 29 additions & 3 deletions public/pages/workflows/workflows.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*/

import React from 'react';
import { render } from '@testing-library/react';
import { render, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import { Provider } from 'react-redux';

import {
Expand Down Expand Up @@ -41,8 +43,32 @@ const renderWithRouter = () => ({
});

describe('Workflows', () => {
test('renders the page', () => {
const { getAllByText } = renderWithRouter();
test('renders the page', async () => {
const { getAllByText, getByTestId, queryByText } = renderWithRouter();

// The "Manage Workflows" tab is displayed by default

// Import Workflow Testing
expect(getAllByText('Workflows').length).toBeGreaterThan(0);
const importWorkflowButton = getByTestId('importWorkflowButton');
await waitFor(() => userEvent.click(importWorkflowButton));
expect(
getAllByText('Select or drag and drop a file').length
).toBeGreaterThan(0);

// Closing or canceling the import
const cancelImportButton = getByTestId('cancelImportButton');
await waitFor(() => userEvent.click(cancelImportButton));
expect(
queryByText('Select or drag and drop a file')
).not.toBeInTheDocument();
expect(getAllByText('Manage existing workflows').length).toBeGreaterThan(0);

// When the "Create Workflow" button is clicked, the "New workflow" tab opens
// Create Workflow Testing
const createWorkflowButton = getByTestId('createWorkflowButton');
expect(createWorkflowButton).toBeInTheDocument();
await waitFor(() => userEvent.click(createWorkflowButton));
expect(getAllByText('Create from a template').length).toBeGreaterThan(0);
});
});
3 changes: 3 additions & 0 deletions public/pages/workflows/workflows.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ export function Workflows(props: WorkflowsProps) {
onClick={() => {
setSelectedTabId(WORKFLOWS_TAB.CREATE);
}}
data-testid="createWorkflowButton"
>
Create workflow
</EuiSmallButton>,
Expand All @@ -292,6 +293,7 @@ export function Workflows(props: WorkflowsProps) {
onClick={() => {
setIsImportModalOpen(true);
}}
data-testid="importWorkflowButton"
>
Import workflow
</EuiSmallButton>,
Expand All @@ -302,6 +304,7 @@ export function Workflows(props: WorkflowsProps) {
onClick={() => {
setIsImportModalOpen(true);
}}
data-testid="importWorkflowButton"
>
Import workflow
</EuiSmallButton>,
Expand Down
Loading

0 comments on commit 6bee312

Please sign in to comment.