Add missing tests

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2020-11-17 11:58:03 +01:00
parent 4f27b8879c
commit 402b5db42b
8 changed files with 306 additions and 96 deletions

View File

@ -68,6 +68,7 @@ const CustomDragLayer = () => {
<Li> <Li>
<RelationItem <RelationItem
data={item.data} data={item.data}
displayNavigationLink={false}
mainField={item.mainField} mainField={item.mainField}
isDisabled={false} isDisabled={false}
isDragging isDragging

View File

@ -1,5 +1,4 @@
import { fromJS } from 'immutable'; import { fromJS } from 'immutable';
import moment from 'moment';
const initialState = fromJS({ const initialState = fromJS({
attributes: {}, attributes: {},
@ -17,7 +16,7 @@ function reducer(state, action) {
return state return state
.updateIn(['modifiedData', ...action.keys], () => { .updateIn(['modifiedData', ...action.keys], () => {
if (action.value && action.value._isAMomentObject === true) { if (action.value && action.value._isAMomentObject === true) {
return moment(action.value, 'YYYY-MM-DD HH:mm:ss').format(); return action.value.toISOString();
} }
return action.value; return action.value;

View File

@ -382,7 +382,7 @@ function ListView({
<FilterIcon /> <FilterIcon />
<FormattedMessage id="app.utils.filters" /> <FormattedMessage id="app.utils.filters" />
</AddFilterCta> </AddFilterCta>
{filters.map(({ filter: filterName, name }, key) => ( {filters.map(({ filter: filterName, name, value }, key) => (
<Filter <Filter
contentType={contentType} contentType={contentType}
filterName={filterName} filterName={filterName}
@ -393,6 +393,7 @@ function ListView({
toggleFilterPickerState={toggleFilterPickerState} toggleFilterPickerState={toggleFilterPickerState}
isFilterPickerOpen={isFilterPickerOpen} isFilterPickerOpen={isFilterPickerOpen}
setQuery={setQuery} setQuery={setQuery}
value={value}
/> />
))} ))}
</> </>

View File

@ -2,6 +2,53 @@ import { cloneDeep, get, set } from 'lodash';
import { mergeMetasWithSchema } from '../../../utils'; import { mergeMetasWithSchema } from '../../../utils';
import pluginId from '../../../pluginId'; import pluginId from '../../../pluginId';
// editRelations is an array of strings...
const formatEditRelationsLayoutWithMetas = (obj, models) => {
const formatted = obj.layouts.editRelations.reduce((acc, current) => {
const fieldSchema = get(obj, ['attributes', current], {});
const metadatas = get(obj, ['metadatas', current, 'edit'], {});
const size = 6;
const queryInfos = generateRelationQueryInfos(obj, current, models);
acc.push({
name: current,
size,
fieldSchema,
metadatas,
queryInfos,
});
return acc;
}, []);
return formatted;
};
const formatLayouts = (initialData, models) => {
const data = mergeMetasWithSchema(cloneDeep(initialData), models, 'contentType');
const formattedCTEditLayout = formatLayoutWithMetas(data.contentType, null, models);
const ctUid = data.contentType.uid;
const formattedEditRelationsLayout = formatEditRelationsLayoutWithMetas(data.contentType, models);
const formattedListLayout = formatListLayoutWithMetas(data.contentType);
set(data, ['contentType', 'layouts', 'edit'], formattedCTEditLayout);
set(data, ['contentType', 'layouts', 'editRelations'], formattedEditRelationsLayout);
set(data, ['contentType', 'layouts', 'list'], formattedListLayout);
Object.keys(data.components).forEach(compoUID => {
const formattedCompoEditLayout = formatLayoutWithMetas(
data.components[compoUID],
ctUid,
models
);
set(data, ['components', compoUID, 'layouts', 'edit'], formattedCompoEditLayout);
});
return data;
};
const formatLayoutWithMetas = (obj, ctUid, models) => { const formatLayoutWithMetas = (obj, ctUid, models) => {
const formatted = obj.layouts.edit.reduce((acc, current) => { const formatted = obj.layouts.edit.reduce((acc, current) => {
const row = current.map(attribute => { const row = current.map(attribute => {
@ -32,8 +79,18 @@ const formatLayoutWithMetas = (obj, ctUid, models) => {
return formatted; return formatted;
}; };
const getDisplayedModels = models => const formatListLayoutWithMetas = obj => {
models.filter(model => model.isDisplayed).map(({ uid }) => uid); const formatted = obj.layouts.list.reduce((acc, current) => {
const fieldSchema = get(obj, ['attributes', current], {});
const metadatas = get(obj, ['metadatas', current, 'list'], {});
acc.push({ key: `__${current}_key__`, name: current, fieldSchema, metadatas });
return acc;
}, []);
return formatted;
};
const generateRelationQueryInfos = (obj, fieldName, models) => { const generateRelationQueryInfos = (obj, fieldName, models) => {
const uid = obj.uid; const uid = obj.uid;
@ -70,65 +127,15 @@ const generateRelationQueryInfosForComponents = (obj, fieldName, ctUid, models)
return queryInfos; return queryInfos;
}; };
// editRelations is an array of strings... const getDisplayedModels = models =>
const formatEditRelationsLayoutWithMetas = (obj, models) => { models.filter(model => model.isDisplayed).map(({ uid }) => uid);
const formatted = obj.layouts.editRelations.reduce((acc, current) => {
const fieldSchema = get(obj, ['attributes', current], {});
const metadatas = get(obj, ['metadatas', current, 'edit'], {});
const size = 6;
const queryInfos = generateRelationQueryInfos(obj, current, models);
acc.push({
name: current,
size,
fieldSchema,
metadatas,
queryInfos,
});
return acc;
}, []);
return formatted;
};
const formatListLayoutWithMetas = obj => {
const formatted = obj.layouts.list.reduce((acc, current) => {
const fieldSchema = get(obj, ['attributes', current], {});
const metadatas = get(obj, ['metadatas', current, 'list'], {});
acc.push({ key: `__${current}_key__`, name: current, fieldSchema, metadatas });
return acc;
}, []);
return formatted;
};
const formatLayouts = (initialData, models) => {
const data = mergeMetasWithSchema(cloneDeep(initialData), models, 'contentType');
const formattedCTEditLayout = formatLayoutWithMetas(data.contentType, models);
const ctUid = data.contentType.uid;
const formattedEditRelationsLayout = formatEditRelationsLayoutWithMetas(data.contentType, models);
const formattedListLayout = formatListLayoutWithMetas(data.contentType);
set(data, ['contentType', 'layouts', 'edit'], formattedCTEditLayout);
set(data, ['contentType', 'layouts', 'editRelations'], formattedEditRelationsLayout);
set(data, ['contentType', 'layouts', 'list'], formattedListLayout);
Object.keys(data.components).forEach(compoUID => {
const formattedCompoEditLayout = formatLayoutWithMetas(
data.components[compoUID],
ctUid,
models
);
set(data, ['components', compoUID, 'layouts', 'edit'], formattedCompoEditLayout);
});
return data;
};
export default formatLayouts; export default formatLayouts;
export { formatEditRelationsLayoutWithMetas, formatLayoutWithMetas }; export {
formatEditRelationsLayoutWithMetas,
formatLayoutWithMetas,
formatListLayoutWithMetas,
generateRelationQueryInfos,
generateRelationQueryInfosForComponents,
getDisplayedModels,
};

View File

@ -1,12 +1,70 @@
import formatLayouts, { formatLayoutWithMetas } from '../formatLayouts'; import formatLayouts, {
formatEditRelationsLayoutWithMetas,
formatLayoutWithMetas,
formatListLayoutWithMetas,
generateRelationQueryInfos,
generateRelationQueryInfosForComponents,
getDisplayedModels,
} from '../formatLayouts';
const addressSchema = {
uid: 'application::address.address',
attributes: {
categories: {
targetModel: 'application::category.category',
},
},
layouts: {
editRelations: ['categories'],
},
metadatas: {
categories: {
edit: {
mainField: 'name',
},
},
},
};
const simpleModels = [
{
uid: 'application::category.category',
isDisplayed: true,
},
];
describe('Content Manager | hooks | useFetchContentTypeLayout | utils ', () => {
describe('formatEditRelationsLayoutWithMetas', () => {
it('should format editRelations layout correctly', () => {
const expectedLayout = [
{
name: 'categories',
size: 6,
fieldSchema: {
targetModel: 'application::category.category',
},
metadatas: {
mainField: 'name',
},
queryInfos: {
endPoint: '/content-manager/relations/application::address.address/categories',
containsKey: 'name_contains',
defaultParams: {},
shouldDisplayRelationLink: true,
},
},
];
expect(formatEditRelationsLayoutWithMetas(addressSchema, simpleModels)).toEqual(
expectedLayout
);
});
});
describe('Content Manager | hooks | useFetchContentTypeLayout | utils | formatLayoutWithMetas', () => {
describe('formatLayouts', () => { describe('formatLayouts', () => {
it('should format the content type and components layouts', () => { it('should format the content type and components layouts', () => {
const models = [ const models = [
{ {
uid: 'compo', uid: 'compo',
attributes: { attributes: {
full_name: { full_name: {
type: 'string', type: 'string',
@ -33,7 +91,6 @@ describe('Content Manager | hooks | useFetchContentTypeLayout | utils | formatLa
type: 'string', type: 'string',
required: true, required: true,
}, },
city: { city: {
type: 'string', type: 'string',
maxLength: 100, maxLength: 100,
@ -53,7 +110,6 @@ describe('Content Manager | hooks | useFetchContentTypeLayout | utils | formatLa
components: { components: {
compo: { compo: {
uid: 'compo', uid: 'compo',
layouts: { layouts: {
edit: [ edit: [
[ [
@ -157,7 +213,6 @@ describe('Content Manager | hooks | useFetchContentTypeLayout | utils | formatLa
expect(result.contentType).toHaveProperty('attributes'); expect(result.contentType).toHaveProperty('attributes');
expect(result.contentType).toHaveProperty('layouts'); expect(result.contentType).toHaveProperty('layouts');
expect(result.contentType).toHaveProperty('metadatas'); expect(result.contentType).toHaveProperty('metadatas');
expect(result.contentType.layouts.edit).toEqual([ expect(result.contentType.layouts.edit).toEqual([
[ [
{ {
@ -421,4 +476,76 @@ describe('Content Manager | hooks | useFetchContentTypeLayout | utils | formatLa
expect(formatLayoutWithMetas(data)).toEqual(expected); expect(formatLayoutWithMetas(data)).toEqual(expected);
}); });
}); });
describe('formatListLayoutWithMetas', () => {
it('should format the list layout correctly', () => {
const data = {
layouts: {
list: ['test'],
},
metadatas: {
test: {
list: { ok: true },
},
},
attributes: {
test: { type: 'string' },
},
};
const expected = [
{
name: 'test',
key: '__test_key__',
metadatas: { ok: true },
fieldSchema: { type: 'string' },
},
];
expect(formatListLayoutWithMetas(data)).toEqual(expected);
});
});
describe('generateRelationQueryInfos', () => {
it('should return an object with the correct keys', () => {
expect(generateRelationQueryInfos(addressSchema, 'categories', simpleModels)).toEqual({
endPoint: '/content-manager/relations/application::address.address/categories',
containsKey: 'name_contains',
defaultParams: {},
shouldDisplayRelationLink: true,
});
});
});
describe('generateRelationQueryInfosForComponents', () => {
it('should return an object with the correct keys', () => {
expect(
generateRelationQueryInfosForComponents(
addressSchema,
'categories',
'application::address.address',
simpleModels
)
).toEqual({
endPoint: '/content-manager/relations/application::address.address/categories',
containsKey: 'name_contains',
defaultParams: {
_component: 'application::address.address',
},
shouldDisplayRelationLink: true,
});
});
});
describe('getDisplayedModels', () => {
it('should return an array containing only the displayable models', () => {
const models = [
{ uid: 'test', isDisplayed: false },
{ uid: 'testtest', isDisplayed: true },
];
expect(getDisplayedModels([])).toHaveLength(0);
expect(getDisplayedModels(models)).toHaveLength(1);
expect(getDisplayedModels(models)[0]).toEqual('testtest');
});
});
}); });

View File

@ -1,30 +1,37 @@
const findAppliedFilter = str => { // List of all the possible filters
let filter = '='; const VALID_REST_OPERATORS = [
let name = str; 'eq',
'ne',
const filters = [ 'in',
'_ne', 'nin',
'_lt', 'contains',
'_lte', 'ncontains',
'_gt', 'containss',
'_gte', 'ncontainss',
'_contains', 'lt',
'_containss', 'lte',
'_ncontains', 'gt',
'_in', 'gte',
'_nin', 'null',
]; ];
filters.forEach(filterName => { // from strapi-utims/convert-rest-query-params
const split = str.split(filterName); const findAppliedFilter = whereClause => {
const separatorIndex = whereClause.lastIndexOf('_');
if (split[1] === '') { if (separatorIndex === -1) {
filter = filterName; return { operator: '=', field: whereClause };
name = split[0];
} }
});
return { filter, name }; const fieldName = whereClause.substring(0, separatorIndex);
const operator = whereClause.slice(separatorIndex + 1);
// the field as underscores
if (!VALID_REST_OPERATORS.includes(operator)) {
return { operator: '=', field: whereClause };
}
return { operator: `_${operator}`, field: fieldName };
}; };
const formatFiltersFromQuery = ({ _where }) => { const formatFiltersFromQuery = ({ _where }) => {
@ -34,11 +41,11 @@ const formatFiltersFromQuery = ({ _where }) => {
return _where.map(obj => { return _where.map(obj => {
const [key] = Object.keys(obj); const [key] = Object.keys(obj);
const { filter, name } = findAppliedFilter(key); const { field, operator } = findAppliedFilter(key);
const value = obj[key]; const value = obj[key];
return { name, filter, value }; return { name: field, filter: operator, value };
}); });
}; };

View File

@ -0,0 +1,45 @@
import formatFiltersFromQuery, { findAppliedFilter } from '../formatFiltersFromQuery';
describe('CONTENT MANAGER | utils', () => {
describe('findAppliedFilter', () => {
it('should return the correct filter', () => {
expect(findAppliedFilter('city')).toEqual({ operator: '=', field: 'city' });
expect(findAppliedFilter('city_nee')).toEqual({ operator: '=', field: 'city_nee' });
expect(findAppliedFilter('city_ne')).toEqual({ operator: '_ne', field: 'city' });
expect(findAppliedFilter('city_lt')).toEqual({ operator: '_lt', field: 'city' });
expect(findAppliedFilter('city_lte')).toEqual({ operator: '_lte', field: 'city' });
expect(findAppliedFilter('city_gt')).toEqual({ operator: '_gt', field: 'city' });
expect(findAppliedFilter('city_gte')).toEqual({ operator: '_gte', field: 'city' });
});
});
describe('formatFiltersFromQuery', () => {
it('should return an empty array if there is no where clause', () => {
expect(formatFiltersFromQuery({})).toHaveLength(0);
});
it('should return array of filter', () => {
const query = {
_where: [
{
city_ne_ne: 'paris',
},
{
city_ne: 'paris',
},
{
city: 'paris',
},
],
};
const expected = [
{ name: 'city_ne', filter: '_ne', value: 'paris' },
{ name: 'city', filter: '_ne', value: 'paris' },
{ name: 'city', filter: '=', value: 'paris' },
];
expect(formatFiltersFromQuery(query)).toEqual(expected);
});
});
});

View File

@ -0,0 +1,23 @@
import formatLayoutToApi from '../formatLayoutToApi';
describe('CONTENT MANAGER | utils | formatLayoutToApi', () => {
it('should format the list layout correctly if it is an array of objects', () => {
const layouts = {
list: [{ name: 'test', size: 6 }],
edit: [],
editRelations: [],
};
expect(formatLayoutToApi({ layouts }).layouts.list).toEqual(['test']);
});
it('should format the list layout correctly if it is an array of strings', () => {
const layouts = {
list: ['test'],
edit: [],
editRelations: [],
};
expect(formatLayoutToApi({ layouts }).layouts.list).toEqual(['test']);
});
});