@eeacms/volto-accordion-block
Version:
volto-accordion-block: Volto accordion block
226 lines (200 loc) • 5.88 kB
JSX
import React from 'react';
import View from './View';
import { render, fireEvent, screen } from '@testing-library/react';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-intl-redux';
import { MemoryRouter, Route } from 'react-router-dom';
import config from '@plone/volto/registry';
import * as utils from './util';
import '@testing-library/jest-dom';
config.blocks.blocksConfig.accordion = {
...config.blocks.blocksConfig.accordion,
titleIcons: {
opened: {
rightPosition: 'chevron left',
leftPosition: 'chevron right',
},
closed: {
rightPosition: 'chevron down',
leftPosition: 'chevron down',
},
unfiltered: {
rightPosition: 'chevron left',
leftPosition: 'chevron right',
},
filtered: {
rightPosition: 'chevron down',
leftPosition: 'chevron down',
},
size: 'tiny',
iconComponent: 'SemanticIcon',
},
};
const mockStore = configureStore();
const store = mockStore({
intl: {
locale: 'en',
messages: {},
},
});
jest.mock('@plone/volto/helpers//Extensions', () => ({
withBlockExtensions: jest.fn((Component) => Component),
}));
jest.mock('@plone/volto/components/theme/View/RenderBlocks', () => ({
__esModule: true,
default: jest.fn(() => <div>RenderBlocks</div>),
}));
jest.mock('./util', () => ({
getPanels: () => [['id1', { title: 'Panel 1' }]],
accordionBlockHasValue: jest.fn(),
Icon: () => <div>Icon</div>,
}));
const mockData = {
'@type': 'accordion',
title_size: 'h3',
right_arrows: true,
collapsed: false,
exclusive: false,
non_exclusive: true,
styles: {
theme: 'default',
},
};
const mockData1 = {
'@type': 'accordion',
title_size: 'h3',
right_arrows: false,
collapsed: true,
exclusive: false,
non_exclusive: true,
};
const mockData2 = {
'@type': 'accordion',
data: {
blocks: {
1: {
'@type': 'accordionPanel',
title: 'Panel 1',
blocks_layout: {
items: ['block1', 'block2'],
},
},
2: {
'@type': 'accordionPanel',
title: 'Panel 2',
blocks_layout: {
items: ['block3', 'block4'],
},
},
},
blocks_layout: {
items: ['1', '2'],
},
},
right_arrows: false,
non_exclusive: true,
collapsed: false,
filtering: false,
};
describe('View Component', () => {
it('renders with panels', () => {
utils.accordionBlockHasValue.mockReturnValue(true);
const { rerender, getByText } = render(
<Provider store={store}>
<MemoryRouter>
<View data={mockData} />
</MemoryRouter>
</Provider>,
);
expect(getByText('Panel 1')).toBeInTheDocument();
rerender(
<Provider store={store}>
<MemoryRouter>
<View data={mockData1} />
</MemoryRouter>
</Provider>,
);
});
it('should open accordion content when title is clicked', () => {
utils.accordionBlockHasValue.mockReturnValue(true);
const { container, getByText } = render(
<Provider store={store}>
<MemoryRouter>
<View data={mockData} />
</MemoryRouter>
</Provider>,
);
const accordionTitle = container.querySelector('.accordion-title');
fireEvent.click(accordionTitle);
const contentElement = getByText('RenderBlocks');
expect(contentElement).toBeInTheDocument();
});
it('should open accordion content when title is clicked', () => {
utils.accordionBlockHasValue.mockReturnValue(true);
const { container, getByText } = render(
<Provider store={store}>
<MemoryRouter>
<View data={{ ...mockData, non_exclusive: false }}>
<p>Accordion Content</p>
</View>
</MemoryRouter>
</Provider>,
);
const accordionTitle = container.querySelector('.accordion-title');
fireEvent.click(accordionTitle);
const contentElement = getByText('RenderBlocks');
expect(contentElement).toBeInTheDocument();
});
it('should open accordion content when Enter key is pressed', () => {
const { container, getByText } = render(
<Provider store={store}>
<MemoryRouter>
<View data={mockData} />
</MemoryRouter>
</Provider>,
);
const accordionTitle = container.querySelector('.accordion-title');
fireEvent.keyDown(accordionTitle, { keyCode: 13 });
const contentElement = getByText('RenderBlocks');
expect(contentElement).toBeInTheDocument();
});
it('filters the accordion panels based on the filter value', () => {
render(
<Provider store={store}>
<MemoryRouter>
<View data={{ ...mockData2, filtering: true }} />
</MemoryRouter>
</Provider>,
);
const filterInput = screen.getByPlaceholderText('Type to filter...');
fireEvent.change(filterInput, { target: { value: 'Panel 1' } });
expect(screen.getByText('Panel 1')).toBeInTheDocument();
expect(screen.queryByText('Panel 2')).not.toBeInTheDocument();
});
it('updates the URL query parameter when a panel is clicked', () => {
render(
<Provider store={store}>
<MemoryRouter initialEntries={['/']}>
<View data={mockData2} />
<Route
path="*"
render={({ location }) => <div>{location.search}</div>}
/>
</MemoryRouter>
</Provider>,
);
const panel1Title = screen.getByText('Panel 1');
fireEvent.click(panel1Title);
expect(screen.getByText('?activeAccordion=')).toBeInTheDocument();
});
it('renders the accordion panels in diff view mode', () => {
render(
<Provider store={store}>
<MemoryRouter initialEntries={['/diff']}>
<View data={mockData2} />
</MemoryRouter>
</Provider>,
);
expect(screen.getByText('RenderBlocks')).toBeInTheDocument();
});
});