homepage reducer unit tests and some code review apply

Signed-off-by: Virginie Ky <virginie.ky@gmail.com>
This commit is contained in:
Virginie Ky 2020-03-05 16:13:44 +01:00
parent 8f24f1537c
commit aaead39d38
9 changed files with 149 additions and 137 deletions

View File

@ -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;

View File

@ -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,
}; };

View File

@ -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 = {

View File

@ -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;

View File

@ -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"]
}

View File

@ -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;

View File

@ -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: [],

View File

@ -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;

View File

@ -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);
});
});