mirror of
https://github.com/strapi/strapi.git
synced 2025-11-08 22:32:02 +00:00
homepage reducer unit tests and some code review apply
Signed-off-by: Virginie Ky <virginie.ky@gmail.com>
This commit is contained in:
parent
8f24f1537c
commit
aaead39d38
@ -8,17 +8,15 @@ import CardPreview from '../CardPreview';
|
|||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
import Title from './Title';
|
import Title from './Title';
|
||||||
|
|
||||||
const Card = ({ file, id, small, selected, onChange }) => {
|
// TODO - adapt with the real data
|
||||||
// TODO - adapt with the real data
|
const Card = ({ checked, id, name, size, small, type, onChange, url }) => {
|
||||||
const { type, size, name } = file;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<div>
|
<div>
|
||||||
<CardImgWrapper small={small} selected={selected}>
|
<CardImgWrapper small={small} checked={checked}>
|
||||||
<CardPreview {...file} />
|
<CardPreview type={type} url={url} />
|
||||||
<div className="card-control-wrapper">
|
<div className="card-control-wrapper">
|
||||||
<Checkbox name={id} onChange={onChange} value={selected} />
|
<Checkbox name={id} onChange={onChange} value={checked} />
|
||||||
</div>
|
</div>
|
||||||
</CardImgWrapper>
|
</CardImgWrapper>
|
||||||
<Title fontSize="md" fontWeight="bold" ellipsis>
|
<Title fontSize="md" fontWeight="bold" ellipsis>
|
||||||
@ -31,18 +29,24 @@ const Card = ({ file, id, small, selected, onChange }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Card.defaultProps = {
|
Card.defaultProps = {
|
||||||
file: null,
|
checked: false,
|
||||||
|
name: null,
|
||||||
onChange: () => {},
|
onChange: () => {},
|
||||||
|
size: 0,
|
||||||
small: false,
|
small: false,
|
||||||
selected: false,
|
type: null,
|
||||||
|
url: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
Card.propTypes = {
|
Card.propTypes = {
|
||||||
|
checked: PropTypes.bool,
|
||||||
|
name: PropTypes.string,
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
file: PropTypes.object,
|
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
|
size: PropTypes.number,
|
||||||
small: PropTypes.bool,
|
small: PropTypes.bool,
|
||||||
selected: PropTypes.bool,
|
type: PropTypes.string,
|
||||||
|
url: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Card;
|
export default Card;
|
||||||
|
|||||||
@ -38,8 +38,8 @@ const CardImgWrapper = styled.div`
|
|||||||
return '';
|
return '';
|
||||||
}}
|
}}
|
||||||
|
|
||||||
${({ selected }) =>
|
${({ checked }) =>
|
||||||
selected &&
|
checked &&
|
||||||
`
|
`
|
||||||
.card-control-wrapper {
|
.card-control-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -50,14 +50,14 @@ const CardImgWrapper = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
CardImgWrapper.defaultProps = {
|
CardImgWrapper.defaultProps = {
|
||||||
|
checked: false,
|
||||||
hasError: false,
|
hasError: false,
|
||||||
selected: false,
|
|
||||||
small: false,
|
small: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
CardImgWrapper.propTypes = {
|
CardImgWrapper.propTypes = {
|
||||||
|
checked: PropTypes.bool,
|
||||||
hasError: PropTypes.bool,
|
hasError: PropTypes.bool,
|
||||||
selected: PropTypes.bool,
|
|
||||||
small: PropTypes.bool,
|
small: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,15 +6,9 @@ import Wrapper from './Wrapper';
|
|||||||
import Image from './Image';
|
import Image from './Image';
|
||||||
|
|
||||||
const CardPreview = ({ url, type }) => {
|
const CardPreview = ({ url, type }) => {
|
||||||
const renderFile = () => {
|
return (
|
||||||
if (!url) {
|
<Wrapper isImg={!!url}>{!url ? <FileIcon fileType={type} /> : <Image src={url} />}</Wrapper>
|
||||||
return <FileIcon fileType={type} />;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return <Image src={url} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
return <Wrapper isImg={!!url}>{renderFile()}</Wrapper>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CardPreview.defaultProps = {
|
CardPreview.defaultProps = {
|
||||||
|
|||||||
@ -1,25 +1,10 @@
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
// TODO : Review this code when API is done
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
font-size: 54px;
|
font-size: 54px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
color: ${({ type }) => {
|
// TODO : Review this code when API is done
|
||||||
switch (type) {
|
color: #bdbfc2;
|
||||||
case 'file-pdf':
|
|
||||||
return '#E26D6D';
|
|
||||||
case 'file-image':
|
|
||||||
return '#8AA066';
|
|
||||||
case 'file-video':
|
|
||||||
return '#77C69E';
|
|
||||||
case 'file-code':
|
|
||||||
return '#515A6D';
|
|
||||||
case 'file-archive':
|
|
||||||
return '#715A31';
|
|
||||||
default:
|
|
||||||
return '#BDBFC2';
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default Wrapper;
|
export default Wrapper;
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
// TODO : Review this code when API is done
|
|
||||||
{
|
|
||||||
"archive": ["rar", "zip"],
|
|
||||||
"code": ["js", "json", "rb", "erb", "txt", "css", "scss", "html", "jsx", "svg"],
|
|
||||||
"img": ["jpg", "jpeg", "png", "gif", "ico"],
|
|
||||||
"pdf": ["pdf"],
|
|
||||||
"powerpoint": ["ppt", "key", "xls"],
|
|
||||||
"video": ["mov", "avi", "mpg", "mp4", "m4v"],
|
|
||||||
"word": ["doc", "pages"]
|
|
||||||
}
|
|
||||||
@ -4,50 +4,18 @@
|
|||||||
* FileIcon
|
* FileIcon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO : Review this code when API is done
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { trim } from 'lodash';
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
||||||
import ext from './extensions.json';
|
|
||||||
import Wrapper from './Wrapper';
|
import Wrapper from './Wrapper';
|
||||||
|
|
||||||
function FileIcon({ fileType }) {
|
// TODO : Review this code when API is done
|
||||||
const iconType = (() => {
|
function FileIcon() {
|
||||||
switch (true) {
|
|
||||||
case ext.archive.includes(trim(fileType, '.')):
|
|
||||||
return 'file-archive';
|
|
||||||
case ext.code.includes(trim(fileType, '.')):
|
|
||||||
return 'file-code';
|
|
||||||
case ext.img.includes(trim(fileType, '.')):
|
|
||||||
return 'file-image';
|
|
||||||
case ext.pdf.includes(trim(fileType, '.')):
|
|
||||||
return 'file-pdf';
|
|
||||||
case ext.powerpoint.includes(trim(fileType, '.')):
|
|
||||||
return 'file-powerpoint';
|
|
||||||
case ext.video.includes(trim(fileType, '.')):
|
|
||||||
return 'file-video';
|
|
||||||
case ext.word.includes(trim(fileType, '.')):
|
|
||||||
return 'file-word';
|
|
||||||
default:
|
|
||||||
return 'file';
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper type={iconType}>
|
<Wrapper type="file">
|
||||||
<FontAwesomeIcon icon={['far', iconType]} />
|
<FontAwesomeIcon icon={['far', 'file']} />
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileIcon.defaultProps = {
|
|
||||||
fileType: 'zip',
|
|
||||||
};
|
|
||||||
|
|
||||||
FileIcon.propTypes = {
|
|
||||||
fileType: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FileIcon;
|
export default FileIcon;
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const List = ({ data, onChange, selectedItems }) => {
|
|||||||
<div className="col-xs-12 col-md-6 col-xl-3" key={JSON.stringify(item)}>
|
<div className="col-xs-12 col-md-6 col-xl-3" key={JSON.stringify(item)}>
|
||||||
<Card
|
<Card
|
||||||
small
|
small
|
||||||
selected={selectedItems.includes(item.id)}
|
checked={selectedItems.includes(item.id)}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
{...item}
|
{...item}
|
||||||
/>
|
/>
|
||||||
@ -37,74 +37,58 @@ List.defaultProps = {
|
|||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
id: '0',
|
id: '0',
|
||||||
file: {
|
|
||||||
name: 'Chat paysage',
|
name: 'Chat paysage',
|
||||||
size: 17329,
|
size: 17329,
|
||||||
type: 'image/png',
|
type: 'image/png',
|
||||||
url:
|
url:
|
||||||
'https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350',
|
'https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&h=350',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
file: {
|
|
||||||
name: 'Chat portrait',
|
name: 'Chat portrait',
|
||||||
size: 17329,
|
size: 17329,
|
||||||
type: 'image/png',
|
type: 'image/png',
|
||||||
url: 'https://emiliedammedumoulin.com/wp-content/uploads/2018/07/contact-chat-accueil.jpg',
|
url: 'https://emiliedammedumoulin.com/wp-content/uploads/2018/07/contact-chat-accueil.jpg',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
file: {
|
|
||||||
name: 'Gif',
|
name: 'Gif',
|
||||||
size: 17329,
|
size: 17329,
|
||||||
type: 'image/png',
|
type: 'image/png',
|
||||||
url:
|
url:
|
||||||
'https://user-images.githubusercontent.com/879561/51321923-54024f00-1a64-11e9-8c37-3308350a59c4.gif',
|
'https://user-images.githubusercontent.com/879561/51321923-54024f00-1a64-11e9-8c37-3308350a59c4.gif',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '3',
|
id: '3',
|
||||||
file: {
|
|
||||||
name: 'Paysage',
|
name: 'Paysage',
|
||||||
size: 17329,
|
size: 17329,
|
||||||
type: 'image/png',
|
type: 'image/png',
|
||||||
url:
|
url:
|
||||||
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSyHCXO8D0QQrPDuGstvH9dEwhhB7Qv-3mDMWGpLExyY1CF84cL',
|
'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcSyHCXO8D0QQrPDuGstvH9dEwhhB7Qv-3mDMWGpLExyY1CF84cL',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '4',
|
id: '4',
|
||||||
file: {
|
|
||||||
name: 'That kitten is so beautiful that I am not sure to have the place to describe it',
|
name: 'That kitten is so beautiful that I am not sure to have the place to describe it',
|
||||||
size: 17329,
|
size: 17329,
|
||||||
type: 'image/png',
|
type: 'image/png',
|
||||||
url:
|
url:
|
||||||
'https://images.pexels.com/photos/1643457/pexels-photo-1643457.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
|
'https://images.pexels.com/photos/1643457/pexels-photo-1643457.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '5',
|
id: '5',
|
||||||
file: {
|
|
||||||
name: 'pdf file',
|
name: 'pdf file',
|
||||||
type: 'pdf',
|
type: 'pdf',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '6',
|
id: '6',
|
||||||
file: {
|
|
||||||
name: 'Zip file',
|
name: 'Zip file',
|
||||||
type: 'zip',
|
type: 'zip',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '7',
|
id: '7',
|
||||||
file: {
|
|
||||||
name: 'Doc file',
|
name: 'Doc file',
|
||||||
type: 'docx',
|
type: 'docx',
|
||||||
},
|
},
|
||||||
},
|
|
||||||
],
|
],
|
||||||
onChange: () => {},
|
onChange: () => {},
|
||||||
selectedItems: [],
|
selectedItems: [],
|
||||||
|
|||||||
@ -19,9 +19,7 @@ const reducer = (state, action) => {
|
|||||||
}
|
}
|
||||||
const index = state.get('dataToDelete').findIndex(item => item === id);
|
const index = state.get('dataToDelete').findIndex(item => item === id);
|
||||||
|
|
||||||
return state.update('dataToDelete', dataToDelete => {
|
return state.removeIn(['dataToDelete', index]);
|
||||||
return dataToDelete.splice(index, 1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|||||||
@ -0,0 +1,89 @@
|
|||||||
|
import { fromJS } from 'immutable';
|
||||||
|
import reducer, { initialState } from '../reducer';
|
||||||
|
|
||||||
|
describe('Upload | containers | HomePage | reducer', () => {
|
||||||
|
it('should update data with received data', () => {
|
||||||
|
const state = initialState;
|
||||||
|
|
||||||
|
const receivedData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Capture d’écran 2020-02-25 à 15.43.44.png',
|
||||||
|
ext: '.png',
|
||||||
|
mime: 'image/png',
|
||||||
|
size: 146.25,
|
||||||
|
url: '/uploads/ba0c3352c4b14132aed3fcf3110b481c.png',
|
||||||
|
created_at: '2020-03-04T09:45:32.444Z',
|
||||||
|
updated_at: '2020-03-04T09:45:32.444Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'photo_2020-02-27 17.07.08.jpeg',
|
||||||
|
ext: '.jpeg',
|
||||||
|
mime: 'image/jpeg',
|
||||||
|
size: 140.64,
|
||||||
|
url: '/uploads/1d2ac677ea194b48bbe55ecec1b452d6.jpeg',
|
||||||
|
created_at: '2020-03-04T14:16:35.148Z',
|
||||||
|
updated_at: '2020-03-04T14:16:35.148Z',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: 'GET_DATA_SUCCEEDED',
|
||||||
|
data: receivedData,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedState = state.set('data', receivedData);
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expectedState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add a media to dataToDelete if value is true', () => {
|
||||||
|
const state = initialState;
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: 'ON_CHANGE_DATA_TO_DELETE',
|
||||||
|
value: true,
|
||||||
|
id: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedState = state.set('dataToDelete', fromJS([2]));
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expectedState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove a media to dataToDelete if value is false', () => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Capture d’écran 2020-02-25 à 15.43.44.png',
|
||||||
|
ext: '.png',
|
||||||
|
mime: 'image/png',
|
||||||
|
size: 146.25,
|
||||||
|
url: '/uploads/ba0c3352c4b14132aed3fcf3110b481c.png',
|
||||||
|
created_at: '2020-03-04T09:45:32.444Z',
|
||||||
|
updated_at: '2020-03-04T09:45:32.444Z',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'photo_2020-02-27 17.07.08.jpeg',
|
||||||
|
ext: '.jpeg',
|
||||||
|
mime: 'image/jpeg',
|
||||||
|
size: 140.64,
|
||||||
|
url: '/uploads/1d2ac677ea194b48bbe55ecec1b452d6.jpeg',
|
||||||
|
created_at: '2020-03-04T14:16:35.148Z',
|
||||||
|
updated_at: '2020-03-04T14:16:35.148Z',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const state = initialState.set('data', data).set('dataToDelete', fromJS([1, 2]));
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
type: 'ON_CHANGE_DATA_TO_DELETE',
|
||||||
|
id: 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedState = state.set('dataToDelete', fromJS([1]));
|
||||||
|
|
||||||
|
expect(reducer(state, action)).toEqual(expectedState);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user