mirror of
https://github.com/strapi/strapi.git
synced 2025-12-09 05:50:37 +00:00
Merge pull request #4995 from strapi/chore/ctb-front-end-tests
Chore/ctb front end tests
This commit is contained in:
commit
27c3cf7a91
@ -81,10 +81,10 @@
|
||||
"dz": {
|
||||
"type": "dynamiczone",
|
||||
"components": [
|
||||
"default.closingperiod",
|
||||
"default.dish",
|
||||
"default.openingtimes",
|
||||
"default.restaurantservice"
|
||||
"default.restaurantservice",
|
||||
"default.closingperiod",
|
||||
"default.dish"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ const MultipleMenuList = ({
|
||||
const handleChange = ({ target }) => {
|
||||
const dataTarget = {
|
||||
name,
|
||||
components: target.name,
|
||||
components: [target.name],
|
||||
shouldAddComponents: target.value,
|
||||
};
|
||||
|
||||
|
||||
@ -2,8 +2,9 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { SelectWrapper, SelectNav } from 'strapi-helper-plugin';
|
||||
import { ErrorMessage } from '@buffetjs/styles';
|
||||
import CreatableSelect from '../CreatableSelect';
|
||||
import ComponentSelect from '../ComponentSelect';
|
||||
import CreatableSelect from '../CreatableSelect';
|
||||
|
||||
/* eslint-disable no-nested-ternary */
|
||||
|
||||
const WrapperSelect = ({ error, label, name, type, ...rest }) => {
|
||||
@ -19,7 +20,7 @@ const WrapperSelect = ({ error, label, name, type, ...rest }) => {
|
||||
border: state.isFocused
|
||||
? '1px solid #78caff !important'
|
||||
: error
|
||||
? '1px solid red !important'
|
||||
? '1px solid #F64D0A !important'
|
||||
: '1px solid #E3E9F3 !important',
|
||||
borderRadius: '2px !important',
|
||||
}),
|
||||
|
||||
@ -86,6 +86,7 @@ const DataManagerProvider = ({ allIcons, children }) => {
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const components = createDataObject(componentsArray);
|
||||
const contentTypes = createDataObject(contentTypesArray);
|
||||
const orderedComponents = orderAllDataAttributesWithImmutable({
|
||||
|
||||
@ -7,7 +7,7 @@ const initialState = fromJS({
|
||||
components: {},
|
||||
contentTypes: {},
|
||||
initialComponents: {},
|
||||
intialContentTypes: {},
|
||||
initialContentTypes: {},
|
||||
initialData: {},
|
||||
modifiedData: {},
|
||||
isLoading: true,
|
||||
@ -15,6 +15,7 @@ const initialState = fromJS({
|
||||
});
|
||||
|
||||
const ONE_SIDE_RELATIONS = ['oneWay', 'manyWay'];
|
||||
|
||||
const getOppositeNature = originalNature => {
|
||||
if (originalNature === 'manyToOne') {
|
||||
return 'oneToMany';
|
||||
@ -113,7 +114,8 @@ const reducer = (state, action) => {
|
||||
nature: getOppositeNature(nature),
|
||||
target,
|
||||
unique: rest.unique,
|
||||
required: rest.required,
|
||||
// Leave this if we allow the required on the relation
|
||||
// required: rest.required,
|
||||
dominant: nature === 'manyToMany' ? !rest.dominant : null,
|
||||
targetAttribute: name,
|
||||
columnName: rest.targetColumnName,
|
||||
@ -241,15 +243,6 @@ const reducer = (state, action) => {
|
||||
? [forTarget]
|
||||
: [forTarget, targetUid];
|
||||
|
||||
const isEditingComponentAttribute = rest.type === 'component';
|
||||
|
||||
if (isEditingComponentAttribute) {
|
||||
newState = state.updateIn(
|
||||
['modifiedData', 'components', rest.component],
|
||||
() => state.getIn(['components', rest.component])
|
||||
);
|
||||
}
|
||||
|
||||
return newState.updateIn(
|
||||
['modifiedData', ...pathToDataToEdit, 'schema'],
|
||||
obj => {
|
||||
@ -333,7 +326,8 @@ const reducer = (state, action) => {
|
||||
nature: getOppositeNature(rest.nature),
|
||||
target: rest.target,
|
||||
unique: rest.unique,
|
||||
required: rest.required,
|
||||
// Leave this if we allow the required on the relation
|
||||
// required: rest.required,
|
||||
dominant:
|
||||
rest.nature === 'manyToMany' ? !rest.dominant : null,
|
||||
targetAttribute: name,
|
||||
@ -389,7 +383,7 @@ const reducer = (state, action) => {
|
||||
);
|
||||
}
|
||||
|
||||
case 'GET_DATA_SUCCEEDED':
|
||||
case 'GET_DATA_SUCCEEDED': {
|
||||
return state
|
||||
.update('components', () => fromJS(action.components))
|
||||
.update('initialComponents', () => fromJS(action.components))
|
||||
@ -397,7 +391,7 @@ const reducer = (state, action) => {
|
||||
.update('contentTypes', () => fromJS(action.contentTypes))
|
||||
|
||||
.update('isLoading', () => false);
|
||||
|
||||
}
|
||||
case 'RELOAD_PLUGIN':
|
||||
return initialState;
|
||||
case 'REMOVE_FIELD_FROM_DISPLAYED_COMPONENT': {
|
||||
@ -519,4 +513,4 @@ const reducer = (state, action) => {
|
||||
};
|
||||
|
||||
export default reducer;
|
||||
export { initialState };
|
||||
export { addComponentsToState, initialState };
|
||||
|
||||
@ -0,0 +1,485 @@
|
||||
const data = {
|
||||
components: {
|
||||
'default.closingperiod': {
|
||||
uid: 'default.closingperiod',
|
||||
category: '',
|
||||
schema: {
|
||||
icon: 'angry',
|
||||
name: 'closingperiod',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_closingperiods',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
},
|
||||
start_date: {
|
||||
type: 'date',
|
||||
required: true,
|
||||
},
|
||||
end_date: {
|
||||
type: 'date',
|
||||
required: true,
|
||||
},
|
||||
media: {
|
||||
type: 'media',
|
||||
multiple: false,
|
||||
required: false,
|
||||
},
|
||||
dish: {
|
||||
component: 'default.dish',
|
||||
type: 'component',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'default.dish': {
|
||||
uid: 'default.dish',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'book',
|
||||
name: 'dish',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_dishes',
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'My super dish',
|
||||
},
|
||||
description: {
|
||||
type: 'text',
|
||||
},
|
||||
price: {
|
||||
type: 'float',
|
||||
},
|
||||
picture: {
|
||||
type: 'media',
|
||||
multiple: false,
|
||||
required: false,
|
||||
},
|
||||
very_long_description: {
|
||||
type: 'richtext',
|
||||
},
|
||||
category: {
|
||||
nature: 'oneWay',
|
||||
target: 'application::category.category',
|
||||
dominant: false,
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'default.openingtimes': {
|
||||
uid: 'default.openingtimes',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'openingtimes',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_openingtimes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'default.restaurantservice': {
|
||||
uid: 'default.restaurantservice',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'strapi',
|
||||
name: 'restaurantservice',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_restaurantservices',
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
media: {
|
||||
type: 'media',
|
||||
multiple: false,
|
||||
required: false,
|
||||
},
|
||||
is_available: {
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
contentTypes: {
|
||||
'plugins::myplugin.test': {
|
||||
uid: '',
|
||||
plugin: 'myplugin',
|
||||
schema: {
|
||||
name: 'test',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'myplugin_test',
|
||||
attributes: {
|
||||
type: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
unique: true,
|
||||
configurable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'plugins::users-permissions.role': {
|
||||
uid: 'plugins::users-permissions.role',
|
||||
plugin: 'users-permissions',
|
||||
schema: {
|
||||
name: 'role',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
name: {
|
||||
type: 'string',
|
||||
minLength: 3,
|
||||
required: true,
|
||||
configurable: false,
|
||||
},
|
||||
description: { type: 'string', configurable: false },
|
||||
type: { type: 'string', unique: true, configurable: false },
|
||||
permissions: {
|
||||
nature: 'oneToMany',
|
||||
target: 'plugins::users-permissions.permission',
|
||||
plugin: 'users-permissions',
|
||||
dominant: false,
|
||||
targetAttribute: 'role',
|
||||
configurable: false,
|
||||
unique: false,
|
||||
},
|
||||
users: {
|
||||
nature: 'oneToMany',
|
||||
target: 'plugins::users-permissions.user',
|
||||
plugin: 'users-permissions',
|
||||
dominant: false,
|
||||
targetAttribute: 'role',
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::address.address': {
|
||||
uid: 'application::address.address',
|
||||
schema: {
|
||||
name: 'address',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
geolocation: { type: 'json', required: true },
|
||||
city: { type: 'string', required: true },
|
||||
postal_coder: { type: 'string' },
|
||||
category: {
|
||||
nature: 'oneWay',
|
||||
target: 'application::category.category',
|
||||
dominant: false,
|
||||
unique: false,
|
||||
},
|
||||
cover: { type: 'media', multiple: false, required: false },
|
||||
images: { type: 'media', multiple: true, required: false },
|
||||
full_name: { type: 'string', required: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::menusection.menusection': {
|
||||
uid: 'application::menusection.menusection',
|
||||
schema: {
|
||||
name: 'menusection',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
name: { type: 'string', required: true, minLength: 6 },
|
||||
dishes: {
|
||||
component: 'default.dish',
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
},
|
||||
menu: {
|
||||
nature: 'manyToOne',
|
||||
target: 'application::menu.menu',
|
||||
dominant: false,
|
||||
targetAttribute: 'menusections',
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::country.country': {
|
||||
uid: 'application::country.country',
|
||||
schema: {
|
||||
name: 'country',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
name: { type: 'string', required: true, minLength: 3 },
|
||||
code: { type: 'string', maxLength: 3, unique: true, minLength: 2 },
|
||||
},
|
||||
},
|
||||
},
|
||||
'plugins::users-permissions.user': {
|
||||
uid: 'plugins::users-permissions.user',
|
||||
plugin: 'users-permissions',
|
||||
schema: {
|
||||
name: 'users',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
username: {
|
||||
type: 'string',
|
||||
minLength: 3,
|
||||
unique: true,
|
||||
configurable: false,
|
||||
required: true,
|
||||
},
|
||||
email: {
|
||||
type: 'email',
|
||||
minLength: 6,
|
||||
configurable: false,
|
||||
required: true,
|
||||
},
|
||||
provider: { type: 'string', configurable: false },
|
||||
password: {
|
||||
type: 'password',
|
||||
minLength: 6,
|
||||
configurable: false,
|
||||
private: true,
|
||||
},
|
||||
resetPasswordToken: {
|
||||
type: 'string',
|
||||
configurable: false,
|
||||
private: true,
|
||||
},
|
||||
confirmed: { type: 'boolean', default: false, configurable: false },
|
||||
blocked: { type: 'boolean', default: false, configurable: false },
|
||||
role: {
|
||||
nature: 'manyToOne',
|
||||
target: 'plugins::users-permissions.role',
|
||||
plugin: 'users-permissions',
|
||||
dominant: false,
|
||||
targetAttribute: 'users',
|
||||
configurable: false,
|
||||
unique: false,
|
||||
},
|
||||
picture: { type: 'media', multiple: false, required: false },
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::review.review': {
|
||||
uid: 'application::review.review',
|
||||
schema: {
|
||||
name: 'review',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
comment: { type: 'text', required: true },
|
||||
rating: { type: 'integer', required: true, min: 1, max: 5 },
|
||||
likes: {
|
||||
nature: 'oneToMany',
|
||||
target: 'application::like.like',
|
||||
dominant: false,
|
||||
targetAttribute: 'review',
|
||||
unique: false,
|
||||
},
|
||||
author: {
|
||||
nature: 'oneWay',
|
||||
target: 'plugins::users-permissions.user',
|
||||
plugin: 'users-permissions',
|
||||
dominant: false,
|
||||
unique: false,
|
||||
},
|
||||
restaurant: {
|
||||
nature: 'oneWay',
|
||||
target: 'application::restaurant.restaurant',
|
||||
dominant: false,
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::like.like': {
|
||||
uid: 'application::like.like',
|
||||
schema: {
|
||||
name: 'like',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
author: {
|
||||
nature: 'oneWay',
|
||||
target: 'plugins::users-permissions.user',
|
||||
plugin: 'users-permissions',
|
||||
dominant: false,
|
||||
unique: false,
|
||||
},
|
||||
review: {
|
||||
nature: 'manyToOne',
|
||||
target: 'application::review.review',
|
||||
dominant: false,
|
||||
targetAttribute: 'likes',
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::category.category': {
|
||||
uid: 'application::category.category',
|
||||
schema: {
|
||||
name: 'category',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
name: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
'plugins::users-permissions.permission': {
|
||||
uid: 'plugins::users-permissions.permission',
|
||||
plugin: 'users-permissions',
|
||||
schema: {
|
||||
name: 'permission',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
type: { type: 'string', required: true, configurable: false },
|
||||
controller: { type: 'string', required: true, configurable: false },
|
||||
action: { type: 'string', required: true, configurable: false },
|
||||
enabled: { type: 'boolean', required: true, configurable: false },
|
||||
policy: { type: 'string', configurable: false },
|
||||
role: {
|
||||
nature: 'manyToOne',
|
||||
target: 'plugins::users-permissions.role',
|
||||
plugin: 'users-permissions',
|
||||
dominant: false,
|
||||
targetAttribute: 'permissions',
|
||||
configurable: false,
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::menu.menu': {
|
||||
uid: 'application::menu.menu',
|
||||
schema: {
|
||||
name: 'menu',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
description: { type: 'text' },
|
||||
menusections: {
|
||||
nature: 'oneToMany',
|
||||
target: 'application::menusection.menusection',
|
||||
dominant: false,
|
||||
targetAttribute: 'menu',
|
||||
unique: false,
|
||||
},
|
||||
restaurant: {
|
||||
nature: 'oneToOne',
|
||||
target: 'application::restaurant.restaurant',
|
||||
dominant: false,
|
||||
targetAttribute: 'menu',
|
||||
unique: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'application::restaurant.restaurant': {
|
||||
uid: 'application::restaurant.restaurant',
|
||||
schema: {
|
||||
name: 'restaurant',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: '',
|
||||
attributes: {
|
||||
price_range: {
|
||||
enum: [
|
||||
'very_cheap',
|
||||
'cheap',
|
||||
'average',
|
||||
'expensive',
|
||||
'very_expensive',
|
||||
],
|
||||
type: 'enumeration',
|
||||
},
|
||||
closing_period: {
|
||||
component: 'default.closingperiod',
|
||||
type: 'component',
|
||||
},
|
||||
name: { maxLength: 50, required: true, minLength: 5, type: 'string' },
|
||||
address: {
|
||||
nature: 'oneWay',
|
||||
target: 'application::address.address',
|
||||
dominant: false,
|
||||
unique: false,
|
||||
},
|
||||
cover: { type: 'media', multiple: false, required: false },
|
||||
images: { type: 'media', multiple: true, required: false },
|
||||
short_description: { type: 'text' },
|
||||
since: { type: 'date' },
|
||||
categories: {
|
||||
nature: 'manyWay',
|
||||
target: 'application::category.category',
|
||||
dominant: false,
|
||||
unique: false,
|
||||
},
|
||||
description: { type: 'richtext', required: true },
|
||||
services: {
|
||||
component: 'default.restaurantservice',
|
||||
repeatable: true,
|
||||
type: 'component',
|
||||
},
|
||||
menu: {
|
||||
nature: 'oneToOne',
|
||||
target: 'application::menu.menu',
|
||||
dominant: false,
|
||||
targetAttribute: 'restaurant',
|
||||
unique: false,
|
||||
},
|
||||
opening_times: {
|
||||
component: 'default.openingtimes',
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
min: 1,
|
||||
max: 10,
|
||||
},
|
||||
dz: {
|
||||
type: 'dynamiczone',
|
||||
components: [
|
||||
'default.closingperiod',
|
||||
'default.dish',
|
||||
'default.openingtimes',
|
||||
'default.restaurantservice',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default data;
|
||||
@ -0,0 +1,842 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import { get } from 'lodash';
|
||||
import reducer, { initialState } from '../reducer';
|
||||
import testData from './data';
|
||||
|
||||
describe('CTB | containers | DataManagerProvider | reducer | ADD_ATTRIBUTE', () => {
|
||||
describe('Adding a common field that is not a relation', () => {
|
||||
it('Should add a text field to a content type correctly', () => {
|
||||
const state = initialState.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(get(testData, ['contentTypes', 'application::address.address']))
|
||||
);
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
|
||||
attributeToSet: {
|
||||
type: 'string',
|
||||
name: 'name',
|
||||
default: 'something',
|
||||
private: true,
|
||||
required: true,
|
||||
unique: true,
|
||||
maxLength: 3,
|
||||
minLength: 1,
|
||||
},
|
||||
forTarget: 'contentType',
|
||||
targetUid: 'application::address.address',
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'name'],
|
||||
fromJS({
|
||||
type: 'string',
|
||||
default: 'something',
|
||||
private: true,
|
||||
required: true,
|
||||
unique: true,
|
||||
maxLength: 3,
|
||||
minLength: 1,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should add a integer field to a component that is an attribute of a content type', () => {
|
||||
const compoUID = 'default.dish';
|
||||
const compoSchema = fromJS(get(testData, ['components', compoUID]));
|
||||
const state = initialState
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(
|
||||
get(testData, ['contentTypes', 'application::address.address'])
|
||||
).setIn(
|
||||
['schema', 'attributes', 'compo_field'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
component: compoUID,
|
||||
})
|
||||
)
|
||||
)
|
||||
.setIn(['modifiedData', 'components', compoUID], compoSchema)
|
||||
.setIn(['components', compoUID], compoSchema);
|
||||
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
name: 'test',
|
||||
type: 'integer',
|
||||
default: 2,
|
||||
private: true,
|
||||
required: true,
|
||||
min: null,
|
||||
},
|
||||
forTarget: 'components',
|
||||
targetUid: 'default.dish',
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
|
||||
const expected = state.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'components',
|
||||
compoUID,
|
||||
'schema',
|
||||
'attributes',
|
||||
'test',
|
||||
],
|
||||
fromJS({
|
||||
type: 'integer',
|
||||
default: 2,
|
||||
private: true,
|
||||
required: true,
|
||||
min: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding a component field attribute', () => {
|
||||
it('Should create the component attribute and add the component to the modifiedData.components if the component is not in the object', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const contentType = get(testData, ['contentTypes', contentTypeUID]);
|
||||
const componentToAddUID = 'default.dish';
|
||||
|
||||
const state = initialState
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(['modifiedData', 'contentType'], fromJS(contentType))
|
||||
.setIn(['modifiedData', 'components'], fromJS({}));
|
||||
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
name: 'compoField',
|
||||
component: componentToAddUID,
|
||||
required: true,
|
||||
max: 2,
|
||||
min: 1,
|
||||
},
|
||||
forTarget: 'contentType',
|
||||
targetUid: 'application::address.address',
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: true,
|
||||
};
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'components', componentToAddUID],
|
||||
fromJS(testData.components[componentToAddUID])
|
||||
)
|
||||
.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'compoField'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
|
||||
component: componentToAddUID,
|
||||
required: true,
|
||||
max: 2,
|
||||
min: 1,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should create the component attribute and add the component to the modifiedData.components and its nested components if none of the added components are in the object', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const contentType = get(testData, ['contentTypes', contentTypeUID]);
|
||||
const componentToAddUID = 'default.closingperiod';
|
||||
|
||||
const state = initialState
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(['modifiedData', 'contentType'], fromJS(contentType))
|
||||
.setIn(['modifiedData', 'components'], fromJS({}));
|
||||
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
name: 'compoField',
|
||||
component: componentToAddUID,
|
||||
required: true,
|
||||
max: 2,
|
||||
min: 1,
|
||||
},
|
||||
forTarget: 'contentType',
|
||||
targetUid: 'application::address.address',
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: true,
|
||||
};
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'components', componentToAddUID],
|
||||
fromJS(testData.components[componentToAddUID])
|
||||
)
|
||||
.setIn(
|
||||
['modifiedData', 'components', 'default.dish'],
|
||||
fromJS(testData.components['default.dish'])
|
||||
)
|
||||
.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'compoField'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
component: componentToAddUID,
|
||||
required: true,
|
||||
max: 2,
|
||||
min: 1,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should create the component attribute and add the component to the modifiedData.components and only add the nested components that are not in the modifiedData.components object to keep previous the modifications', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const contentType = get(testData, ['contentTypes', contentTypeUID]);
|
||||
const componentToAddUID = 'default.closingperiod';
|
||||
|
||||
const state = initialState
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(['modifiedData', 'contentType'], fromJS(contentType))
|
||||
.setIn(
|
||||
['modifiedData', 'components', 'default.dish'],
|
||||
fromJS(testData.components['default.dish'])
|
||||
);
|
||||
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
name: 'compoField',
|
||||
component: componentToAddUID,
|
||||
required: true,
|
||||
max: 2,
|
||||
min: 1,
|
||||
},
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: true,
|
||||
};
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'components', componentToAddUID],
|
||||
fromJS(testData.components[componentToAddUID])
|
||||
)
|
||||
|
||||
.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'compoField'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
component: componentToAddUID,
|
||||
required: true,
|
||||
max: 2,
|
||||
min: 1,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should create the component correctly in case of creating the component on the fly', () => {
|
||||
const componentToCreateUID = 'default.new-compo';
|
||||
const componentToCreate = {
|
||||
uid: componentToCreateUID,
|
||||
isTemporary: true,
|
||||
category: 'default',
|
||||
schema: {
|
||||
name: 'newCompo',
|
||||
icon: 'ad',
|
||||
attributes: {},
|
||||
},
|
||||
};
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
name: 'newCompo',
|
||||
type: 'component',
|
||||
repeatable: false,
|
||||
component: componentToCreateUID,
|
||||
},
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
initialAttribute: undefined,
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.setIn(['components', componentToCreateUID], fromJS(componentToCreate))
|
||||
.setIn(
|
||||
['modifiedData', 'components', componentToCreateUID],
|
||||
fromJS(componentToCreate)
|
||||
)
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'newCompo'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
repeatable: false,
|
||||
component: componentToCreateUID,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding a dynamic zone', () => {
|
||||
it('Should create the dynamiczone attribute correctly', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
type: 'dynamiczone',
|
||||
components: [],
|
||||
name: 'dz',
|
||||
},
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
const state = initialState.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'dz'],
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
components: [],
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding a relation with another content type', () => {
|
||||
it('Should add the relation attribute correctly for a content type', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const targetContentTypeUID = 'application::category.category';
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
name: 'categories',
|
||||
nature: 'oneToMany',
|
||||
targetAttribute: 'address',
|
||||
target: targetContentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
)
|
||||
.setIn(['modifiedData', 'components'], fromJS({}));
|
||||
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'categories'],
|
||||
fromJS({
|
||||
nature: 'oneToMany',
|
||||
targetAttribute: 'address',
|
||||
target: targetContentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should add the relation attribute correctly for a component', () => {
|
||||
const componentUID = 'default.dish';
|
||||
const targetContentTypeUID = 'application::category.category';
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
name: 'address',
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: targetContentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
forTarget: 'component',
|
||||
targetUid: componentUID,
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'component'],
|
||||
fromJS(testData.components[componentUID])
|
||||
)
|
||||
.setIn(['modifiedData', 'components'], fromJS({}));
|
||||
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'component', 'schema', 'attributes', 'address'],
|
||||
fromJS({
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: targetContentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should add the relation attribute correctly for a component from the modifiedData.components object', () => {
|
||||
const componentUID = 'default.dish';
|
||||
const targetContentTypeUID = 'application::category.category';
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
attributeToSet: {
|
||||
name: 'address',
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: targetContentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
forTarget: 'components',
|
||||
targetUid: componentUID,
|
||||
initialAttribute: {},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[targetContentTypeUID])
|
||||
)
|
||||
.setIn(
|
||||
['modifiedData', 'components', componentUID],
|
||||
fromJS(testData.components[componentUID])
|
||||
)
|
||||
.setIn(['modifiedData', 'components'], fromJS({}));
|
||||
|
||||
const expected = state.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'components',
|
||||
componentUID,
|
||||
'schema',
|
||||
'attributes',
|
||||
'address',
|
||||
],
|
||||
fromJS({
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: targetContentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding a relation with the same content type', () => {
|
||||
it('Should not create an opposite attribute if the relation is oneWay', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
attributeToSet: {
|
||||
name: 'address',
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'address'],
|
||||
fromJS({
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should not create an opposite attribute if the relation is manyWay', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
attributeToSet: {
|
||||
name: 'address',
|
||||
nature: 'manyWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', 'address'],
|
||||
fromJS({
|
||||
nature: 'manyWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the oneToOne relation correctly and create the opposite attribute', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const name = 'address_left_side';
|
||||
const targetAttribute = 'address_right_side';
|
||||
const columnName = 'left_side';
|
||||
const targetColumnName = 'right_side';
|
||||
const attribute = {
|
||||
nature: 'oneToOne',
|
||||
targetAttribute,
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName,
|
||||
targetColumnName,
|
||||
};
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
attributeToSet: {
|
||||
name,
|
||||
...attribute,
|
||||
},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
const oppositeAttribute = {
|
||||
nature: 'oneToOne',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
targetAttribute: name,
|
||||
dominant: null,
|
||||
columnName: targetColumnName,
|
||||
targetColumnName: columnName,
|
||||
};
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', name],
|
||||
fromJS(attribute)
|
||||
)
|
||||
.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
targetAttribute,
|
||||
],
|
||||
fromJS(oppositeAttribute)
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the oneToMany relation correctly and create the opposite attribute', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const name = 'address_left_side';
|
||||
const targetAttribute = 'address_right_side';
|
||||
const columnName = 'left_side';
|
||||
const targetColumnName = 'right_side';
|
||||
const attribute = {
|
||||
nature: 'oneToMany',
|
||||
targetAttribute,
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName,
|
||||
targetColumnName,
|
||||
};
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
attributeToSet: {
|
||||
name,
|
||||
...attribute,
|
||||
},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
const oppositeAttribute = {
|
||||
nature: 'manyToOne',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
targetAttribute: name,
|
||||
dominant: null,
|
||||
columnName: targetColumnName,
|
||||
targetColumnName: columnName,
|
||||
};
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', name],
|
||||
fromJS(attribute)
|
||||
)
|
||||
.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
targetAttribute,
|
||||
],
|
||||
fromJS(oppositeAttribute)
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the manyToOne relation correctly and create the opposite attribute', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const name = 'address_left_side';
|
||||
const targetAttribute = 'address_right_side';
|
||||
const columnName = 'left_side';
|
||||
const targetColumnName = 'right_side';
|
||||
const attribute = {
|
||||
nature: 'manyToOne',
|
||||
targetAttribute,
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName,
|
||||
targetColumnName,
|
||||
};
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
attributeToSet: {
|
||||
name,
|
||||
...attribute,
|
||||
},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
const oppositeAttribute = {
|
||||
nature: 'oneToMany',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
targetAttribute: name,
|
||||
dominant: null,
|
||||
columnName: targetColumnName,
|
||||
targetColumnName: columnName,
|
||||
};
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', name],
|
||||
fromJS(attribute)
|
||||
)
|
||||
.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
targetAttribute,
|
||||
],
|
||||
fromJS(oppositeAttribute)
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the manyToMany relation correctly and create the opposite attribute', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const name = 'address_left_side';
|
||||
const targetAttribute = 'address_right_side';
|
||||
const columnName = 'left_side';
|
||||
const targetColumnName = 'right_side';
|
||||
const attribute = {
|
||||
nature: 'manyToMany',
|
||||
targetAttribute,
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: true,
|
||||
columnName,
|
||||
targetColumnName,
|
||||
};
|
||||
const action = {
|
||||
type: 'ADD_ATTRIBUTE',
|
||||
forTarget: 'contentType',
|
||||
targetUid: contentTypeUID,
|
||||
attributeToSet: {
|
||||
name,
|
||||
...attribute,
|
||||
},
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
const oppositeAttribute = {
|
||||
nature: 'manyToMany',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
targetAttribute: name,
|
||||
dominant: false,
|
||||
columnName: targetColumnName,
|
||||
targetColumnName: columnName,
|
||||
};
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('components', fromJS(testData.components))
|
||||
.set('initialComponents', fromJS(testData.components))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
);
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'contentType', 'schema', 'attributes', name],
|
||||
fromJS(attribute)
|
||||
)
|
||||
.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
targetAttribute,
|
||||
],
|
||||
fromJS(oppositeAttribute)
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,945 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import { get } from 'lodash';
|
||||
import reducer, { initialState } from '../reducer';
|
||||
import testData from './data';
|
||||
|
||||
describe('CTB | containers | DataManagerProvider | reducer | basics actions ', () => {
|
||||
it('Should return the initial state', () => {
|
||||
expect(reducer(initialState, { type: 'TEST' })).toEqual(initialState);
|
||||
});
|
||||
|
||||
describe('ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE', () => {
|
||||
it('should add the created component to the dynamic zone', () => {
|
||||
const createdComponent = fromJS({
|
||||
uid: 'default.test',
|
||||
category: 'default',
|
||||
isTemporary: true,
|
||||
schema: {
|
||||
icon: 'book',
|
||||
name: 'test',
|
||||
collectionName: '',
|
||||
attributes: {},
|
||||
},
|
||||
});
|
||||
const components = fromJS({
|
||||
'default.test': createdComponent,
|
||||
'default.other': {
|
||||
uid: 'default.other',
|
||||
category: 'default',
|
||||
|
||||
schema: {
|
||||
icon: 'book',
|
||||
name: 'test',
|
||||
collectionName: '',
|
||||
attributes: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
const contentType = fromJS({
|
||||
uid: 'application::test',
|
||||
schema: {
|
||||
name: 'test',
|
||||
attributes: {
|
||||
dz: {
|
||||
type: 'dynamiczone',
|
||||
components: ['default.other'],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const state = initialState
|
||||
.setIn(['components'], components)
|
||||
.setIn(['modifiedData', 'components'], components)
|
||||
|
||||
.setIn(['modifiedData', 'contentType'], contentType);
|
||||
|
||||
const expected = state.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
'dz',
|
||||
'components',
|
||||
],
|
||||
fromJS(['default.other', 'default.test'])
|
||||
);
|
||||
|
||||
expect(
|
||||
reducer(state, {
|
||||
type: 'ADD_CREATED_COMPONENT_TO_DYNAMIC_ZONE',
|
||||
dynamicZoneTarget: 'dz',
|
||||
componentsToAdd: ['default.test'],
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CANCEL_CHANGES', () => {
|
||||
it('Should set the modifiedData and the components object with the initial ones', () => {
|
||||
const state = fromJS({
|
||||
components: {
|
||||
test: {
|
||||
something: true,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
initialComponents: {
|
||||
test: {
|
||||
something: false,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
modifiedData: {
|
||||
components: {
|
||||
test: {
|
||||
something: true,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
contentType: {
|
||||
uid: 'something',
|
||||
name: 'test',
|
||||
},
|
||||
},
|
||||
initialData: {
|
||||
components: {
|
||||
test: {
|
||||
something: false,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
contentType: {
|
||||
uid: 'something',
|
||||
name: 'something',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const expected = fromJS({
|
||||
components: {
|
||||
test: {
|
||||
something: false,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
initialComponents: {
|
||||
test: {
|
||||
something: false,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
modifiedData: {
|
||||
components: {
|
||||
test: {
|
||||
something: false,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
contentType: {
|
||||
uid: 'something',
|
||||
name: 'something',
|
||||
},
|
||||
},
|
||||
initialData: {
|
||||
components: {
|
||||
test: {
|
||||
something: false,
|
||||
},
|
||||
other: {
|
||||
something: false,
|
||||
},
|
||||
},
|
||||
contentType: {
|
||||
uid: 'something',
|
||||
name: 'something',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(reducer(state, { type: 'CANCEL_CHANGES' })).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CHANGE_DYNAMIC_ZONE_COMPONENTS', () => {
|
||||
it('Should add the component to the dz field and to the modifiedData.components if the added component is not already in the modifiedData.components', () => {
|
||||
const componentUID = 'default.openingtimes';
|
||||
const component = get(testData, ['components', componentUID]);
|
||||
const contentType = fromJS(
|
||||
testData.contentTypes['application::address.address']
|
||||
).setIn(
|
||||
['schema', 'attributes', 'dz'],
|
||||
fromJS({ type: 'dynamiczone', components: ['default.openingtimes'] })
|
||||
);
|
||||
const state = initialState
|
||||
.setIn(['components'], fromJS(testData.components))
|
||||
.setIn(['modifiedData', 'components', componentUID], fromJS(component))
|
||||
.setIn(['modifiedData', 'contentType'], contentType);
|
||||
|
||||
const expected = state
|
||||
.setIn(
|
||||
['modifiedData', 'components', 'default.dish'],
|
||||
fromJS(get(testData, ['components', 'default.dish']))
|
||||
)
|
||||
.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
'dz',
|
||||
'components',
|
||||
],
|
||||
fromJS([componentUID, 'default.dish'])
|
||||
);
|
||||
|
||||
expect(
|
||||
reducer(state, {
|
||||
type: 'CHANGE_DYNAMIC_ZONE_COMPONENTS',
|
||||
dynamicZoneTarget: 'dz',
|
||||
newComponents: ['default.dish'],
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should add the component to the dz field and not to the modifiedData.components if the added component is already in the modifiedData.components', () => {
|
||||
const componentUID = 'default.openingtimes';
|
||||
const component = get(testData, ['components', componentUID]);
|
||||
const contentType = fromJS(
|
||||
testData.contentTypes['application::address.address']
|
||||
).setIn(
|
||||
['schema', 'attributes', 'dz'],
|
||||
fromJS({ type: 'dynamiczone', components: ['default.openingtimes'] })
|
||||
);
|
||||
const state = initialState
|
||||
.setIn(['components'], fromJS(testData.components))
|
||||
.setIn(['modifiedData', 'components', componentUID], fromJS(component))
|
||||
.setIn(
|
||||
['modifiedData', 'components', 'default.dish'],
|
||||
fromJS(get(testData, ['components', 'default.dish']))
|
||||
)
|
||||
.setIn(['modifiedData', 'contentType'], contentType);
|
||||
|
||||
const expected = state.setIn(
|
||||
[
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
'dz',
|
||||
'components',
|
||||
],
|
||||
fromJS([componentUID, 'default.dish'])
|
||||
);
|
||||
|
||||
expect(
|
||||
reducer(state, {
|
||||
type: 'CHANGE_DYNAMIC_ZONE_COMPONENTS',
|
||||
dynamicZoneTarget: 'dz',
|
||||
newComponents: ['default.dish'],
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CREATE_COMPONENT_SCHEMA', () => {
|
||||
it('Should add the created component schema to the components object when creating a component using the left menu link', () => {
|
||||
const action = {
|
||||
type: 'CREATE_COMPONENT_SCHEMA',
|
||||
data: { name: 'new component', icon: 'arrow-alt-circle-down' },
|
||||
componentCategory: 'test',
|
||||
schemaType: 'component',
|
||||
uid: 'test.new-component',
|
||||
shouldAddComponentToData: false,
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.setIn(['components', fromJS(testData.components)])
|
||||
.setIn(['initialComponents', fromJS(testData.components)]);
|
||||
|
||||
const expected = state.setIn(
|
||||
['components', action.uid],
|
||||
fromJS({
|
||||
uid: action.uid,
|
||||
isTemporary: true,
|
||||
category: action.componentCategory,
|
||||
schema: {
|
||||
...action.data,
|
||||
attributes: {},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should add the created component schema to the components object, create the attribute and also add the created component to modifiedData.components when using the add attribute modal', () => {
|
||||
const action = {
|
||||
type: 'CREATE_COMPONENT_SCHEMA',
|
||||
data: { name: 'new component', icon: 'arrow-alt-circle-down' },
|
||||
componentCategory: 'test',
|
||||
schemaType: 'component',
|
||||
uid: 'test.new-component',
|
||||
shouldAddComponentToData: true,
|
||||
};
|
||||
const compoToCreate = {
|
||||
uid: action.uid,
|
||||
isTemporary: true,
|
||||
category: action.componentCategory,
|
||||
schema: {
|
||||
...action.data,
|
||||
attributes: {},
|
||||
},
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.setIn(['components', fromJS(testData.components)])
|
||||
.setIn(['initialComponents', fromJS(testData.components)]);
|
||||
|
||||
const expected = state
|
||||
.setIn(['components', action.uid], fromJS(compoToCreate))
|
||||
.setIn(
|
||||
['modifiedData', 'components', action.uid],
|
||||
fromJS(compoToCreate)
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CREATE_SCHEMA', () => {
|
||||
it('Should create a content type schema correctly', () => {
|
||||
const uid = 'application::test';
|
||||
const data = {
|
||||
collectionName: 'test',
|
||||
name: 'test',
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['contentTypes', uid],
|
||||
fromJS({
|
||||
uid,
|
||||
isTemporary: true,
|
||||
schema: {
|
||||
collectionName: data.collectionName,
|
||||
name: data.name,
|
||||
attributes: {},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
expect(
|
||||
reducer(initialState, { type: 'CREATE_SCHEMA', uid, data })
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE_NOT_SAVED_TYPE', () => {
|
||||
it('Should reset the components and and contentTypes object', () => {
|
||||
const state = initialState
|
||||
.setIn(['components'], fromJS({ foo: {}, bar: {} }))
|
||||
.setIn(['initialComponents'], fromJS({ foo: {} }))
|
||||
.setIn(['contentTypes'], fromJS({ baz: {}, bat: {} }))
|
||||
.setIn(['initialContentTypes'], fromJS({ baz: {} }));
|
||||
|
||||
const expected = initialState
|
||||
.setIn(['components'], fromJS({ foo: {} }))
|
||||
.setIn(['initialComponents'], fromJS({ foo: {} }))
|
||||
.setIn(['contentTypes'], fromJS({ baz: {} }))
|
||||
.setIn(['initialContentTypes'], fromJS({ baz: {} }));
|
||||
|
||||
expect(reducer(state, { type: 'DELETE_NOT_SAVED_TYPE' })).toEqual(
|
||||
expected
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET_DATA_SUCCEEDED', () => {
|
||||
const components = {
|
||||
'default.test': {
|
||||
uid: 'default.test',
|
||||
category: 'default',
|
||||
schema: {
|
||||
attributes: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
const contentTypes = {
|
||||
'application::test.test': {
|
||||
uid: 'application::test.test',
|
||||
schema: {
|
||||
attributes: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
const expected = initialState
|
||||
.set('components', fromJS(components))
|
||||
.set('contentTypes', fromJS(contentTypes))
|
||||
.set('initialContentTypes', fromJS(contentTypes))
|
||||
.set('initialComponents', fromJS(components))
|
||||
.set('isLoading', false);
|
||||
|
||||
expect(
|
||||
reducer(initialState, {
|
||||
type: 'GET_DATA_SUCCEEDED',
|
||||
components,
|
||||
contentTypes,
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
|
||||
describe('RELOAD_PLUGIN', () => {
|
||||
it('Should return the initial state constant', () => {
|
||||
expect(
|
||||
reducer(initialState.setIn(['components', 'foo'], {}), {
|
||||
type: 'RELOAD_PLUGIN',
|
||||
})
|
||||
).toEqual(initialState);
|
||||
});
|
||||
});
|
||||
|
||||
describe('REMOVE_COMPONENT_FROM_DYNAMIC_ZONE', () => {
|
||||
it('Should remove a component from a dynamic zone', () => {
|
||||
const state = fromJS({
|
||||
components: {
|
||||
'default.openingtimes': {
|
||||
uid: 'default.openingtimes',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'openingtimes',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_openingtimes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'default.dish': {
|
||||
uid: 'default.dish',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'dish',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_dishes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
modifiedData: {
|
||||
components: {
|
||||
'default.dish': {
|
||||
uid: 'default.dish',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'dish',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_dishes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'default.openingtimes': {
|
||||
uid: 'default.openingtimes',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'openingtimes',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_openingtimes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
contentType: {
|
||||
uid: 'application::address.address',
|
||||
schema: {
|
||||
name: 'address',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'addresses',
|
||||
attributes: {
|
||||
geolocation: {
|
||||
type: 'json',
|
||||
required: true,
|
||||
},
|
||||
city: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
postal_coder: {
|
||||
type: 'string',
|
||||
},
|
||||
category: {
|
||||
model: 'category',
|
||||
},
|
||||
cover: {
|
||||
model: 'file',
|
||||
via: 'related',
|
||||
plugin: 'upload',
|
||||
required: false,
|
||||
},
|
||||
images: {
|
||||
collection: 'file',
|
||||
via: 'related',
|
||||
plugin: 'upload',
|
||||
required: false,
|
||||
},
|
||||
full_name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
dz: {
|
||||
type: 'dynamiczone',
|
||||
components: ['default.openingtimes', 'default.dish'],
|
||||
},
|
||||
otherDz: {
|
||||
type: 'dynamiczone',
|
||||
components: ['default.openingtimes', 'default.dish'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const expected = fromJS({
|
||||
components: {
|
||||
'default.openingtimes': {
|
||||
uid: 'default.openingtimes',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'openingtimes',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_openingtimes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'default.dish': {
|
||||
uid: 'default.dish',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'dish',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_dishes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
modifiedData: {
|
||||
components: {
|
||||
'default.dish': {
|
||||
uid: 'default.dish',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'dish',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_dishes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'default.openingtimes': {
|
||||
uid: 'default.openingtimes',
|
||||
category: 'default',
|
||||
schema: {
|
||||
icon: 'calendar',
|
||||
name: 'openingtimes',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'components_openingtimes',
|
||||
attributes: {
|
||||
label: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
default: 'something',
|
||||
},
|
||||
time: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
contentType: {
|
||||
uid: 'application::address.address',
|
||||
schema: {
|
||||
name: 'address',
|
||||
description: '',
|
||||
connection: 'default',
|
||||
collectionName: 'addresses',
|
||||
attributes: {
|
||||
geolocation: {
|
||||
type: 'json',
|
||||
required: true,
|
||||
},
|
||||
city: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
postal_coder: {
|
||||
type: 'string',
|
||||
},
|
||||
category: {
|
||||
model: 'category',
|
||||
},
|
||||
cover: {
|
||||
model: 'file',
|
||||
via: 'related',
|
||||
plugin: 'upload',
|
||||
required: false,
|
||||
},
|
||||
images: {
|
||||
collection: 'file',
|
||||
via: 'related',
|
||||
plugin: 'upload',
|
||||
required: false,
|
||||
},
|
||||
full_name: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
},
|
||||
dz: {
|
||||
type: 'dynamiczone',
|
||||
components: ['default.openingtimes'],
|
||||
},
|
||||
otherDz: {
|
||||
type: 'dynamiczone',
|
||||
components: ['default.openingtimes', 'default.dish'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
reducer(state, {
|
||||
type: 'REMOVE_COMPONENT_FROM_DYNAMIC_ZONE',
|
||||
dzName: 'dz',
|
||||
componentToRemoveIndex: 1,
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('REMOVE_FIELD_FROM_DISPLAYED_COMPONENT', () => {
|
||||
it('Should remove the selected field', () => {
|
||||
const state = fromJS({
|
||||
modifiedData: {
|
||||
components: {
|
||||
'default.test': {
|
||||
schema: {
|
||||
attributes: {
|
||||
text: {
|
||||
type: 'text',
|
||||
},
|
||||
other: {
|
||||
type: 'string',
|
||||
},
|
||||
last: {
|
||||
type: 'integer',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const expected = fromJS({
|
||||
modifiedData: {
|
||||
components: {
|
||||
'default.test': {
|
||||
schema: {
|
||||
attributes: {
|
||||
text: {
|
||||
type: 'text',
|
||||
},
|
||||
last: {
|
||||
type: 'integer',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
reducer(state, {
|
||||
type: 'REMOVE_FIELD_FROM_DISPLAYED_COMPONENT',
|
||||
componentUid: 'default.test',
|
||||
attributeToRemoveName: 'other',
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_MODIFIED_DATA', () => {
|
||||
it('Should set the modifiedData object correctly if the user did create a new type', () => {
|
||||
const schemaToSet = fromJS({
|
||||
components: {},
|
||||
contentType: {
|
||||
uid: 'test',
|
||||
},
|
||||
});
|
||||
const expected = initialState
|
||||
.set('modifiedData', schemaToSet)
|
||||
.set('initialData', schemaToSet)
|
||||
.set('isLoadingForDataToBeSet', false);
|
||||
|
||||
expect(
|
||||
reducer(initialState, {
|
||||
type: 'SET_MODIFIED_DATA',
|
||||
schemaToSet,
|
||||
hasJustCreatedSchema: true,
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the modifiedData object correctly if the user did not create a new type', () => {
|
||||
const schemaToSet = fromJS({
|
||||
components: {},
|
||||
contentType: {
|
||||
uid: 'test',
|
||||
},
|
||||
});
|
||||
const expected = initialState
|
||||
.set('modifiedData', schemaToSet)
|
||||
.set('initialData', schemaToSet)
|
||||
.set('isLoadingForDataToBeSet', false);
|
||||
|
||||
expect(
|
||||
reducer(initialState, {
|
||||
type: 'SET_MODIFIED_DATA',
|
||||
schemaToSet,
|
||||
hasJustCreatedSchema: false,
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('UPDATE_SCHEMA', () => {
|
||||
it('Should update the modified data correctly if the schemaType is a content type', () => {
|
||||
const data = {
|
||||
name: 'test1',
|
||||
collectionName: 'newTest',
|
||||
};
|
||||
const state = fromJS({
|
||||
modifiedData: {
|
||||
components: {},
|
||||
contentType: {
|
||||
uid: 'test',
|
||||
schema: {
|
||||
name: 'test',
|
||||
collectionName: 'test',
|
||||
attributes: {
|
||||
something: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const expected = fromJS({
|
||||
modifiedData: {
|
||||
components: {},
|
||||
contentType: {
|
||||
uid: 'test',
|
||||
schema: {
|
||||
name: 'test1',
|
||||
collectionName: 'newTest',
|
||||
attributes: {
|
||||
something: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
reducer(state, {
|
||||
type: 'UPDATE_SCHEMA',
|
||||
data,
|
||||
schemaType: 'contentType',
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should update the modified data correctly if the schemaType is a component', () => {
|
||||
const data = {
|
||||
name: 'newTest',
|
||||
collectionName: 'newTest',
|
||||
category: 'test',
|
||||
icon: 'test',
|
||||
};
|
||||
const state = fromJS({
|
||||
components: {
|
||||
test: {
|
||||
uid: 'test',
|
||||
category: 'default',
|
||||
schema: {
|
||||
name: 'test',
|
||||
icon: 'book',
|
||||
collectionName: 'components_tests',
|
||||
attributes: {
|
||||
something: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
modifiedData: {
|
||||
components: {},
|
||||
component: {
|
||||
uid: 'test',
|
||||
category: 'default',
|
||||
schema: {
|
||||
name: 'test',
|
||||
icon: 'book',
|
||||
collectionName: 'components_tests',
|
||||
attributes: {
|
||||
something: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const expected = fromJS({
|
||||
components: {
|
||||
test: {
|
||||
uid: 'test',
|
||||
category: 'test',
|
||||
schema: {
|
||||
name: 'newTest',
|
||||
icon: 'test',
|
||||
collectionName: 'newTest',
|
||||
attributes: {
|
||||
something: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
modifiedData: {
|
||||
components: {},
|
||||
component: {
|
||||
uid: 'test',
|
||||
category: 'test',
|
||||
schema: {
|
||||
name: 'newTest',
|
||||
icon: 'test',
|
||||
collectionName: 'newTest',
|
||||
attributes: {
|
||||
something: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
reducer(state, {
|
||||
type: 'UPDATE_SCHEMA',
|
||||
data,
|
||||
schemaType: 'component',
|
||||
uid: 'test',
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,274 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import reducer, { initialState } from '../reducer';
|
||||
import testData from './data';
|
||||
|
||||
describe('CTB | containers | DataManagerProvider | reducer | REMOVE_FIELD', () => {
|
||||
describe('Removing a field that is not a relation', () => {
|
||||
it('Should remove the attribute correctly from the content type', () => {
|
||||
const contentTypeUID = 'application::address.address';
|
||||
const attributeToRemoveName = 'city';
|
||||
const action = {
|
||||
type: 'REMOVE_FIELD',
|
||||
mainDataKey: 'contentType',
|
||||
attributeToRemoveName,
|
||||
componentUid: '',
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
)
|
||||
.setIn(['modifiedData', 'components'], fromJS({}));
|
||||
|
||||
const expected = state.removeIn([
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
attributeToRemoveName,
|
||||
]);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Removing a relation attribute with another content type', () => {
|
||||
it('Should remove the attribute correctly if the relation is made with another content type', () => {
|
||||
const contentTypeUID = 'application::menusection.menusection';
|
||||
const attributeToRemoveName = 'menu';
|
||||
const action = {
|
||||
type: 'REMOVE_FIELD',
|
||||
mainDataKey: 'contentType',
|
||||
attributeToRemoveName,
|
||||
componentUid: '',
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.set('contentTypes', fromJS(testData.contentTypes))
|
||||
.set('initialContentTypes', fromJS(testData.contentTypes))
|
||||
.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(testData.contentTypes[contentTypeUID])
|
||||
)
|
||||
.setIn(['modifiedData', 'components'], fromJS({}));
|
||||
|
||||
const expected = state.removeIn([
|
||||
'modifiedData',
|
||||
'contentType',
|
||||
'schema',
|
||||
'attributes',
|
||||
attributeToRemoveName,
|
||||
]);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Removing a relation attribute with the same content type', () => {
|
||||
it('Should handle the removal of the one side (oneWay or manyWay) nature correctly', () => {
|
||||
const contentTypeUID = 'application::dummy.dummy';
|
||||
const action = {
|
||||
type: 'REMOVE_FIELD',
|
||||
mainDataKey: 'contentType',
|
||||
attributeToRemoveName: 'one_way_attr',
|
||||
componentUid: '',
|
||||
};
|
||||
const contentType = {
|
||||
uid: contentTypeUID,
|
||||
schema: {
|
||||
name: 'dummy',
|
||||
attributes: {
|
||||
name: { type: 'string' },
|
||||
one_way_attr: {
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
many_way_attrs: {
|
||||
nature: 'manyWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
one_to_many_left: {
|
||||
nature: 'oneToMany',
|
||||
targetAttribute: 'one_to_many_right',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
one_to_many_right: {
|
||||
nature: 'manyToOne',
|
||||
target: 'application::dummy.dummy',
|
||||
unique: false,
|
||||
dominant: null,
|
||||
targetAttribute: 'one_to_many_left',
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const expectedContentType = {
|
||||
uid: contentTypeUID,
|
||||
schema: {
|
||||
name: 'dummy',
|
||||
attributes: {
|
||||
name: { type: 'string' },
|
||||
many_way_attrs: {
|
||||
nature: 'manyWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
one_to_many_left: {
|
||||
nature: 'oneToMany',
|
||||
targetAttribute: 'one_to_many_right',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
one_to_many_right: {
|
||||
nature: 'manyToOne',
|
||||
target: 'application::dummy.dummy',
|
||||
unique: false,
|
||||
dominant: null,
|
||||
targetAttribute: 'one_to_many_left',
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.setIn(['contentTypes', contentTypeUID], fromJS(contentType))
|
||||
.setIn(['modifiedData', 'contentType'], fromJS(contentType));
|
||||
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(expectedContentType)
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the removal of the two sides (oneToOne, oneToMany, manyToOne, manyToMany) nature correctly', () => {
|
||||
const contentTypeUID = 'application::dummy.dummy';
|
||||
const action = {
|
||||
type: 'REMOVE_FIELD',
|
||||
mainDataKey: 'contentType',
|
||||
attributeToRemoveName: 'one_to_many_left',
|
||||
componentUid: '',
|
||||
};
|
||||
const contentType = {
|
||||
uid: contentTypeUID,
|
||||
schema: {
|
||||
name: 'dummy',
|
||||
attributes: {
|
||||
name: { type: 'string' },
|
||||
one_way_attr: {
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
many_way_attrs: {
|
||||
nature: 'manyWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
one_to_many_left: {
|
||||
nature: 'oneToMany',
|
||||
targetAttribute: 'one_to_many_right',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
one_to_many_right: {
|
||||
nature: 'manyToOne',
|
||||
target: 'application::dummy.dummy',
|
||||
unique: false,
|
||||
dominant: null,
|
||||
targetAttribute: 'one_to_many_left',
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const expectedContentType = {
|
||||
uid: contentTypeUID,
|
||||
schema: {
|
||||
name: 'dummy',
|
||||
attributes: {
|
||||
name: { type: 'string' },
|
||||
one_way_attr: {
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
many_way_attrs: {
|
||||
nature: 'manyWay',
|
||||
targetAttribute: '-',
|
||||
target: contentTypeUID,
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const state = initialState
|
||||
.setIn(['contentTypes', contentTypeUID], fromJS(contentType))
|
||||
.setIn(['modifiedData', 'contentType'], fromJS(contentType));
|
||||
|
||||
const expected = state.setIn(
|
||||
['modifiedData', 'contentType'],
|
||||
fromJS(expectedContentType)
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
expect(
|
||||
reducer(state, {
|
||||
...action,
|
||||
attributeToRemoveName: 'one_to_many_right',
|
||||
})
|
||||
).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,4 +1,4 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import { fromJS, List } from 'immutable';
|
||||
import pluralize from 'pluralize';
|
||||
import { snakeCase } from 'lodash';
|
||||
import makeUnique from '../../utils/makeUnique';
|
||||
@ -22,15 +22,17 @@ const reducer = (state, action) => {
|
||||
const { name, components, shouldAddComponents } = action;
|
||||
|
||||
return state.updateIn(['modifiedData', name], list => {
|
||||
let updatedList = list;
|
||||
|
||||
if (shouldAddComponents) {
|
||||
return makeUnique(list.concat(components));
|
||||
updatedList = list.concat(components);
|
||||
} else {
|
||||
updatedList = list.filter(comp => {
|
||||
return components.indexOf(comp) === -1;
|
||||
});
|
||||
}
|
||||
|
||||
return makeUnique(
|
||||
list.filter(comp => {
|
||||
return components.indexOf(comp) === -1;
|
||||
})
|
||||
);
|
||||
return List(makeUnique(updatedList.toJS()));
|
||||
});
|
||||
}
|
||||
case 'ON_CHANGE':
|
||||
|
||||
@ -0,0 +1,587 @@
|
||||
import { fromJS } from 'immutable';
|
||||
import reducer, { initialState } from '../reducer';
|
||||
|
||||
describe('CTB | containers | FormModal | reducer | actions', () => {
|
||||
describe('ADD_COMPONENTS_TO_DYNAMIC_ZONE', () => {
|
||||
it('Should add the components correctly', () => {
|
||||
const action = {
|
||||
type: 'ADD_COMPONENTS_TO_DYNAMIC_ZONE',
|
||||
components: ['default.test', 'default.test2', 'default.test3'],
|
||||
shouldAddComponents: true,
|
||||
name: 'components',
|
||||
};
|
||||
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
name: 'dz',
|
||||
components: ['default.test'],
|
||||
})
|
||||
);
|
||||
const expected = state.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
name: 'dz',
|
||||
components: ['default.test', 'default.test2', 'default.test3'],
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should remove the components correctly', () => {
|
||||
const action = {
|
||||
type: 'ADD_COMPONENTS_TO_DYNAMIC_ZONE',
|
||||
components: ['default.test2', 'default.test3'],
|
||||
shouldAddComponents: false,
|
||||
name: 'components',
|
||||
};
|
||||
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
name: 'dz',
|
||||
components: ['default.test', 'default.test2', 'default.test3'],
|
||||
})
|
||||
);
|
||||
const expected = state.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
name: 'dz',
|
||||
components: ['default.test'],
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ON_CHANGE', () => {
|
||||
it('Should update the modifiedData object correctly if it is not relation', () => {
|
||||
const action = {
|
||||
type: 'ON_CHANGE',
|
||||
keys: ['name'],
|
||||
value: 'test',
|
||||
};
|
||||
const state = initialState.setIn(['modifiedData', 'type'], 'string');
|
||||
const expected = state.setIn(['modifiedData', 'name'], 'test');
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the nature change correctly from oneWay to manyToMany', () => {
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
name: 'category test',
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: 'application::category.category',
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
const action = {
|
||||
type: 'ON_CHANGE',
|
||||
keys: ['nature'],
|
||||
value: 'manyToMany',
|
||||
targetContentType: 'application::category.category',
|
||||
oneThatIsCreatingARelationWithAnother: 'address',
|
||||
};
|
||||
const expected = state
|
||||
.setIn(['modifiedData', 'nature'], 'manyToMany')
|
||||
.setIn(['modifiedData', 'dominant'], true)
|
||||
.setIn(['modifiedData', 'name'], 'category_tests')
|
||||
.setIn(['modifiedData', 'targetAttribute'], 'addresses');
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the nature change correctly from manyToMany to oneWay', () => {
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
name: 'category_tests',
|
||||
nature: 'manyToMany',
|
||||
targetAttribute: 'addresses',
|
||||
target: 'application::category.category',
|
||||
unique: false,
|
||||
dominant: true,
|
||||
columnName: null,
|
||||
targetColumnName: 'test',
|
||||
})
|
||||
);
|
||||
const action = {
|
||||
type: 'ON_CHANGE',
|
||||
keys: ['nature'],
|
||||
value: 'oneWay',
|
||||
targetContentType: 'application::category.category',
|
||||
oneThatIsCreatingARelationWithAnother: 'address',
|
||||
};
|
||||
const expected = state
|
||||
.setIn(['modifiedData', 'nature'], 'oneWay')
|
||||
.setIn(['modifiedData', 'dominant'], null)
|
||||
.setIn(['modifiedData', 'name'], 'category_test')
|
||||
.setIn(['modifiedData', 'targetAttribute'], '-')
|
||||
.setIn(['modifiedData', 'targetColumnName'], null);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the nature change correctly from oneToOne to oneToMany', () => {
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
name: 'category_test',
|
||||
nature: 'oneToOne',
|
||||
targetAttribute: 'address',
|
||||
target: 'application::category.category',
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: 'test',
|
||||
})
|
||||
);
|
||||
const action = {
|
||||
type: 'ON_CHANGE',
|
||||
keys: ['nature'],
|
||||
value: 'oneToMany',
|
||||
targetContentType: 'application::category.category',
|
||||
oneThatIsCreatingARelationWithAnother: 'address',
|
||||
};
|
||||
const expected = state
|
||||
.setIn(['modifiedData', 'nature'], 'oneToMany')
|
||||
.setIn(['modifiedData', 'name'], 'category_tests');
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the target change correctly for a one side relation (oneWay, manyWay)', () => {
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
name: 'category test',
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: 'application::category.category',
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
const action = {
|
||||
type: 'ON_CHANGE',
|
||||
keys: ['target'],
|
||||
value: 'application::address.address',
|
||||
oneThatIsCreatingARelationWithAnother: 'address',
|
||||
selectedContentTypeFriendlyName: 'address',
|
||||
};
|
||||
const expected = state
|
||||
.setIn(['modifiedData', 'target'], 'application::address.address')
|
||||
.setIn(['modifiedData', 'name'], 'address');
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should handle the target change correctly for the manyToMany relation', () => {
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
name: 'categories',
|
||||
nature: 'manyToMany',
|
||||
targetAttribute: 'addresses',
|
||||
target: 'application::category.category',
|
||||
unique: false,
|
||||
dominant: true,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
const action = {
|
||||
type: 'ON_CHANGE',
|
||||
keys: ['target'],
|
||||
value: 'application::country.country',
|
||||
oneThatIsCreatingARelationWithAnother: 'address',
|
||||
selectedContentTypeFriendlyName: 'country',
|
||||
};
|
||||
const expected = state
|
||||
.setIn(['modifiedData', 'target'], 'application::country.country')
|
||||
.setIn(['modifiedData', 'name'], 'countries');
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('RESET_PROPS', () => {
|
||||
it('Should return the initialState', () => {
|
||||
const state = initialState.setIn(['modifiedData'], 'test');
|
||||
const action = { type: 'RESET_PROPS' };
|
||||
|
||||
expect(reducer(state, action)).toEqual(initialState);
|
||||
});
|
||||
});
|
||||
|
||||
describe('RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO', () => {
|
||||
it('Should reset the state and update the modifiedData object with the component field basic schema', () => {
|
||||
const action = {
|
||||
type: 'RESET_PROPS_AND_SET_FORM_FOR_ADDING_AN_EXISTING_COMPO',
|
||||
};
|
||||
const state = initialState.setIn(['modifiedData'], 'test');
|
||||
const expected = state.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({ type: 'component', repeatable: true })
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('RESET_PROPS_AND_SAVE_CURRENT_DATA', () => {
|
||||
it('Should reset the state and update the modifiedData and componentToCreate objects correctly', () => {
|
||||
const action = { type: 'RESET_PROPS_AND_SAVE_CURRENT_DATA' };
|
||||
|
||||
const state = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
createComponent: true,
|
||||
componentToCreate: {
|
||||
type: 'component',
|
||||
name: 'compo',
|
||||
icon: 'air-freshener',
|
||||
category: 'default',
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const expected = initialState
|
||||
.set(
|
||||
'componentToCreate',
|
||||
fromJS({
|
||||
type: 'component',
|
||||
name: 'compo',
|
||||
icon: 'air-freshener',
|
||||
category: 'default',
|
||||
})
|
||||
)
|
||||
.set(
|
||||
'modifiedData',
|
||||
fromJS({
|
||||
name: 'compo',
|
||||
type: 'component',
|
||||
repeatable: false,
|
||||
component: 'default.compo',
|
||||
})
|
||||
)
|
||||
.set('isCreatingComponentWhileAddingAField', true);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('RESET_PROPS_AND_SET_THE_FORM_FOR_ADDING_A_COMPO_TO_A_DZ', () => {
|
||||
it('Should reset the state and prepare the form for adding or creating a component to a dynamic zone', () => {
|
||||
const action = {
|
||||
type: 'RESET_PROPS_AND_SET_THE_FORM_FOR_ADDING_A_COMPO_TO_A_DZ',
|
||||
};
|
||||
|
||||
const state = initialState.set('initialData', 'test').set(
|
||||
'modifiedData',
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
components: [],
|
||||
name: 'dz',
|
||||
})
|
||||
);
|
||||
const expected = initialState.set(
|
||||
'modifiedData',
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
components: [],
|
||||
name: 'dz',
|
||||
createComponent: true,
|
||||
componentToCreate: fromJS({ type: 'component' }),
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(state, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_DATA_TO_EDIT', () => {
|
||||
it('Should set the state correctly', () => {
|
||||
const action = {
|
||||
type: 'SET_DATA_TO_EDIT',
|
||||
data: {
|
||||
test: true,
|
||||
},
|
||||
};
|
||||
const expected = initialState
|
||||
.set('modifiedData', fromJS(action.data))
|
||||
.set('initialData', fromJS(action.data));
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_ATTRIBUTE_DATA_SCHEMA', () => {
|
||||
it('Should handle the edition correcty', () => {
|
||||
const expected = initialState
|
||||
.setIn(['modifiedData'], fromJS({ test: true }))
|
||||
.setIn(['initialData'], fromJS({ test: true }));
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
isEditing: true,
|
||||
modifiedDataToSetForEditing: {
|
||||
test: true,
|
||||
},
|
||||
};
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a component in step 1', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'component',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: '1',
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
createComponent: true,
|
||||
componentToCreate: { type: 'component' },
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a component in step 2', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'component',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: '2',
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'component',
|
||||
repeatable: true,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a dynamiczone', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'dynamiczone',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: '2',
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'dynamiczone',
|
||||
components: [],
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a text', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'text',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: null,
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({
|
||||
type: 'string',
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a number', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'number',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: null,
|
||||
};
|
||||
const expected = initialState.setIn(['modifiedData'], fromJS({}));
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a date', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'date',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: null,
|
||||
};
|
||||
const expected = initialState.setIn(['modifiedData'], fromJS({}));
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a media', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'media',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: null,
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({ type: 'media', multiple: true })
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for an enumeration', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'enumeration',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: null,
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({ type: 'enumeration', enum: [] })
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for a relation', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'relation',
|
||||
nameToSetForRelation: 'address test',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null, targetAttribute: '-' },
|
||||
step: null,
|
||||
};
|
||||
const expected = initialState.set(
|
||||
'modifiedData',
|
||||
fromJS({
|
||||
name: 'address_test',
|
||||
nature: 'oneWay',
|
||||
targetAttribute: '-',
|
||||
target: 'application::address.address',
|
||||
unique: false,
|
||||
dominant: null,
|
||||
columnName: null,
|
||||
targetColumnName: null,
|
||||
})
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('Should set the state correctly for the other cases', () => {
|
||||
const action = {
|
||||
type: 'SET_ATTRIBUTE_DATA_SCHEMA',
|
||||
attributeType: 'json',
|
||||
nameToSetForRelation: 'address',
|
||||
targetUid: 'application::address.address',
|
||||
isEditing: false,
|
||||
modifiedDataToSetForEditing: { name: null },
|
||||
step: null,
|
||||
};
|
||||
const expected = initialState.setIn(
|
||||
['modifiedData'],
|
||||
fromJS({ type: 'json', default: null })
|
||||
);
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_DYNAMIC_ZONE_DATA_SCHEMA', () => {
|
||||
it('Should set the dynamic zone schema correctly', () => {
|
||||
const action = {
|
||||
type: 'SET_DYNAMIC_ZONE_DATA_SCHEMA',
|
||||
attributeToEdit: {
|
||||
type: 'dynamiczone',
|
||||
components: [],
|
||||
name: 'dz',
|
||||
createComponent: false,
|
||||
componentToCreate: { type: 'component' },
|
||||
},
|
||||
};
|
||||
const expected = initialState
|
||||
.setIn(['modifiedData'], fromJS(action.attributeToEdit))
|
||||
.setIn(['initialData'], fromJS(action.attributeToEdit));
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_ERRORS', () => {
|
||||
it('Should set the formErrors object correctly', () => {
|
||||
const action = {
|
||||
type: 'SET_ERRORS',
|
||||
errors: {
|
||||
test: 'this is required',
|
||||
},
|
||||
};
|
||||
const expected = initialState.set('formErrors', fromJS(action.errors));
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Default', () => {
|
||||
it('Should return the initialState', () => {
|
||||
const action = { type: 'DUMMY' };
|
||||
|
||||
expect(reducer(initialState, action)).toEqual(initialState);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,4 +1,3 @@
|
||||
const makeUnique = array =>
|
||||
array.filter((key, index) => array.indexOf(key) === index && key !== '');
|
||||
const makeUnique = array => [...new Set(array)];
|
||||
|
||||
export default makeUnique;
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import makeUnique from '../makeUnique';
|
||||
|
||||
describe('CTB | utils | makeUnique', () => {
|
||||
it('Should remove the duplicate elements', () => {
|
||||
const data = ['a', 'b', 'c', 'aa', 'a', 'bb', 'b'];
|
||||
const expected = ['a', 'b', 'c', 'aa', 'bb'];
|
||||
|
||||
expect(makeUnique(data)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@ -104,7 +104,7 @@ class PopUpForm extends React.Component {
|
||||
const { name, type } = e.target;
|
||||
const target = Object.assign(
|
||||
{ name, type },
|
||||
{ value: `/auth/${this.props.dataToEdit}/callback` },
|
||||
{ value: `/auth/${this.props.dataToEdit}/callback` }
|
||||
);
|
||||
this.props.onChange({ target });
|
||||
}
|
||||
@ -141,7 +141,7 @@ class PopUpForm extends React.Component {
|
||||
|
||||
return acc;
|
||||
},
|
||||
[],
|
||||
[]
|
||||
);
|
||||
|
||||
if (settingType === 'providers') {
|
||||
@ -169,7 +169,7 @@ class PopUpForm extends React.Component {
|
||||
errors={get(
|
||||
formErrors,
|
||||
[findIndex(formErrors, ['name', value]), 'errors'],
|
||||
[],
|
||||
[]
|
||||
)}
|
||||
key={value}
|
||||
label={{
|
||||
@ -240,7 +240,7 @@ class PopUpForm extends React.Component {
|
||||
errors={get(
|
||||
this.props.formErrors,
|
||||
[findIndex(this.props.formErrors, ['name', value]), 'errors'],
|
||||
[],
|
||||
[]
|
||||
)}
|
||||
label={{ id: `users-permissions.PopUpForm.Email.${value}.label` }}
|
||||
name={`${settingType}.${dataToEdit}.${value}`}
|
||||
@ -262,7 +262,7 @@ class PopUpForm extends React.Component {
|
||||
errors={get(
|
||||
this.props.formErrors,
|
||||
[findIndex(this.props.formErrors, ['name', value]), 'errors'],
|
||||
[],
|
||||
[]
|
||||
)}
|
||||
label={{ id: `users-permissions.PopUpForm.Email.${value}.label` }}
|
||||
name={`${settingType}.${dataToEdit}.${value}`}
|
||||
|
||||
@ -223,7 +223,7 @@ export class EditPage extends React.Component {
|
||||
type: 'submit',
|
||||
disabled: isEqual(
|
||||
this.props.editPage.modifiedData,
|
||||
this.props.editPage.initialData,
|
||||
this.props.editPage.initialData
|
||||
),
|
||||
key: 'button-submit',
|
||||
},
|
||||
@ -258,7 +258,7 @@ export class EditPage extends React.Component {
|
||||
description: get(
|
||||
this.props.editPage.initialData,
|
||||
'description',
|
||||
'',
|
||||
''
|
||||
),
|
||||
}}
|
||||
>
|
||||
@ -388,13 +388,13 @@ function mapDispatchToProps(dispatch) {
|
||||
resetProps,
|
||||
resetShouldDisplayPoliciesHint,
|
||||
},
|
||||
dispatch,
|
||||
dispatch
|
||||
);
|
||||
}
|
||||
|
||||
const withConnect = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
mapDispatchToProps
|
||||
);
|
||||
const withReducer = strapi.injectReducer({
|
||||
key: 'editPage',
|
||||
@ -406,5 +406,5 @@ const withSaga = strapi.injectSaga({ key: 'editPage', saga, pluginId });
|
||||
export default compose(
|
||||
withReducer,
|
||||
withSaga,
|
||||
withConnect,
|
||||
withConnect
|
||||
)(EditPage);
|
||||
|
||||
@ -3,7 +3,7 @@ import { get, isEmpty, isObject } from 'lodash';
|
||||
export default function checkFormValidity(
|
||||
settingType,
|
||||
data,
|
||||
providerToEdit = '',
|
||||
providerToEdit = ''
|
||||
) {
|
||||
const formErrors = [];
|
||||
|
||||
|
||||
@ -148,7 +148,7 @@ export class HomePage extends React.Component {
|
||||
this.props.history.push(`${this.props.location.pathname}/create`);
|
||||
} else if (this.props.match.params.settingType === 'providers') {
|
||||
this.props.history.push(
|
||||
`${this.props.location.pathname}#add::${this.props.match.params.settingType}`,
|
||||
`${this.props.location.pathname}#add::${this.props.match.params.settingType}`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -166,7 +166,7 @@ export class HomePage extends React.Component {
|
||||
const formErrors = checkFormValidity(
|
||||
this.props.match.params.settingType,
|
||||
modifiedObject,
|
||||
this.props.dataToEdit,
|
||||
this.props.dataToEdit
|
||||
);
|
||||
|
||||
if (isEqual(initObject, modifiedObject)) {
|
||||
@ -318,7 +318,7 @@ function mapDispatchToProps(dispatch) {
|
||||
submit,
|
||||
unsetDataToEdit,
|
||||
},
|
||||
dispatch,
|
||||
dispatch
|
||||
);
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ const mapStateToProps = selectHomePage();
|
||||
|
||||
const withConnect = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
mapDispatchToProps
|
||||
);
|
||||
const withReducer = strapi.injectReducer({
|
||||
key: 'homePage',
|
||||
@ -338,5 +338,5 @@ const withSaga = strapi.injectSaga({ key: 'homePage', saga, pluginId });
|
||||
export default compose(
|
||||
withReducer,
|
||||
withSaga,
|
||||
withConnect,
|
||||
withConnect
|
||||
)(injectIntl(HomePage));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user