Skip to content

Commit

Permalink
feat(follow and unfollow users) Users should be able to follow each o…
Browse files Browse the repository at this point in the history
…ther [#167484558]
  • Loading branch information
raymond42 committed Oct 23, 2019
2 parents 19aec06 + acc3f08 commit 0c05056
Show file tree
Hide file tree
Showing 33 changed files with 609 additions and 202 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
"dependencies": {
"@ckeditor/ckeditor5-build-classic": "^12.4.0",
"@ckeditor/ckeditor5-editor-classic": "^12.1.4",
"@ckeditor/ckeditor5-build-inline": "^12.4.0",
"@ckeditor/ckeditor5-image": "^14.0.0",
"@ckeditor/ckeditor5-react": "^1.1.3",
"axios": "^0.19.0",
"ckeditor-cloudinary-uploader-adapter": "^1.1.3",
Expand Down
20 changes: 0 additions & 20 deletions src/__mocks__/mockArticles.js

This file was deleted.

18 changes: 18 additions & 0 deletions src/__mocks__/mockData.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ export default {
body:
'is simply dummy text of the printing and typesetting industry Lorem Ipsum has'
},
article: {
title: 'Kigali the cleaniest city in Africa',
description:
'Kigali also known as a city of a thousand hills boasts itself with the cleaniest neighbourhood in Africa',
body:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry'
},
createResponse: {
articles: [
{
title: 'Kigali the cleaniest city in Africa',
description:
'Kigali also known as a city of a thousand hills boasts itself with the cleaniest neighbourhood in Africa',
body:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry'
}
]
},

returnedArticle: {
author: {
Expand Down
6 changes: 4 additions & 2 deletions src/app/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import UpdateProfile from '../feature/profile/update_profile/UpdateProfileCompon
import ForgotPassword from '../feature/Reset Password/forgot password/ForgotPasswordComponent';
import ResetPassword from '../feature/Reset Password/reset password/ResetPasswordComponent';
import FollowUnfollowComponent from '../feature/followUnfollow/FollowUnfollowComponent';
import Home from '../feature/homePage/Home';
// import SingleArticle from '../feature/article/getSingleArticle/ReadSingleArticleComponent';

toast.configure();
function App() {
return (
<div className="App">
<BrowserRouter>
{/* <Nav /> */}
<Home />
<ToastContainer />
<Switch>
<Route path="/forgot" component={ForgotPassword} />
Expand All @@ -36,9 +38,9 @@ function App() {
<Route path="/profile" component={Profile} />
<Route path="/update-profile" component={UpdateProfile} />
<Route path="/Signup" component={SignUp} />
<ProtectedRoutes path="/Create" component={CreateArticle} />
<Route path="/profiles/:userName/follow" component={FollowUnfollowComponent} />
<Route path="/profiles/:userName/unfollow" component={FollowUnfollowComponent} />
{/* // <Route path="/articles/:slug" component={SingleArticle} /> */}
<Route path="/articles/:slug" component={GetSingleArticle} />
</Switch>
</BrowserRouter>
Expand Down
1 change: 0 additions & 1 deletion src/app/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import resetPasswordReducer from '../../feature/Reset Password/reset password/re
import article from '../../feature/articles/createArticle/createArticleReducer';
import getAllArticles from '../../feature/articles/getArticles/GetAllArticleReducer';
import followReducer from '../../feature/followUnfollow/followUnfollowReducer';

import getSingleArticle from '../../feature/articles/getSingleArticle/GetSingleArticleReducer';
import socialReducer from '../../feature/auth/socialLogin/SocialReducer';

Expand Down
2 changes: 0 additions & 2 deletions src/feature/articles/__tests__/CreateArticleComponent.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import { shallow } from 'enzyme';
import '@ckeditor/ckeditor5-react';
import '@ckeditor/ckeditor5-build-classic';
import { CreateArticle } from '../createArticle/CreateArticleComponent';
import dummyData from '../../../__mocks__/mockData';

Expand Down
13 changes: 7 additions & 6 deletions src/feature/articles/__tests__/CreateComponentReducer.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
CREATE_ARTICLE_SUCCESS,
CREATE_ARTICLE_FAIL
} from '../constants';
import { CREATE_ARTICLE_SUCCESS, CREATE_ARTICLE_FAIL } from '../constants';
import createArticleReducer, {
initialState
} from '../createArticle/createArticleReducer';
Expand All @@ -17,8 +14,12 @@ describe('Create Article reducer', () => {
}
});
expect(reducer.title).toEqual('So I the last one standing');
expect(reducer.description).toEqual('I knew that would happen soon but i kept it inside');
expect(reducer.body).toEqual('I knew that would happen soon but i kept it inside');
expect(reducer.description).toEqual(
'I knew that would happen soon but i kept it inside'
);
expect(reducer.body).toEqual(
'I knew that would happen soon but i kept it inside'
);
});

it('Should test CREATE_ARTICLE_FAIL', () => {
Expand Down
1 change: 1 addition & 0 deletions src/feature/articles/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export const LIKE_ARTICLE_SUCCESS = 'GET_SINGLE_ARTICLE_SUCCESS';
export const DISLIKE_ARTICLE_FAIL = 'GET_SINGLE_ARTICLE_FAIL';
export const LIKE_ARTICLE_FAIL = 'GET_SINGLE_ARTICLE_SUCCESS';
export const DISLIKE_ARTICLE_SUCCESS = 'GET_SINGLE_ARTICLE_FAIL';
export const LOADING = 'LOADING';
8 changes: 4 additions & 4 deletions src/feature/articles/createArticle/CreateArticleComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import createArticle from './createArticleAction';
import editorConfigs from '../../../app/config/ckeditorConfig';
import 'react-toastify/dist/ReactToastify.css';
import './createArticle.scss';
import Home from '../../homePage/Home';
// import Home from '../../homePage/Home';

export class CreateArticle extends Component {
constructor(props) {
Expand All @@ -32,7 +32,7 @@ export class CreateArticle extends Component {
title, description, tags, category, body
} = this.state;
const { createArticle } = this.props;
const test = (!title || !description || !body);
const test = !title || !description || !body;
const message = 'Please fill in Title, Description and Body to create an article';
return test
? toast.error(message, { position: toast.POSITION.TOP_CENTER })
Expand All @@ -54,7 +54,7 @@ export class CreateArticle extends Component {
} = this.state;
return (
<>
<Home />
{/* <Home /> */}
<div className="mainDiv">
<div className="input input--form">
<input
Expand Down Expand Up @@ -116,7 +116,7 @@ export class CreateArticle extends Component {
type="submit"
onClick={this.handleSubmit}
>
Create
Create
</button>
</div>
</div>
Expand Down
10 changes: 7 additions & 3 deletions src/feature/articles/getArticles/GetAllArticleReducer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { GET_ARTICLES_SUCCESS, GET_ARTICLES_FAIL } from '../constants';
import { GET_ARTICLES_SUCCESS, GET_ARTICLES_FAIL, LOADING } from '../constants';

export const initialState = {
articles: []
articles: [],
loading: true
};

export default (state = initialState, action) => {
Expand All @@ -10,10 +11,13 @@ export default (state = initialState, action) => {
case GET_ARTICLES_SUCCESS:
return {
...state,
...payload
...payload,
loading: false
};
case GET_ARTICLES_FAIL:
return { ...state, ...payload };
case LOADING:
return { ...state, ...payload };
default:
return {
...state
Expand Down
12 changes: 9 additions & 3 deletions src/feature/articles/getArticles/GetAllArticlesAction.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import axios from 'axios';
import { toast } from 'react-toastify';
import { GET_ARTICLES_SUCCESS, GET_ARTICLES_FAIL } from '../constants';
import { GET_ARTICLES_SUCCESS, GET_ARTICLES_FAIL, LOADING } from '../constants';
import { BACKEND_URL } from '../../../app/common/config/appConfig';

const getAllArticles = () => async dispatch => {
try {
dispatch({
type: LOADING,
payload: true
});
// const res = await axios.get('http://localhost:4000/api/v1/articles/');
// console.log(res);

const res = await axios.get(`${BACKEND_URL}/articles/`);

dispatch({
type: GET_ARTICLES_SUCCESS,
payload: res.data
});
return true;
} catch (err) {
const error = (await err.response)
? err.response.data.error
: 'SERVER ERROR! Please contact the administartor';
: 'SERVER ERROR!  Please contact the administartor';
dispatch({ type: GET_ARTICLES_FAIL, payload: error });
toast.error(error, { position: toast.POSITION.TOP_CENTER });
}
Expand Down
36 changes: 15 additions & 21 deletions src/feature/articles/getArticles/GetAllArticlesComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,19 @@ import getImage from '../../../app/helpers/getImage';
import defautImage from '../../../app/common/images/defaultImage.png';
import avatar from '../../../app/common/images/avatar.png';
import getAllArticles from './GetAllArticlesAction';
import Home from '../../homePage/Home';
import LikeDilsikeArticle from '../likeDislikeArticles/LikeDislikeComponent';
import './GetAllArticles.scss';

export class GetAllArticles extends Component {
constructor() {
super();
this.state = {
loading: false
};
}

componentDidMount() {
this.setState({
loading: true
});
this.props.getAllArticles();
setTimeout(() => {
this.setState({
loading: false
});
}, 2000);
}

render() {
const { loading } = this.state;
const { articles } = this.props;
const { articles, loading } = this.props;
return (
<>
<Home />
{/* <Home /> */}
<div className="mainDiv">
<div className="main--banner">
<div className="main--banner__text">
Expand All @@ -56,7 +40,11 @@ export class GetAllArticles extends Component {
<div className="main-content">
{articles.length !== 0 ? (
articles.map(article => (
<Link to="#!" key={article.slug} className="link">
<Link
to={`/articles/${article.slug}`}
key={article.slug}
className="link"
>
<div className="article article-main--wrapper">
<div className="article__image">
<img
Expand Down Expand Up @@ -94,6 +82,11 @@ export class GetAllArticles extends Component {
{article.description}
</div>
</div>
<hr className="divider" />
<LikeDilsikeArticle
likes={article.likes}
dislikes={article.dislikes}
/>
</div>
</div>
</Link>
Expand All @@ -117,7 +110,8 @@ export class GetAllArticles extends Component {
}

const mapStateToProps = state => ({
articles: state.getAllArticles.articles
articles: state.getAllArticles.articles,
loading: state.getAllArticles.loading
});

export default connect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,36 @@ describe('Create Article success', () => {
store.clearActions();
});

test('Should return GET_ARTICLES_SUCCESS action', () => {
test('Should return GET_ARTICLES_SUCCESS action', async () => {
moxios.wait(() => {
const request = moxios.requests.mostRecent();
request.respondWith({
status: 200
});
});
const expectedAction = [GET_ARTICLES_SUCCESS];
return store.dispatch(getAllArticles()).then(() => {
const expectedAction = GET_ARTICLES_SUCCESS;
await store.dispatch(getAllArticles()).then(() => {
const dispatchedActions = store.getActions();

const dispatchedTypes = dispatchedActions.map(action => action.type);
expect(dispatchedTypes).toEqual(expectedAction);
expect(dispatchedTypes[1]).toEqual(expectedAction);
});
});
test('Should return GET_ARTICLES_FAIL action', () => {
test('Should return GET_ARTICLES_FAIL action', async () => {
moxios.wait(() => {
const request = moxios.requests.mostRecent();
request.respondWith({
request.respondWith({
status: 404,
response: {
error: 'No articles found at the monent'
}
});
});
const expectedAction = [GET_ARTICLES_FAIL];
return store.dispatch(getAllArticles()).then(() => {
const expectedAction = GET_ARTICLES_FAIL;
await store.dispatch(getAllArticles()).then(() => {
const dispatchedActions = store.getActions();

const dispatchedTypes = dispatchedActions.map(action => action.type);
expect(dispatchedTypes).toEqual(expectedAction);
expect(dispatchedTypes[1]).toEqual(expectedAction);
});
});
});
Loading

0 comments on commit 0c05056

Please sign in to comment.