Skip to content

Commit

Permalink
* test: add unit tests and modify jest-addon.config for searchlib ali…
Browse files Browse the repository at this point in the history
…as - refs #254313
  • Loading branch information
ana-oprea committed Oct 18, 2023
1 parent e311843 commit 620031b
Show file tree
Hide file tree
Showing 12 changed files with 1,561 additions and 1 deletion.
3 changes: 2 additions & 1 deletion jest-addon.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ module.exports = {
'@package/(.*)$': '<rootDir>/src/$1',
'@root/(.*)$': '<rootDir>/src/$1',
'@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
'@eeacms/search': '<rootDir>/src/addons/volto-searchlib/src',
'@eeacms/search/(.*)$': '<rootDir>/src/addons/volto-searchlib/searchlib/$1',
'@eeacms/search': '<rootDir>/src/addons/volto-searchlib/searchlib',
'@eeacms/(.*?)/(.*)$': '<rootDir>/node_modules/@eeacms/$1/src/$2',
'@plone/volto-slate':
'<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
Expand Down
99 changes: 99 additions & 0 deletions src/SearchBlock/BlockContainer/BlockContainer.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React from 'react';
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import BlockContainer from './BlockContainer';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-intl-redux';
import '@testing-library/jest-dom/extend-expect';

const mockStore = configureStore();
let store;

jest.mock('@plone/volto/components/manage/Blocks/Block/Edit', () => ({
__esModule: true,
default: () => <div>Block Edit</div>,
}));

jest.mock('@plone/volto/components/theme/View/RenderBlocks', () => ({
__esModule: true,
default: () => <div>Render Blocks</div>,
}));

jest.mock('./NewBlockAddButton', () => ({
__esModule: true,
default: () => <div>New Block Add Button</div>,
}));

describe('BlockContainer', () => {
const mockProps = {
mode: 'view',
block: 'someBlock',
data: { '@type': 'someType' },
selected: false,
onChangeSlotfill: jest.fn(),
onSelectSlotfill: jest.fn(),
properties: {},
metadata: {},
};

beforeEach(() => {
jest.clearAllMocks();
store = mockStore({
intl: {
locale: 'en',
formatMessage: () => 'Select layout',
},
});
});
afterEach(() => {
jest.clearAllMocks();
});
it('should render RenderBlocks when mode is "view" and data is present', () => {
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter>
<BlockContainer {...mockProps} />
</MemoryRouter>
</Provider>,
);
expect(queryByText('Render Blocks')).toBeInTheDocument();
expect(queryByText('Block Edit')).not.toBeInTheDocument();
expect(queryByText('New Block Add Button')).not.toBeInTheDocument();
});
it('should not render anything when mode is "view" and data is not present', () => {
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter>
<BlockContainer {...mockProps} data={null} />
</MemoryRouter>
</Provider>,
);
expect(queryByText('Render Blocks')).not.toBeInTheDocument();
expect(queryByText('Block Edit')).not.toBeInTheDocument();
expect(queryByText('New Block Add Button')).not.toBeInTheDocument();
});
it('should render BlockEdit when mode is not "view" and data is present', () => {
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter>
<BlockContainer {...mockProps} mode="edit" />
</MemoryRouter>
</Provider>,
);
expect(queryByText('Block Edit')).toBeInTheDocument();
expect(queryByText('Render Blocks')).not.toBeInTheDocument();
expect(queryByText('New Block Add Button')).not.toBeInTheDocument();
});
it('should render NewBlockAddButton when mode is not "view" and data is not present', () => {
const { queryByText } = render(
<Provider store={store}>
<MemoryRouter>
<BlockContainer {...mockProps} mode="edit" data={null} />
</MemoryRouter>
</Provider>,
);
expect(queryByText('New Block Add Button')).toBeInTheDocument();
expect(queryByText('Block Edit')).not.toBeInTheDocument();
expect(queryByText('Render Blocks')).not.toBeInTheDocument();
});
});
86 changes: 86 additions & 0 deletions src/SearchBlock/BlockContainer/NewBlockAddButton.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React from 'react';
import { render, fireEvent, screen, act } from '@testing-library/react';
import NewBlockAddButton from './NewBlockAddButton';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-intl-redux';
import '@testing-library/jest-dom/extend-expect';

