Skip to content

Commit

Permalink
Merge 64d6dee into c038120
Browse files Browse the repository at this point in the history
  • Loading branch information
obayomi96 committed Sep 13, 2019
2 parents c038120 + 64d6dee commit 1146fdd
Show file tree
Hide file tree
Showing 19 changed files with 704 additions and 7 deletions.
112 changes: 112 additions & 0 deletions src/actions/__tests__/commentActions.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import nock from 'nock';
import { getComment, postComment } from '@Actions/commentActions';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
const url = 'https://a-haven-staging.herokuapp.com/api/v1';

describe('Comment action tests', () => {
describe('Get comments async actions', () => {
let store;
const response = {
data: {
data: {
comments: [],
},
},
};

beforeEach(() => {
store = mockStore({});
});

afterEach(() => {
nock.cleanAll();
});

it('gets comments succesfully', () => {
const articleId = 1;
store.dispatch(getComment(articleId))
.then(() => {
nock(url)
.get(`/comment/${articleId}`)
.reply(200, response);
})
.then(() => {
expect(store.getActions()).toMatchSnapShot();
});
});

it('Should error as expected', () => {
const articleId = null;
const errorResponse = {
err: {
response: {
data: {},
},
},
};
nock(url)
.get(`/comment/${articleId}`)
.reply(400, errorResponse.err);
store.dispatch(getComment(articleId))
.then(() => {
expect(store.getActions()).toMatchSnapShot();
});
});
});

describe('Create comment action test', () => {
let store;
const response = {
data: {
data: {
comments: [],
},
},
};

beforeEach(() => {
store = mockStore({});
});

afterEach(() => {
nock.cleanAll();
});

it('Create a comment successfully', () => {
const articleId = 2;
const comment = 'the test comment';
store.dispatch(postComment(comment, articleId))
.then(() => {
nock(url)
.post(`/comment/${articleId}`, comment)
.reply(201, response);
})
.then(() => {
expect(store.getActions()).toMatchSnapShot();
});
});

it('Should error as expected', () => {
const articleId = null;
const comment = null;
const errorResponse = {
err: {
response: {
data: {},
},
},
};
nock(url)
.post(`/comment/${articleId}`)
.reply(400, errorResponse.err);
store.dispatch(postComment(comment, articleId))
.then(() => {
expect(store.getActions()).toMatchSnapShot();
});
});
});
});
17 changes: 12 additions & 5 deletions src/actions/authActions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import jwtDecode from 'jwt-decode';
import { toast } from 'react-toastify';
import swal from '@sweetalert/with-react';
import {
SET_CURRENT_USER,
Expand All @@ -24,8 +23,12 @@ export const logIn = (userData, history) => async (dispatch) => {
setToken(user.token);
dispatch(setCurrentUser(jwtDecode(user.token)));
history.push('/');
toast.dismiss();
toast.success('Login Successful');
swal({
text: 'Login Successful',
icon: 'success',
buttons: false,
timer: 3000,
});
}
dispatch({
type: NOT_LOADING,
Expand All @@ -35,8 +38,12 @@ export const logIn = (userData, history) => async (dispatch) => {
});
} catch (err) {
const { error } = err.response.data;
toast.dismiss();
toast.error(error, { autoClose: 10000 });
swal({
text: error,
icon: 'error',
buttons: false,
timer: 5000,
});
return dispatch({
type: NOT_LOADING,
});
Expand Down
41 changes: 41 additions & 0 deletions src/actions/commentActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-disable import/prefer-default-export */
import {
GET_COMMENTS_SUCCESS,
GET_COMMENTS_FAILURE,
POST_COMMENTS_SUCCESS,
POST_COMMENTS_FAILURE,
LOADING,
} from '@Actions/types';
import { axiosInstance } from '@Utils/';

export const getComment = (articleId) => async (dispatch) => {
dispatch({ type: LOADING });
try {
const response = await axiosInstance.get(`comment/${articleId}`);
dispatch({
type: GET_COMMENTS_SUCCESS,
payload: response.data.data,
});
} catch (err) {
dispatch({
type: GET_COMMENTS_FAILURE,
payload: err.response.data,
});
}
};

export const postComment = (newComment, articleId) => async (dispatch) => {
dispatch({ type: LOADING });
try {
const response = await axiosInstance.post(`comment/${articleId}`, { comment: newComment });
dispatch({
type: POST_COMMENTS_SUCCESS,
payload: response.data.data,
});
} catch (err) {
dispatch({
type: POST_COMMENTS_FAILURE,
payload: err.response.data,
});
}
};
5 changes: 5 additions & 0 deletions src/actions/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ export const UPDATE_SUB = 'UPDATE_SUB';
export const UPDATE_CATEGORY_ARTICLES = 'UPDATE_CATEGORY_ARTICLES';
export const UPDATE_CATEGORY = 'UPDATE_CATEGORY';
export const UPDATE_MENU_ITEM = 'UPDATE_MENU_ITEM';

export const GET_COMMENTS_SUCCESS = 'GET_COMMENTS_SUCCESS';
export const GET_COMMENTS_FAILURE = 'GET_COMMENTS_FAILURE';
export const POST_COMMENTS_SUCCESS = 'POST_COMMENTS_SUCCESS';
export const POST_COMMENTS_FAILURE = 'POST_COMMENTS_FAILURE';
2 changes: 1 addition & 1 deletion src/components/ArticleCard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ArticleCard extends Component {
const comments = thousandths(comment.length);
const { loading, error } = this.state;
return (
<div className={`${type}`}>
<div className={`${type}`} data-test="articleCard-home">
<Link to={`/articles/${slug}`}>
<div className="image-container">
{loading === 0 ? <Skeleton width="100%" height="100%" /> : ''}
Expand Down
53 changes: 53 additions & 0 deletions src/components/Comment/Comment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import Icon from '@Components/Icon';
import { thousandths } from '@Utils/';
import './Comment.scss';

const Comment = (props) => {
const {
avatar, author, alt, body, createdAt, likesCount, dislikesCount,
} = props;

const likes = thousandths(likesCount);
const dislikes = thousandths(dislikesCount);
return (
<div className="comment-container">
<div className="comment-author-info">
<img className="comment-author-img" src={avatar} alt={alt} />
<div className="comment-p">
<p className="comment-author">{author}</p>
<p className="comment-date">{moment(createdAt).format('MMM DD')}</p>
<p className="comment-body">{body}</p>
</div>
</div>
<div className="icons">
<div className="singleIcon">
<Icon name="likes" className="like" />
<label className="icon-label">{likes}</label>
</div>
<div className="singleIcon">
<Icon name="dislikes" className="dislike" />
<label className="icon-label">{dislikes}</label>
</div>
</div>
</div>
);
};

Comment.propTypes = {
author: PropTypes.string.isRequired,
alt: PropTypes.string.isRequired,
avatar: PropTypes.string,
body: PropTypes.string.isRequired,
createdAt: PropTypes.string.isRequired,
likesCount: PropTypes.number.isRequired,
dislikesCount: PropTypes.number.isRequired,
};

Comment.defaultProps = {
avatar: 'https://via.placeholder.com/50',
};

export default Comment;
70 changes: 70 additions & 0 deletions src/components/Comment/Comment.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.comment-container {
background: rgba(196, 196, 196, 0.1);
display: flex;
width: 650px;
height: 100px;
margin: 20px auto;


.comment-author-info {
margin: auto;
width: 100%;
display: flex;

.comment-author-img {
margin: 10px 5px auto 10px;
border: 2px solid #ddd;
border-radius: 50%;
height: 60px;
width: 60px;
}

.comment-p {
margin: 10px auto auto 10px;

.comment-author {
font-style: normal;
font-weight: 600;
font-size: 11px;
line-height: 22px;
display: flex;
color: #000000;
}

.comment-date {
font-weight: 600;
font-size: 11px;
color: #FBC02A !important;
}

.comment-body {
width: 100%;
font-style: normal;
font-weight: 500;
font-size: 11px;
line-height: 22px;
display: block;
color: #000000;
}
}
}

.icons {
display: flex;
flex-direction: row;
align-items: center;
margin-top: 15px;
color:rgba(0, 0, 0, 0.8);

.singleIcon {
display: flex;
margin-right: 10px;

.like, .dislike {
display: flex;
align-items: center;
font-size: 10px;
}
}
}
}
27 changes: 27 additions & 0 deletions src/components/Comment/Comment.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import chai from 'chai';
import { shallow } from 'enzyme';
import Comment from '@Components/Comment';

chai.should();

describe('<Comment /> Component', () => {
let wrapper, props;

beforeEach(() => {
props = {
avatar: 'image.png',
author: 'author',
alt: 'author',
body: 'this is my comment',
createdAt: 'date',
likesCount: 34,
dislikesCount: 30,
};
wrapper = shallow(<Comment {...props} />);
});

it('Renders as expected', () => {
expect(wrapper.find('.comment-container')).toHaveLength(1);
});
});
3 changes: 3 additions & 0 deletions src/components/Comment/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Comment from './Comment';

export default Comment;
3 changes: 3 additions & 0 deletions src/components/Forms/SignUp/SignUp.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ export class SignUp extends Component {
style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center' }}
>
<Input
id="firstname"
name="firstname"
value={firstname}
type="text"
Expand All @@ -214,6 +215,7 @@ export class SignUp extends Component {
error={errors.firstname}
/>
<Input
id="lastname"
name="lastname"
value={lastname}
type="text"
Expand All @@ -223,6 +225,7 @@ export class SignUp extends Component {
error={errors.lastname}
/>
<Input
id="username"
name="username"
value={username}
type="text"
Expand Down
Loading

0 comments on commit 1146fdd

Please sign in to comment.