decap-cms-core
Version:
Decap CMS core application, see decap-cms package for the main distribution.
191 lines (162 loc) • 7.25 kB
JavaScript
import { render } from '@testing-library/react';
import { Set, fromJS } from 'immutable';
import configureStore from 'redux-mock-store';
import { Provider } from 'react-redux';
import ConnectedEntriesCollection, {
EntriesCollection,
filterNestedEntries,
} from '../EntriesCollection';
import Entries from '../Entries';
jest.mock('../Entries', () => {
return jest.fn(props => <mock-entries {...props} />);
});
const middlewares = [];
const mockStore = configureStore(middlewares);
function createMockStore(collection, entriesArray, additionalState = {}) {
return mockStore({
entries: toEntriesState(collection, entriesArray),
cursors: fromJS({}),
config: fromJS({ publish_mode: 'simple' }),
collections: fromJS({ [collection.get('name')]: collection }),
editorialWorkflow: fromJS({
pages: { ids: [] },
}),
...additionalState,
});
}
function renderWithRedux(component, { store } = {}) {
function Wrapper({ children }) {
return <Provider store={store}>{children}</Provider>;
}
return render(component, { wrapper: Wrapper });
}
function toEntriesState(collection, entriesArray) {
const entries = entriesArray.reduce(
(acc, entry) => {
acc.entities[`${collection.get('name')}.${entry.slug}`] = entry;
acc.pages[collection.get('name')].ids.push(entry.slug);
return acc;
},
{ pages: { [collection.get('name')]: { ids: [] } }, entities: {} },
);
return fromJS(entries);
}
describe('filterNestedEntries', () => {
it('should return only immediate children for non root path', () => {
const entriesArray = [
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
{ slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } },
{ slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } },
{ slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } },
];
const entries = fromJS(entriesArray);
expect(filterNestedEntries('dir3', 'src/pages', entries).toJS()).toEqual([
{ slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } },
]);
});
it('should return only immediate children for root path', () => {
const entriesArray = [
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
{ slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } },
{ slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } },
{ slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } },
];
const entries = fromJS(entriesArray);
expect(filterNestedEntries('', 'src/pages', entries).toJS()).toEqual([
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
]);
});
});
describe('EntriesCollection', () => {
const collection = fromJS({ name: 'pages', label: 'Pages', folder: 'src/pages' });
const props = {
t: jest.fn(),
loadEntries: jest.fn(),
traverseCollectionCursor: jest.fn(),
loadUnpublishedEntries: jest.fn(),
isFetching: false,
cursor: {},
collection,
collections: fromJS({ pages: collection }),
entriesLoaded: true,
unpublishedEntriesLoaded: true,
isEditorialWorkflowEnabled: false,
getWorkflowStatus: jest.fn(),
getUnpublishedEntries: jest.fn(() => []),
};
it('should render with entries', () => {
const entries = fromJS([{ slug: 'index' }]);
const { asFragment } = render(<EntriesCollection {...props} entries={entries} />);
expect(asFragment()).toMatchSnapshot();
});
it('should render unpublished entries once when entries are grouped', () => {
Entries.mockClear();
const entries = fromJS([
{ slug: 'one', path: 'src/pages/one.md' },
{ slug: 'two', path: 'src/pages/two.md' },
]);
const groups = [
{ id: 'Groupone', label: 'Group', value: 'one', paths: Set(['src/pages/one.md']) },
{ id: 'Grouptwo', label: 'Group', value: 'two', paths: Set(['src/pages/two.md']) },
];
const { container } = render(
<EntriesCollection {...props} entries={entries} groups={groups} />,
);
const renderedEntries = container.querySelectorAll('mock-entries');
expect(renderedEntries).toHaveLength(3);
expect(Entries).toHaveBeenCalledTimes(3);
expect(Entries.mock.calls[0][0].showUnpublishedEntries).toBe(false);
expect(Entries.mock.calls[1][0].showUnpublishedEntries).toBe(false);
expect(Entries.mock.calls[2][0].showPublishedEntries).toBe(false);
expect(Entries.mock.calls[2][0].entries).toBe(entries);
});
it('should render connected component', () => {
const entriesArray = [
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
{ slug: 'dir2/index', path: 'src/pages/dir2/index.md', data: { title: 'File 2' } },
];
const store = createMockStore(collection, entriesArray);
const { asFragment } = renderWithRedux(<ConnectedEntriesCollection collection={collection} />, {
store,
});
expect(asFragment()).toMatchSnapshot();
});
it('should render show only immediate children for nested collection', () => {
const entriesArray = [
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
{ slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } },
{ slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } },
{ slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } },
];
const store = createMockStore(collection, entriesArray);
const { asFragment } = renderWithRedux(
<ConnectedEntriesCollection
collection={collection.set('nested', fromJS({ depth: 10, subfolders: false }))}
/>,
{ store },
);
expect(asFragment()).toMatchSnapshot();
});
it('should render with applied filter term for nested collections', () => {
const entriesArray = [
{ slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } },
{ slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } },
{ slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } },
{ slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } },
{ slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } },
];
const store = createMockStore(collection, entriesArray);
const { asFragment } = renderWithRedux(
<ConnectedEntriesCollection
collection={collection.set('nested', fromJS({ depth: 10, subfolders: false }))}
filterTerm="dir3/dir4"
/>,
{ store },
);
expect(asFragment()).toMatchSnapshot();
});
});