const mockStore = configureStore();
let store;
let outsideClickCallback;

jest.mock('@eeacms/search/lib/hocs/useOutsideClick', () => {
return jest.fn((ref, callback) => {
outsideClickCallback = callback;
});
});

describe('NewBlockAddButton', () => {
beforeEach(() => {
jest.clearAllMocks();
store = mockStore({
intl: {
locale: 'en',
formatMessage: () => 'Select layout',
},
});
});
afterEach(() => {
jest.clearAllMocks();
});
const mockOnMutateBlock = jest.fn();
const allowedBlocks = ['text', 'image'];
const block = 'some-block-id';

it('should render add block button initially', () => {
const { container } = render(
<Provider store={store}>
<NewBlockAddButton
allowedBlocks={allowedBlocks}
block={block}
onMutateBlock={mockOnMutateBlock}
/>
</Provider>,
);
expect(screen.getByTitle('Add block')).toBeInTheDocument();
expect(container.querySelector('.blocks-chooser')).not.toBeInTheDocument();
});

it('should open BlockChooser on button click', () => {
const { container } = render(
<Provider store={store}>
<NewBlockAddButton
allowedBlocks={allowedBlocks}
block={block}
onMutateBlock={mockOnMutateBlock}
/>
</Provider>,
);
fireEvent.click(screen.getByTitle('Add block'));
expect(container.querySelector('.blocks-chooser')).toBeInTheDocument();
});

it('should close BlockChooser on outside click', () => {
const { container } = render(
<Provider store={store}>
<NewBlockAddButton
allowedBlocks={allowedBlocks}
block={block}
onMutateBlock={mockOnMutateBlock}
/>
</Provider>,
);

// Open the BlockChooser
fireEvent.click(screen.getByTitle('Add block'));
expect(container.querySelector('.blocks-chooser')).toBeInTheDocument();

// Simulate an outside click
act(() => {
outsideClickCallback();
});

// Check if the BlockChooser is closed
expect(container.querySelector('.blocks-chooser')).toBeNull();
});
});
105 changes: 105 additions & 0 deletions src/SearchBlock/BlockContainer/SlotEditor.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from 'react';
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import SlotEditor from './SlotEditor';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-intl-redux';
import '@testing-library/jest-dom/extend-expect';

const mockStore = configureStore();
let store;
const mockData = {
'slotA-any': { '@type': 'slotA-any' },
'slotA-isLandingPage': { '@type': 'slotA-isLandingPage' },
'slotA-hasResults': { '@type': 'slotA-hasResults' },
'slotA-hasNoResults': { '@type': 'slotA-hasNoResults' },
'slotB-any': { '@type': 'slotB-any' },
'slotB-isLandingPage': { '@type': 'slotB-isLandingPage' },
'slotB-hasResults': { '@type': 'slotB-hasResults' },
'slotB-hasNoResults': { '@type': 'slotB-hasNoResults' },
};

