mirror of
https://github.com/strapi/strapi.git
synced 2025-11-07 21:58:23 +00:00
Unit tests
This commit is contained in:
parent
8b9eeee3a3
commit
a747d35c78
@ -1,107 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* AttributeLi
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
import { capitalize } from 'lodash';
|
|
||||||
import { IcoContainer } from 'strapi-helper-plugin';
|
|
||||||
|
|
||||||
import attributeIcons from '../../utils/attributeIcons';
|
|
||||||
import pluginId from '../../pluginId';
|
|
||||||
|
|
||||||
import styles from './styles.scss';
|
|
||||||
|
|
||||||
function AttributeLi({
|
|
||||||
attributeInfos: { configurable, plugin, target, type },
|
|
||||||
name,
|
|
||||||
onClick,
|
|
||||||
onClickOnTrashIcon,
|
|
||||||
}) {
|
|
||||||
const ico = ['integer', 'biginteger', 'float', 'decimal'].includes(type)
|
|
||||||
? 'number'
|
|
||||||
: type;
|
|
||||||
|
|
||||||
const src = target ? attributeIcons.relation : attributeIcons[ico];
|
|
||||||
/* eslint-disable indent */
|
|
||||||
/* istanbul ignore next */
|
|
||||||
const icons =
|
|
||||||
configurable === false
|
|
||||||
? [{ icoType: 'lock' }]
|
|
||||||
: [
|
|
||||||
{ icoType: 'pencil', onClick: () => onClick(name, type) },
|
|
||||||
{ icoType: 'trash', onClick: () => onClickOnTrashIcon(name) },
|
|
||||||
];
|
|
||||||
const relationStyle = target ? styles.relation : null;
|
|
||||||
const configurableStyle = configurable === false ? null : styles.editable;
|
|
||||||
/* eslint-enable indent */
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li
|
|
||||||
className={`${styles.attributeLi} ${relationStyle} ${configurableStyle}`}
|
|
||||||
onClick={() => {
|
|
||||||
if (configurable !== false) {
|
|
||||||
onClick(name, type);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className={styles.flex}>
|
|
||||||
<div className={styles.nameContainer}>
|
|
||||||
<img src={src} alt={`icon-${ico}`} />
|
|
||||||
<div>{name}</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.relationContainer}>
|
|
||||||
{target ? (
|
|
||||||
<div>
|
|
||||||
<FormattedMessage
|
|
||||||
id={`${pluginId}.modelPage.attribute.relationWith`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormattedMessage id={`${pluginId}.from`}>
|
|
||||||
{msg => (
|
|
||||||
<span style={{ fontStyle: 'italic' }}>
|
|
||||||
{capitalize(target)}
|
|
||||||
|
|
||||||
{plugin && `(${msg}: ${plugin})`}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</FormattedMessage>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<FormattedMessage id={`${pluginId}.attribute.${type}`} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className={styles.mainField} />
|
|
||||||
<IcoContainer icons={icons} />
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
AttributeLi.defaultProps = {
|
|
||||||
attributeInfos: {
|
|
||||||
configurable: true,
|
|
||||||
plugin: null,
|
|
||||||
target: null,
|
|
||||||
type: null,
|
|
||||||
},
|
|
||||||
onClick: () => {},
|
|
||||||
onClickOnTrashIcon: () => {},
|
|
||||||
};
|
|
||||||
|
|
||||||
AttributeLi.propTypes = {
|
|
||||||
attributeInfos: PropTypes.shape({
|
|
||||||
configurable: PropTypes.bool,
|
|
||||||
plugin: PropTypes.string,
|
|
||||||
target: PropTypes.string,
|
|
||||||
type: PropTypes.string,
|
|
||||||
}),
|
|
||||||
name: PropTypes.string.isRequired,
|
|
||||||
onClick: PropTypes.func,
|
|
||||||
onClickOnTrashIcon: PropTypes.func,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AttributeLi;
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
.attributeLi {
|
|
||||||
min-height: 5.3rem;
|
|
||||||
margin-top: 0!important;
|
|
||||||
list-style: none;
|
|
||||||
font-size: 1.3rem;
|
|
||||||
line-height: 5.3rem;
|
|
||||||
|
|
||||||
&:last-child .flex {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editable {
|
|
||||||
&:hover {
|
|
||||||
background-color: #F7F8F8;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin: 0 5.3rem 0 3.8rem;
|
|
||||||
// border-bottom: 1px solid black;
|
|
||||||
border-bottom: 1px solid rgba(14,22,34,0.04);
|
|
||||||
}
|
|
||||||
|
|
||||||
.nameContainer {
|
|
||||||
display: flex;
|
|
||||||
width: 30rem;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
> img{
|
|
||||||
display: inline-block;
|
|
||||||
width: 35px;
|
|
||||||
height: 20px;
|
|
||||||
margin-top: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> div {
|
|
||||||
margin-left: 3.9rem;
|
|
||||||
color: #333740;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.relationContainer {
|
|
||||||
width: 30rem;
|
|
||||||
text-align: left;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainField {
|
|
||||||
width: 10rem;
|
|
||||||
text-align: right;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icoContainer {
|
|
||||||
width: 7rem;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
opacity: .75;
|
|
||||||
> div {
|
|
||||||
width: 23px;
|
|
||||||
height: 100%;
|
|
||||||
color: #0E1622;
|
|
||||||
> i {
|
|
||||||
z-index: 0;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
> div:last-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.relation {
|
|
||||||
background: linear-gradient(135deg, rgba(28,93,231,0.05) 0%, rgba(239,243,253,0) 100%);
|
|
||||||
}
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { shallow } from 'enzyme';
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
import AttributeLi from '../index';
|
|
||||||
|
|
||||||
describe('<AttributeLi />', () => {
|
|
||||||
it('should not crash', () => {
|
|
||||||
shallow(<AttributeLi name="test" />);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show the origin of the model if it\'s comming from a plugin', () => {
|
|
||||||
const props = {
|
|
||||||
attributeInfos: {
|
|
||||||
configurable: false,
|
|
||||||
plugin: 'users-permissions',
|
|
||||||
target: 'role',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
name: 'role',
|
|
||||||
onClick: jest.fn(),
|
|
||||||
};
|
|
||||||
const wrapper = shallow(<AttributeLi {...props} />);
|
|
||||||
const insideCompo = shallow(
|
|
||||||
wrapper
|
|
||||||
.find(FormattedMessage)
|
|
||||||
.last()
|
|
||||||
.prop('children')(),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(insideCompo.text()).toContain('users-permissions');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not show the origin of the model if it\'s not comming from a plugin', () => {
|
|
||||||
const props = {
|
|
||||||
attributeInfos: {
|
|
||||||
configurable: false,
|
|
||||||
plugin: null,
|
|
||||||
target: 'role',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
name: 'role',
|
|
||||||
onClick: jest.fn(),
|
|
||||||
};
|
|
||||||
const wrapper = shallow(<AttributeLi {...props} />);
|
|
||||||
const insideCompo = shallow(
|
|
||||||
wrapper
|
|
||||||
.find(FormattedMessage)
|
|
||||||
.last()
|
|
||||||
.prop('children')(),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(insideCompo.text().trim()).toEqual('Role');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should match the <number> type with the number icon', () => {
|
|
||||||
const props = {
|
|
||||||
attributeInfos: {
|
|
||||||
configurable: false,
|
|
||||||
plugin: null,
|
|
||||||
type: 'biginteger',
|
|
||||||
},
|
|
||||||
name: 'role',
|
|
||||||
onClick: jest.fn(),
|
|
||||||
};
|
|
||||||
const wrapper = shallow(<AttributeLi {...props} />);
|
|
||||||
const img = wrapper.find('img').first();
|
|
||||||
|
|
||||||
expect(img.props('alt')).toBeDefined();
|
|
||||||
expect(img.prop('alt')).toBe('icon-number');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call the onClick prop with the correct data if it is configurable', () => {
|
|
||||||
const props = {
|
|
||||||
attributeInfos: {
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
name: 'name',
|
|
||||||
onClick: jest.fn(),
|
|
||||||
};
|
|
||||||
const wrapper = shallow(<AttributeLi {...props} />);
|
|
||||||
const { onClick } = wrapper.find('li').props();
|
|
||||||
|
|
||||||
onClick();
|
|
||||||
|
|
||||||
expect(props.onClick).toHaveBeenCalledWith('name', 'string');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not call the onClick prop with the correct data if it is configurable', () => {
|
|
||||||
const props = {
|
|
||||||
attributeInfos: {
|
|
||||||
configurable: false,
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
name: 'name',
|
|
||||||
onClick: jest.fn(),
|
|
||||||
};
|
|
||||||
const wrapper = shallow(<AttributeLi {...props} />);
|
|
||||||
const { onClick } = wrapper.find('li').props();
|
|
||||||
|
|
||||||
onClick();
|
|
||||||
|
|
||||||
expect(props.onClick).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the defaultProps', () => {
|
|
||||||
const {
|
|
||||||
defaultProps: { onClick, onClickOnTrashIcon },
|
|
||||||
} = AttributeLi;
|
|
||||||
|
|
||||||
expect(onClick).toBeDefined();
|
|
||||||
expect(onClick()).toBe(undefined);
|
|
||||||
expect(onClickOnTrashIcon).toBeDefined();
|
|
||||||
expect(onClickOnTrashIcon()).toBe(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,10 +1,9 @@
|
|||||||
import React, { useState } from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { capitalize } from 'lodash';
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { PopUpWarning } from 'strapi-helper-plugin';
|
|
||||||
|
|
||||||
import attributeIcons from '../../utils/attributeIcons';
|
import attributeIcons from '../../utils/attributeIcons';
|
||||||
import pluginId from '../../pluginId';
|
import pluginId from '../../pluginId';
|
||||||
|
|
||||||
@ -12,67 +11,59 @@ import StyledListRow from './StyledListRow';
|
|||||||
|
|
||||||
function ListRow({
|
function ListRow({
|
||||||
attributeId,
|
attributeId,
|
||||||
canOpenModal,
|
configurable,
|
||||||
deleteAttribute,
|
|
||||||
isTemporary,
|
|
||||||
name,
|
name,
|
||||||
source,
|
onClick,
|
||||||
|
onClickDelete,
|
||||||
|
plugin,
|
||||||
|
target,
|
||||||
type,
|
type,
|
||||||
}) {
|
}) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
|
|
||||||
const ico = ['integer', 'biginteger', 'float', 'decimal'].includes(type)
|
const ico = ['integer', 'biginteger', 'float', 'decimal'].includes(type)
|
||||||
? 'number'
|
? 'number'
|
||||||
: type;
|
: type;
|
||||||
|
|
||||||
const src = attributeIcons[ico];
|
const src = target ? attributeIcons.relation : attributeIcons[ico];
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
if (configurable !== false) {
|
||||||
|
onClick(attributeId, type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledListRow>
|
<StyledListRow onClick={handleClick}>
|
||||||
<td>
|
<td>
|
||||||
<img src={src} alt={`icon-${ico}`} />
|
<img src={src} alt={`icon-${ico}`} />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>
|
<p>{name}</p>
|
||||||
{name}
|
</td>
|
||||||
{source && (
|
<td>
|
||||||
|
{target ? (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id={`${pluginId}.modelPage.attribute.relationWith`}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormattedMessage id={`${pluginId}.from`}>
|
<FormattedMessage id={`${pluginId}.from`}>
|
||||||
{message => (
|
{msg => (
|
||||||
<span
|
<span style={{ fontStyle: 'italic' }}>
|
||||||
style={{
|
{capitalize(target)}
|
||||||
fontStyle: 'italic',
|
|
||||||
color: '#787E8F',
|
{plugin && `(${msg}: ${plugin})`}
|
||||||
fontWeight: '500',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
({message}: {source})
|
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</FormattedMessage>
|
</FormattedMessage>
|
||||||
)}
|
</div>
|
||||||
|
) : (
|
||||||
{isTemporary && (
|
|
||||||
<FormattedMessage
|
|
||||||
id={`${pluginId}.contentType.temporaryDisplay`}
|
|
||||||
style={{
|
|
||||||
paddingLeft: '15px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<FormattedMessage id={`${pluginId}.attribute.${type}`} />
|
<FormattedMessage id={`${pluginId}.attribute.${type}`} />
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{!source && (
|
{configurable ? (
|
||||||
<>
|
<>
|
||||||
<button
|
<button type="button" onClick={handleClick}>
|
||||||
type="button"
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i className="fa fa-pencil link-icon" />
|
<i className="fa fa-pencil link-icon" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@ -80,33 +71,14 @@ function ListRow({
|
|||||||
onClick={e => {
|
onClick={e => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (canOpenModal || isTemporary) {
|
onClickDelete(attributeId);
|
||||||
setIsOpen(true);
|
|
||||||
} else {
|
|
||||||
strapi.notification.info(
|
|
||||||
`${pluginId}.notification.info.work.notSaved`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i className="fa fa-trash link-icon" />
|
<i className="fa fa-trash link-icon" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<PopUpWarning
|
|
||||||
isOpen={isOpen}
|
|
||||||
toggleModal={() => setIsOpen(prevState => !prevState)}
|
|
||||||
content={{
|
|
||||||
message: `${pluginId}.popUpWarning.bodyMessage.${
|
|
||||||
type === 'models' ? 'contentType' : 'groups'
|
|
||||||
}.delete`,
|
|
||||||
}}
|
|
||||||
type="danger"
|
|
||||||
onConfirm={() => {
|
|
||||||
setIsOpen(false);
|
|
||||||
deleteAttribute(attributeId);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
|
) : (
|
||||||
|
<i className="fa fa-lock" />
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
</StyledListRow>
|
</StyledListRow>
|
||||||
@ -114,19 +86,24 @@ function ListRow({
|
|||||||
}
|
}
|
||||||
|
|
||||||
ListRow.defaultProps = {
|
ListRow.defaultProps = {
|
||||||
canOpenModal: true,
|
configurable: true,
|
||||||
deleteAttribute: () => {},
|
onClick: () => {},
|
||||||
source: null,
|
onClickDelete: () => {},
|
||||||
|
plugin: null,
|
||||||
|
target: null,
|
||||||
|
type: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
ListRow.propTypes = {
|
ListRow.propTypes = {
|
||||||
attributeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
attributeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
||||||
canOpenModal: PropTypes.bool,
|
.isRequired,
|
||||||
deleteAttribute: PropTypes.func,
|
configurable: PropTypes.bool,
|
||||||
isTemporary: PropTypes.bool.isRequired,
|
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
source: PropTypes.string,
|
onClick: PropTypes.func,
|
||||||
type: PropTypes.string.isRequired,
|
onClickDelete: PropTypes.func,
|
||||||
|
plugin: PropTypes.string,
|
||||||
|
target: PropTypes.string,
|
||||||
|
type: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ListRow;
|
export default ListRow;
|
||||||
|
|||||||
@ -0,0 +1,102 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import ListRow from '../index';
|
||||||
|
import StyledListRow from '../StyledListRow';
|
||||||
|
|
||||||
|
describe('<ListRow />', () => {
|
||||||
|
const props = {
|
||||||
|
attributeId: 'role',
|
||||||
|
configurable: false,
|
||||||
|
name: 'role',
|
||||||
|
onClick: jest.fn(),
|
||||||
|
onClickDelete: jest.fn(),
|
||||||
|
plugin: 'users-permissions',
|
||||||
|
target: 'role',
|
||||||
|
type: 'string',
|
||||||
|
};
|
||||||
|
|
||||||
|
it('should not crash', () => {
|
||||||
|
shallow(<ListRow {...props} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show the origin of the feature if it's comming from a plugin", () => {
|
||||||
|
const wrapper = shallow(<ListRow {...props} />);
|
||||||
|
const insideCompo = shallow(
|
||||||
|
wrapper
|
||||||
|
.find(FormattedMessage)
|
||||||
|
.last()
|
||||||
|
.prop('children')()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(insideCompo.text()).toContain('users-permissions');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not show the origin of the feature if it's not comming from a plugin", () => {
|
||||||
|
props.plugin = null;
|
||||||
|
|
||||||
|
const wrapper = shallow(<ListRow {...props} />);
|
||||||
|
const insideCompo = shallow(
|
||||||
|
wrapper
|
||||||
|
.find(FormattedMessage)
|
||||||
|
.last()
|
||||||
|
.prop('children')()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(insideCompo.text().trim()).toEqual('Role');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should match the <number> type with the number icon', () => {
|
||||||
|
props.type = 'biginteger';
|
||||||
|
|
||||||
|
const wrapper = shallow(<ListRow {...props} />);
|
||||||
|
const img = wrapper.find('img').first();
|
||||||
|
|
||||||
|
expect(img.props('alt')).toBeDefined();
|
||||||
|
expect(img.prop('alt')).toBe('icon-number');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call the onClick prop with the correct data if it is not configurable', () => {
|
||||||
|
props.type = 'string';
|
||||||
|
|
||||||
|
const wrapper = shallow(<ListRow {...props} />);
|
||||||
|
const row = wrapper.find(StyledListRow);
|
||||||
|
row.simulate('click');
|
||||||
|
|
||||||
|
expect(props.onClick).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the onClick prop with the correct data if it is configurable', () => {
|
||||||
|
props.configurable = true;
|
||||||
|
|
||||||
|
const wrapper = shallow(<ListRow {...props} />);
|
||||||
|
const row = wrapper.find(StyledListRow);
|
||||||
|
row.simulate('click');
|
||||||
|
|
||||||
|
expect(props.onClick).toHaveBeenCalledWith('role', 'string');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the onClickDelete prop with the correct data if it is configurable', () => {
|
||||||
|
props.configurable = true;
|
||||||
|
|
||||||
|
const wrapper = shallow(<ListRow {...props} />);
|
||||||
|
const deleteBtn = wrapper.find('button').last();
|
||||||
|
deleteBtn.simulate('click', {
|
||||||
|
stopPropagation: () => {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(props.onClickDelete).toHaveBeenCalledWith('role');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use the defaultProps', () => {
|
||||||
|
const {
|
||||||
|
defaultProps: { onClick, onClickDelete },
|
||||||
|
} = ListRow;
|
||||||
|
|
||||||
|
expect(onClick).toBeDefined();
|
||||||
|
expect(onClick()).toBe(undefined);
|
||||||
|
expect(onClickDelete).toBeDefined();
|
||||||
|
expect(onClickDelete()).toBe(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -19,14 +19,21 @@ import {
|
|||||||
List,
|
List,
|
||||||
ListHeader,
|
ListHeader,
|
||||||
ListWrapper,
|
ListWrapper,
|
||||||
|
PopUpWarning,
|
||||||
} from 'strapi-helper-plugin';
|
} from 'strapi-helper-plugin';
|
||||||
|
|
||||||
import { deleteGroupAttribute } from '../App/actions';
|
import { deleteGroupAttribute } from '../App/actions';
|
||||||
|
|
||||||
/* eslint-disable no-extra-boolean-cast */
|
/* eslint-disable no-extra-boolean-cast */
|
||||||
export class GroupPage extends React.Component {
|
export class GroupPage extends React.Component {
|
||||||
|
state = { attrToDelete: null, showWarning: false };
|
||||||
featureType = 'group';
|
featureType = 'group';
|
||||||
|
|
||||||
|
displayNotificationCTNotSaved = () =>
|
||||||
|
strapi.notification.info(
|
||||||
|
`${pluginId}.notification.info.contentType.creating.notSaved`
|
||||||
|
);
|
||||||
|
|
||||||
getFeature = () => {
|
getFeature = () => {
|
||||||
const { modifiedDataGroup, newGroup } = this.props;
|
const { modifiedDataGroup, newGroup } = this.props;
|
||||||
|
|
||||||
@ -93,8 +100,21 @@ export class GroupPage extends React.Component {
|
|||||||
return search;
|
return search;
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDeleteGroupAttribute = attrToDelete => {
|
handleClickOnTrashIcon = attrToDelete => {
|
||||||
|
const { emitEvent } = this.context;
|
||||||
|
const { canOpenModal } = this.props;
|
||||||
|
|
||||||
|
if (canOpenModal || this.isUpdatingTempFeature()) {
|
||||||
|
this.setState({ showWarning: true, attrToDelete });
|
||||||
|
emitEvent('willDeleteFieldOfContentType');
|
||||||
|
} else {
|
||||||
|
this.displayNotificationCTNotSaved();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleDeleteAttribute = () => {
|
||||||
const { deleteGroupAttribute } = this.props;
|
const { deleteGroupAttribute } = this.props;
|
||||||
|
const { attrToDelete } = this.state;
|
||||||
|
|
||||||
const keys = this.isUpdatingTempFeature()
|
const keys = this.isUpdatingTempFeature()
|
||||||
? ['newGroup', 'schema', 'attributes', attrToDelete]
|
? ['newGroup', 'schema', 'attributes', attrToDelete]
|
||||||
@ -105,7 +125,9 @@ export class GroupPage extends React.Component {
|
|||||||
'attributes',
|
'attributes',
|
||||||
attrToDelete,
|
attrToDelete,
|
||||||
];
|
];
|
||||||
|
|
||||||
deleteGroupAttribute(keys);
|
deleteGroupAttribute(keys);
|
||||||
|
this.setState({ attrToDelete: null, showWarning: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleGoBack = () => {
|
handleGoBack = () => {
|
||||||
@ -124,12 +146,33 @@ export class GroupPage extends React.Component {
|
|||||||
return get(currentData, 'isTemporary', false);
|
return get(currentData, 'isTemporary', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
toggleModalWarning = () =>
|
||||||
|
this.setState(prevState => ({ showWarning: !prevState.showWarning }));
|
||||||
|
|
||||||
|
renderListRow = (attribute, index) => {
|
||||||
|
const { canOpenModal } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListRow
|
||||||
|
{...attribute}
|
||||||
|
attributeId={index}
|
||||||
|
canOpenModal={canOpenModal}
|
||||||
|
context={this.context}
|
||||||
|
name={attribute.name}
|
||||||
|
onClick={this.handleClickEditAttribute}
|
||||||
|
onClickDelete={this.handleClickOnTrashIcon}
|
||||||
|
key={attribute.name}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
canOpenModal,
|
|
||||||
history: { push },
|
history: { push },
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const { showWarning } = this.state;
|
||||||
|
|
||||||
const attributes = this.getFeatureAttributes();
|
const attributes = this.getFeatureAttributes();
|
||||||
const attributesNumber = this.getFeatureAttributesLength();
|
const attributesNumber = this.getFeatureAttributesLength();
|
||||||
|
|
||||||
@ -170,18 +213,9 @@ export class GroupPage extends React.Component {
|
|||||||
<List>
|
<List>
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{attributes.map((attribute, index) => (
|
{attributes.map((attribute, index) =>
|
||||||
<ListRow
|
this.renderListRow(attribute, index)
|
||||||
key={attribute.name}
|
)}
|
||||||
attributeId={index}
|
|
||||||
{...attribute}
|
|
||||||
canOpenModal={canOpenModal}
|
|
||||||
context={this.context}
|
|
||||||
deleteAttribute={this.handleDeleteGroupAttribute}
|
|
||||||
isTemporary={false}
|
|
||||||
type={attribute.type}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</List>
|
</List>
|
||||||
@ -191,15 +225,30 @@ export class GroupPage extends React.Component {
|
|||||||
</ListWrapper>
|
</ListWrapper>
|
||||||
)}
|
)}
|
||||||
</ViewContainer>
|
</ViewContainer>
|
||||||
|
|
||||||
<AttributesModalPicker
|
<AttributesModalPicker
|
||||||
isOpen={this.getModalType() === 'chooseAttributes'}
|
isOpen={this.getModalType() === 'chooseAttributes'}
|
||||||
push={push}
|
push={push}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<PopUpWarning
|
||||||
|
isOpen={showWarning}
|
||||||
|
toggleModal={this.toggleModalWarning}
|
||||||
|
content={{
|
||||||
|
message: `${pluginId}.popUpWarning.bodyMessage.attribute.delete`,
|
||||||
|
}}
|
||||||
|
popUpWarningType="danger"
|
||||||
|
onConfirm={this.handleDeleteAttribute}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GroupPage.contextTypes = {
|
||||||
|
emitEvent: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
GroupPage.defaultProps = {
|
GroupPage.defaultProps = {
|
||||||
canOpenModal: true,
|
canOpenModal: true,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +1,40 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
|
import mountWithIntl from 'testUtils/mountWithIntl';
|
||||||
|
import formatMessagesWithPluginId from 'testUtils/formatMessages';
|
||||||
|
|
||||||
import { EmptyAttributesBlock } from 'strapi-helper-plugin';
|
import { EmptyAttributesBlock } from 'strapi-helper-plugin';
|
||||||
|
|
||||||
|
import pluginId from '../../../pluginId';
|
||||||
|
import pluginTradsEn from '../../../translations/en.json';
|
||||||
|
|
||||||
|
import MenuContext from '../../MenuContext';
|
||||||
|
|
||||||
import { GroupPage, mapDispatchToProps } from '../index';
|
import { GroupPage, mapDispatchToProps } from '../index';
|
||||||
|
|
||||||
|
const messages = formatMessagesWithPluginId(pluginId, pluginTradsEn);
|
||||||
|
|
||||||
|
const context = { emitEvent: jest.fn() };
|
||||||
|
const renderComponent = (props = {}) => {
|
||||||
|
const menuContext = {
|
||||||
|
canOpenModal: true,
|
||||||
|
groups: [],
|
||||||
|
models: [],
|
||||||
|
push: jest.fn(),
|
||||||
|
};
|
||||||
|
return mountWithIntl(
|
||||||
|
<BrowserRouter>
|
||||||
|
<MenuContext.Provider value={menuContext}>
|
||||||
|
<GroupPage {...props} />
|
||||||
|
</MenuContext.Provider>
|
||||||
|
</BrowserRouter>,
|
||||||
|
messages,
|
||||||
|
context
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const basePath = '/plugins/content-type-builder/groups';
|
const basePath = '/plugins/content-type-builder/groups';
|
||||||
const props = {
|
const props = {
|
||||||
deleteGroupAttribute: jest.fn(),
|
deleteGroupAttribute: jest.fn(),
|
||||||
@ -156,33 +187,98 @@ describe('CTB <GroupPage />, mapDispatchToProps', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('DeleteGroupAttribute', () => {
|
describe('DeleteGroupAttribute', () => {
|
||||||
it('should call deleteGroupAttribute with modifiedDataGroup path when isTemporary is false', () => {
|
let topCompo;
|
||||||
props.groups.find(item => item.name == 'tests').isTemporary = false;
|
|
||||||
|
|
||||||
const { handleDeleteGroupAttribute } = shallow(
|
afterEach(() => {
|
||||||
<GroupPage {...props} />
|
topCompo.unmount();
|
||||||
).instance();
|
|
||||||
handleDeleteGroupAttribute('name');
|
|
||||||
|
|
||||||
const keys = [
|
|
||||||
'modifiedDataGroup',
|
|
||||||
'tests',
|
|
||||||
'schema',
|
|
||||||
'attributes',
|
|
||||||
'name',
|
|
||||||
];
|
|
||||||
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call deleteGroupAttribute with modifiedDataGroup path when isTemporary is true', () => {
|
describe('ToggleModalWarning', () => {
|
||||||
props.groups.find(item => item.name == 'tests').isTemporary = true;
|
topCompo = renderComponent(props);
|
||||||
const { handleDeleteGroupAttribute } = shallow(
|
|
||||||
<GroupPage {...props} />
|
|
||||||
).instance();
|
|
||||||
|
|
||||||
handleDeleteGroupAttribute('name');
|
const wrapper = topCompo.find(GroupPage);
|
||||||
const keys = ['newGroup', 'schema', 'attributes', 'name'];
|
|
||||||
|
expect(wrapper.state()).toEqual({
|
||||||
|
showWarning: false,
|
||||||
|
attrToDelete: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { toggleModalWarning } = wrapper.instance();
|
||||||
|
|
||||||
|
toggleModalWarning();
|
||||||
|
|
||||||
|
expect(wrapper.state()).toEqual({
|
||||||
|
showWarning: true,
|
||||||
|
attrToDelete: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DeleteGroupAttribute', () => {
|
||||||
|
it('should display a notification if thee modal cannot be opened', async () => {
|
||||||
|
props.groups.find(item => item.name == 'tests').isTemporary = false;
|
||||||
|
props.canOpenModal = false;
|
||||||
|
|
||||||
|
topCompo = renderComponent(props);
|
||||||
|
|
||||||
|
const wrapper = topCompo.find(GroupPage);
|
||||||
|
const spyOnDisplayNotification = jest.spyOn(
|
||||||
|
wrapper.instance(),
|
||||||
|
'displayNotificationCTNotSaved'
|
||||||
|
);
|
||||||
|
const { handleClickOnTrashIcon } = wrapper.instance();
|
||||||
|
|
||||||
|
handleClickOnTrashIcon(0);
|
||||||
|
|
||||||
|
expect(context.emitEvent).not.toHaveBeenCalled();
|
||||||
|
expect(spyOnDisplayNotification).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call deleteGroupAttribute with modifiedDataGroup path when isTemporary is false', () => {
|
||||||
|
props.groups.find(item => item.name == 'tests').isTemporary = false;
|
||||||
|
props.canOpenModal = true;
|
||||||
|
|
||||||
|
topCompo = renderComponent(props);
|
||||||
|
|
||||||
|
const wrapper = topCompo.find(GroupPage);
|
||||||
|
const {
|
||||||
|
handleClickOnTrashIcon,
|
||||||
|
handleDeleteAttribute,
|
||||||
|
} = wrapper.instance();
|
||||||
|
|
||||||
|
handleClickOnTrashIcon(0);
|
||||||
|
expect(wrapper.state()).toEqual({
|
||||||
|
attrToDelete: 0,
|
||||||
|
showWarning: true,
|
||||||
|
});
|
||||||
|
handleDeleteAttribute();
|
||||||
|
|
||||||
|
const keys = ['modifiedDataGroup', 'tests', 'schema', 'attributes', 0];
|
||||||
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
||||||
|
expect(context.emitEvent).toHaveBeenCalledWith(
|
||||||
|
'willDeleteFieldOfContentType'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should call deleteGroupAttribute with newGroup path when isTemporary is true', () => {
|
||||||
|
props.groups.find(item => item.name == 'tests').isTemporary = true;
|
||||||
|
props.canOpenModal = true;
|
||||||
|
|
||||||
|
topCompo = renderComponent(props);
|
||||||
|
|
||||||
|
const wrapper = topCompo.find(GroupPage);
|
||||||
|
const {
|
||||||
|
handleClickOnTrashIcon,
|
||||||
|
handleDeleteAttribute,
|
||||||
|
} = wrapper.instance();
|
||||||
|
|
||||||
|
handleClickOnTrashIcon(0);
|
||||||
|
handleDeleteAttribute();
|
||||||
|
|
||||||
|
const keys = ['newGroup', 'schema', 'attributes', 0];
|
||||||
|
expect(props.deleteGroupAttribute).toHaveBeenCalledWith(keys);
|
||||||
|
expect(context.emitEvent).toHaveBeenCalledWith(
|
||||||
|
'willDeleteFieldOfContentType'
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -359,8 +359,9 @@ export class ModelPage extends React.Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDeleteAttribute = attrToDelete => {
|
handleDeleteAttribute = () => {
|
||||||
const { deleteModelAttribute } = this.props;
|
const { deleteModelAttribute } = this.props;
|
||||||
|
const { attrToDelete } = this.state;
|
||||||
|
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
const keys = this.isUpdatingTemporaryContentType()
|
const keys = this.isUpdatingTemporaryContentType()
|
||||||
@ -368,6 +369,7 @@ export class ModelPage extends React.Component {
|
|||||||
: ['modifiedData', this.getModelName(), 'attributes', attrToDelete];
|
: ['modifiedData', this.getModelName(), 'attributes', attrToDelete];
|
||||||
|
|
||||||
deleteModelAttribute(keys);
|
deleteModelAttribute(keys);
|
||||||
|
this.setState({ attrToDelete: null, showWarning: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleGoBack = () => {
|
handleGoBack = () => {
|
||||||
@ -498,15 +500,14 @@ export class ModelPage extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ListRow
|
<ListRow
|
||||||
key={attribute}
|
|
||||||
attributeId={attribute}
|
|
||||||
{...attributeInfos}
|
{...attributeInfos}
|
||||||
|
attributeId={attribute}
|
||||||
canOpenModal={canOpenModal}
|
canOpenModal={canOpenModal}
|
||||||
context={this.context}
|
context={this.context}
|
||||||
deleteAttribute={this.handleDeleteAttribute}
|
|
||||||
isTemporary={false}
|
|
||||||
name={attribute}
|
name={attribute}
|
||||||
type={attributeInfos.type}
|
onClick={this.handleClickEditAttribute}
|
||||||
|
onClickDelete={this.handleClickOnTrashIcon}
|
||||||
|
key={attribute}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -514,7 +515,6 @@ export class ModelPage extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const listTitleMessageIdBasePrefix = `${pluginId}.modelPage.contentType.list.title`;
|
const listTitleMessageIdBasePrefix = `${pluginId}.modelPage.contentType.list.title`;
|
||||||
const {
|
const {
|
||||||
canOpenModal,
|
|
||||||
clearTemporaryAttribute,
|
clearTemporaryAttribute,
|
||||||
clearTemporaryAttributeRelation,
|
clearTemporaryAttributeRelation,
|
||||||
history: { push },
|
history: { push },
|
||||||
@ -557,7 +557,7 @@ export class ModelPage extends React.Component {
|
|||||||
if (relationsNumber > 0) {
|
if (relationsNumber > 0) {
|
||||||
title.push({
|
title.push({
|
||||||
label: `${pluginId}.table.relations.title.${
|
label: `${pluginId}.table.relations.title.${
|
||||||
attributesNumber > 1 ? 'plural' : 'singular'
|
relationsNumber > 1 ? 'plural' : 'singular'
|
||||||
}`,
|
}`,
|
||||||
values: { number: relationsNumber },
|
values: { number: relationsNumber },
|
||||||
});
|
});
|
||||||
@ -580,7 +580,6 @@ export class ModelPage extends React.Component {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormattedMessage>
|
</FormattedMessage>
|
||||||
|
|
||||||
<ViewContainer
|
<ViewContainer
|
||||||
{...this.props}
|
{...this.props}
|
||||||
featureType={this.featureType}
|
featureType={this.featureType}
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
import { Redirect, BrowserRouter } from 'react-router-dom';
|
import { Redirect, BrowserRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import mountWithIntl from 'testUtils/mountWithIntl';
|
import mountWithIntl from 'testUtils/mountWithIntl';
|
||||||
import formatMessagesWithPluginId from 'testUtils/formatMessages';
|
import formatMessagesWithPluginId from 'testUtils/formatMessages';
|
||||||
|
|
||||||
import { EmptyAttributesBlock } from 'strapi-helper-plugin';
|
import {
|
||||||
|
EmptyAttributesBlock,
|
||||||
|
ListHeader,
|
||||||
|
ListWrapper,
|
||||||
|
} from 'strapi-helper-plugin';
|
||||||
|
|
||||||
import pluginId from '../../../pluginId';
|
import pluginId from '../../../pluginId';
|
||||||
import pluginTradsEn from '../../../translations/en.json';
|
import pluginTradsEn from '../../../translations/en.json';
|
||||||
|
|
||||||
import MenuContext from '../../MenuContext';
|
import MenuContext from '../../MenuContext';
|
||||||
import Block from '../../../components/Block';
|
|
||||||
|
|
||||||
import { clearTemporaryAttribute, onChangeAttribute } from '../../App/actions';
|
import { clearTemporaryAttribute, onChangeAttribute } from '../../App/actions';
|
||||||
|
|
||||||
@ -176,21 +178,19 @@ describe('<ModelPage />', () => {
|
|||||||
expect(wrapper.find(EmptyAttributesBlock)).toHaveLength(1);
|
expect(wrapper.find(EmptyAttributesBlock)).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should display the Block if the model's attributes are not empty", () => {
|
it("should display the ListWrapper if the model's attributes are not empty", () => {
|
||||||
const wrapper = shallow(<ModelPage {...props} />);
|
const wrapper = shallow(<ModelPage {...props} />);
|
||||||
|
|
||||||
expect(wrapper.find(Block)).toHaveLength(1);
|
expect(wrapper.find(ListWrapper)).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should display a singular text if the model's attributes relationship is one", () => {
|
it("should display a singular text if the model's attributes relationship is one", () => {
|
||||||
const wrapper = shallow(<ModelPage {...props} />);
|
const wrapper = shallow(<ModelPage {...props} />);
|
||||||
|
|
||||||
expect(
|
const { title } = wrapper.find(ListHeader).props();
|
||||||
wrapper
|
const { label } = title[1];
|
||||||
.find(FormattedMessage)
|
|
||||||
.last()
|
expect(label).toContain('relations.title.singular');
|
||||||
.prop('id')
|
|
||||||
).toContain('singular');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should display a plural text if the model's attributes relationships is more than one", () => {
|
it("should display a plural text if the model's attributes relationships is more than one", () => {
|
||||||
@ -198,12 +198,10 @@ describe('<ModelPage />', () => {
|
|||||||
props.match.path = `${basePath}/role&source=users-permissions`;
|
props.match.path = `${basePath}/role&source=users-permissions`;
|
||||||
const wrapper = shallow(<ModelPage {...props} />);
|
const wrapper = shallow(<ModelPage {...props} />);
|
||||||
|
|
||||||
expect(
|
const { title } = wrapper.find(ListHeader).props();
|
||||||
wrapper
|
const { label } = title[1];
|
||||||
.find(FormattedMessage)
|
|
||||||
.last()
|
expect(label).toContain('relations.title.plural');
|
||||||
.prop('id')
|
|
||||||
).toContain('plural');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call the handleClickOpenModalChooseAttributes when clicking on the EmptyAttributesBlock', () => {
|
it('should call the handleClickOpenModalChooseAttributes when clicking on the EmptyAttributesBlock', () => {
|
||||||
@ -633,7 +631,9 @@ describe('<ModelPage /> lifecycle', () => {
|
|||||||
|
|
||||||
describe('HandleClickOnTrashIcon', () => {
|
describe('HandleClickOnTrashIcon', () => {
|
||||||
it('should display a notification if thee modal cannot be opened', async () => {
|
it('should display a notification if thee modal cannot be opened', async () => {
|
||||||
|
props.models.find(item => item.name == 'product').isTemporary = false;
|
||||||
props.canOpenModal = false;
|
props.canOpenModal = false;
|
||||||
|
|
||||||
topCompo = renderComponent(props);
|
topCompo = renderComponent(props);
|
||||||
|
|
||||||
const wrapper = topCompo.find(ModelPage);
|
const wrapper = topCompo.find(ModelPage);
|
||||||
@ -645,10 +645,10 @@ describe('<ModelPage /> lifecycle', () => {
|
|||||||
|
|
||||||
handleClickOnTrashIcon('username');
|
handleClickOnTrashIcon('username');
|
||||||
|
|
||||||
|
expect(spyOnDisplayNotification).toHaveBeenCalled();
|
||||||
expect(context.emitEvent).not.toHaveBeenCalledWith(
|
expect(context.emitEvent).not.toHaveBeenCalledWith(
|
||||||
'willDeleteFieldOfContentType'
|
'willDeleteFieldOfContentType'
|
||||||
);
|
);
|
||||||
expect(spyOnDisplayNotification).toHaveBeenCalled();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit the event willDeleteFieldOfContentType', async () => {
|
it('should emit the event willDeleteFieldOfContentType', async () => {
|
||||||
@ -670,6 +670,68 @@ describe('<ModelPage /> lifecycle', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('deleteModelAttribute', () => {
|
||||||
|
it('should call deleteModelAttribute with modifiedDataGroup path when isTemporary is false', () => {
|
||||||
|
props.models.find(item => item.name == 'product').isTemporary = false;
|
||||||
|
props.canOpenModal = true;
|
||||||
|
|
||||||
|
topCompo = renderComponent(props);
|
||||||
|
|
||||||
|
const wrapper = topCompo.find(ModelPage);
|
||||||
|
const {
|
||||||
|
handleClickOnTrashIcon,
|
||||||
|
handleDeleteAttribute,
|
||||||
|
} = wrapper.instance();
|
||||||
|
|
||||||
|
handleClickOnTrashIcon('username');
|
||||||
|
handleDeleteAttribute();
|
||||||
|
|
||||||
|
const keys = ['modifiedData', 'product', 'attributes', 'username'];
|
||||||
|
expect(props.deleteModelAttribute).toHaveBeenCalledWith(keys);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call deleteModelAttribute with newGroup path when isTemporary is true', () => {
|
||||||
|
props.models.find(item => item.name == 'product').isTemporary = true;
|
||||||
|
props.canOpenModal = true;
|
||||||
|
|
||||||
|
topCompo = renderComponent(props);
|
||||||
|
|
||||||
|
const wrapper = topCompo.find(ModelPage);
|
||||||
|
const {
|
||||||
|
handleClickOnTrashIcon,
|
||||||
|
handleDeleteAttribute,
|
||||||
|
} = wrapper.instance();
|
||||||
|
|
||||||
|
handleClickOnTrashIcon('username');
|
||||||
|
handleDeleteAttribute();
|
||||||
|
const keys = ['newContentType', 'attributes', 'username'];
|
||||||
|
expect(props.deleteModelAttribute).toHaveBeenCalledWith(keys);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ToggleModalWarning', () => {
|
||||||
|
it('should change the showWarning on modal toggle', () => {
|
||||||
|
topCompo = renderComponent(props);
|
||||||
|
|
||||||
|
const wrapper = topCompo.find(ModelPage);
|
||||||
|
expect(wrapper.state()).toEqual({
|
||||||
|
attrToDelete: null,
|
||||||
|
showWarning: false,
|
||||||
|
removePrompt: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { toggleModalWarning } = wrapper.instance();
|
||||||
|
|
||||||
|
toggleModalWarning();
|
||||||
|
|
||||||
|
expect(wrapper.state()).toEqual({
|
||||||
|
attrToDelete: null,
|
||||||
|
showWarning: true,
|
||||||
|
removePrompt: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('CTB <ModelPage />, mapDispatchToProps', () => {
|
describe('CTB <ModelPage />, mapDispatchToProps', () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user