describe('SlotEditor', () => {
beforeEach(() => {
jest.clearAllMocks();
store = mockStore({
intl: {
locale: 'en',
formatMessage: () => 'Select layout',
},
});
});
afterEach(() => {
jest.clearAllMocks();
});
it('renders tabs for each search state', () => {
render(
<Provider store={store}>
<MemoryRouter>
<SlotEditor
slot="slotA"
data={mockData}
selectedSlotFill="slotA-any"
onChangeSlotfill={() => {}}
onDeleteSlotfill={() => {}}
onSelectSlotfill={() => {}}
metadata={{}}
mode="view"
/>
</MemoryRouter>
</Provider>,
);
});

// it('calls onChangeSlotfill when a tab is clicked', () => {
// const onChangeSlotfill = jest.fn();

// const { queryByText } = render(
// <Provider store={store}>
// <MemoryRouter>
// <SlotEditor
// slot="slotA"
// data={mockData}
// selectedSlotFill="slotA-state1"
// onChangeSlotfill={onChangeSlotfill}
// onDeleteSlotfill={() => {}}
// onSelectSlotfill={() => {}}
// metadata={{}}
// mode="view"
// />
// </MemoryRouter>
// </Provider>,
// );

// const state2Tab = queryByText(/slotA-any/);
// fireEvent.change(state2Tab, { target: { value: 'slotB-any' } });

// // Ensure onChangeSlotfill is called with the correct blockId
// expect(onChangeSlotfill).toHaveBeenCalledWith('slotA-state2');
// });

// it('calls onDeleteSlotfill when the delete button is clicked', () => {
// const onDeleteSlotfill = jest.fn();

// const { getByLabelText } = render(
// <MemoryRouter>
// <SlotEditor
// slot="slotA"
// data={mockData}
// selectedSlotFill="slotA-state1"
// onChangeSlotfill={() => {}}
// onDeleteSlotfill={onDeleteSlotfill}
// onSelectSlotfill={() => {}}
// metadata={{}}
// mode="view"
// />
// </MemoryRouter>,
// );

// const deleteButton = getByLabelText('Delete block');
// fireEvent.click(deleteButton);

// // Ensure onDeleteSlotfill is called with the correct blockId
// expect(onDeleteSlotfill).toHaveBeenCalledWith('slotA-state1');
// });
});
83 changes: 83 additions & 0 deletions src/SearchBlock/SearchBlockEdit.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react';
import { render, fireEvent, screen } from '@testing-library/react';
import SearchBlockEdit from './SearchBlockEdit';
import '@testing-library/jest-dom/extend-expect';

jest.mock('@plone/volto/registry', () => ({
settings: {
searchlib: {
searchui: {
default: {},
},
},
},
}));

jest.mock('./hocs', () => ({
useDebouncedStableData: jest.fn((data) => data),
}));

jest.mock('@plone/volto/components', () => ({
SidebarPortal: jest.fn((props) => (
<div>
<div>Mocked SidebarPortal</div>
{props.children}
</div>
)),
BlockDataForm: jest.fn((props) => (
<div>
<div>Mocked BlockDataForm</div>
<input id="mocked-blockDataForm" onChange={props.onChangeField} />
{props.children}
</div>
)),
}));

jest.mock('./SearchBlockView', () => {
return jest.fn((props) => (
<div>
<div>Mocked SearchBlockView</div>
<input id="mocked-searchBlockView" onChange={props.onChangeSlotfill} />
<input id="mocked-searchBlockView2" onChange={props.onDeleteSlotfill} />
{props.children}
</div>
));
});

describe('SearchBlockEdit', () => {
const mockOnChangeBlock = jest.fn();
const mockOnChangeField = jest.fn();

it('renders the SearchBlockView component', () => {
const { container } = render(
<SearchBlockEdit
onChangeBlock={mockOnChangeBlock}
onChangeField={mockOnChangeField}
block="someBlock"
data={{ someData: 'data' }}
/>,
);
expect(screen.getByText('Mocked SearchBlockView')).toBeInTheDocument();
expect(screen.getByText('Mocked SidebarPortal')).toBeInTheDocument();
expect(screen.getByText('Mocked BlockDataForm')).toBeInTheDocument();

expect(
container.querySelector('#mocked-blockDataForm'),
).toBeInTheDocument();
fireEvent.change(container.querySelector('#mocked-blockDataForm'), {
target: { value: 'someValue' },
});
expect(
container.querySelector('#mocked-searchBlockView'),
).toBeInTheDocument();
fireEvent.change(container.querySelector('#mocked-searchBlockView'), {
target: { value: 'someValue' },
});
expect(
container.querySelector('#mocked-searchBlockView2'),
).toBeInTheDocument();
fireEvent.change(container.querySelector('#mocked-searchBlockView2'), {
target: { value: 'someValue' },
});
});
});

0 comments on commit 620031b

Please sign in to comment.