Skip to content

Commit

Permalink
Merge b053275 into cea3572
Browse files Browse the repository at this point in the history
  • Loading branch information
judeinno committed Dec 20, 2018
2 parents cea3572 + b053275 commit 3613f03
Show file tree
Hide file tree
Showing 24 changed files with 799 additions and 5 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
APP_URL=https://ah-backend-thanos-staging.herokuapp.com/api
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"react-router-dom": "^4.3.1",
"react-toastify": "^4.4.3",
"react-twitter-auth": "^0.0.12",
"react-tagsinput": "^3.19.0",
"redux": "^4.0.1",
"redux-devtools-extension": "^2.13.7",
"redux-logger": "^3.0.6",
Expand Down
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
</body>

</html>
</html>
4 changes: 4 additions & 0 deletions src/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ exports[`Provider and App renders <Provider/> correctly 2`] = `
component={[Function]}
path="/profiles/edit"
/>
<Route
component={[Function]}
path="/createArticle"
/>
</Switch>
<Connect(Footer) />
</BrowserRouter>
Expand Down
4 changes: 4 additions & 0 deletions src/actions/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const ACTION_TYPE = {
POST_RATING_SUCCESS: 'POST_RATING_SUCCESS',
POST_RATING_FAILED: 'POST_RATING_FAILED',
POST_RATING_DATA: 'POST_RATING_DATA',
CREATE_ARTICLE_SUCCESS: 'CREATE_ARTICLE_SUCCESS',
CREATE_ARTICLE_FAILED: 'CREATE_ARTICLE_FAILED',
POST_ARTICLE_DATA: 'POST_ARTICLE_DATA',
UPDATE_IMAGE_URL: 'UPDATE_IMAGE_URL',
};

export default ACTION_TYPE;
62 changes: 62 additions & 0 deletions src/actions/createArticleActions/createArticleActions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import moxios from 'moxios';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import {
createArticleSuccess, createArticleThunk,
} from './index';
import ACTION_TYPE from '../actionTypes';
import APP_URL from '../../utils/constants';


describe('Create article Actions tests', () => {
let store;
let actionTypesData;
let response;
beforeEach(() => {
response = { title: 'going to school' };
const mockStore = configureMockStore([thunk]);
store = mockStore({});
actionTypesData = actionType => ({
type: actionType,
payload: response,
});
// import and pass your custom axios instance to this method
moxios.install();
});
afterEach(() => {
// import and pass your custom axios instance to this method
moxios.uninstall();
});
test('Successful get and post rating action', () => {
expect(createArticleSuccess(response)).toEqual(expect.objectContaining(
actionTypesData(ACTION_TYPE.CREATE_ARTICLE_SUCCESS),
));
});
test('Post article successfull', () => {
moxios.stubRequest(`${APP_URL}/articles`, {
status: 200,
response: { message: 'ok' },
});
store.dispatch(createArticleThunk()).then(() => {
expect(store.getActions()).toEqual(expect.objectContaining(
{
type: ACTION_TYPE.CREATE_ARTICLE_SUCCESS,
payload: { message: 'ok' },
},
));
});
});
test('Post article successfull', () => {
moxios.stubRequest(`${APP_URL}/articles`, {
status: 400,
responseText: { error: 'ok' },
});
store.dispatch(createArticleThunk()).then(() => {
expect(store.getActions()).toEqual(expect.objectContaining(
[{
type: ACTION_TYPE.CREATE_ARTICLE_FAILED,
}],
));
});
});
});
44 changes: 44 additions & 0 deletions src/actions/createArticleActions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import axios from 'axios';
import ACTION_TYPE from '../actionTypes';
import APP_URL from '../../utils/constants';

export const postArticleData = response => ({
type: ACTION_TYPE.POST_ARTICLE_DATA,
payload: response,
});

export const createArticleSuccess = response => ({
type: ACTION_TYPE.CREATE_ARTICLE_SUCCESS,
payload: response,
});

export const createArticleFailure = errorMessage => ({
type: ACTION_TYPE.CREATE_ARTICLE_FAILED,
errorMessage,
});

export const updateImageUrl = imageUrl => ({
type: ACTION_TYPE.UPDATE_IMAGE_URL,
payload: imageUrl,
});

const tok = localStorage.getItem('token');
export const createArticleThunk = data => (dispatch) => {
const userdata = {
...data,
};
const url = `${APP_URL}/articles`;
const token = `Token ${tok}`;
const headers = {
headers: { Authorization: token },
};
return axios.post(url, userdata, headers)
.then((res) => {
const resData = res.data.results;
dispatch(createArticleSuccess(resData));
}).catch((error) => {
const errorData = error.response.data;
dispatch(createArticleFailure(errorData));
});
};
export default createArticleThunk;
6 changes: 6 additions & 0 deletions src/actions/swalAlerts.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ const swalMessages = {
type: 'success',
confirmButtonText: 'continue',
},
CREATE_ARTICLE_SUCCESSFUL: {
title: 'Article created',
text: 'Your article was successfully created',
type: 'success',
confirmButtonText: 'continue',
},
};

export default swalMessages;
1 change: 1 addition & 0 deletions src/commons/initialStates.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const initialState = {
},
socialLoginReducer: { isLoggedIn: false },
loginReducer: { errorMessage: '', successMessage: '', user_details: '' },
createArticleReducer: {},
userReducer: {
freshUser: { email: '', password: '', username: '' },
},
Expand Down
2 changes: 2 additions & 0 deletions src/components/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Articles from '../../containers/Articles';
import ArticlePageConnected from '../../containers/ArticlePage';
import ProfileConnected from '../../containers/profiles/profiles';
import EditProfilePageConnected from '../../containers/profiles/editProfile';
import CreateArticlePage from '../../containers/CreateArticlePage';

library.add(faSearch);
const App = () => (
Expand All @@ -25,6 +26,7 @@ const App = () => (
<Route path="/article/:articleId" component={ArticlePageConnected} />
<Route path="/profile" component={ProfileConnected} />
<Route path="/profiles/edit" component={EditProfilePageConnected} />
<Route path="/createArticle" component={CreateArticlePage} />
</Switch>
<FooterConnected />
</React.Fragment>
Expand Down
50 changes: 50 additions & 0 deletions src/components/CreateArticle/CreateArticle.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@import url('https://fonts.googleapis.com/css?family=Roboto+Condensed');

#titleInput,
#descriptionInput,
#image_urlInput,
#tag_listInput {
height: 40px;
border-top: none;
border-left: none;
border-right: none;
}

#createArticleBt {
padding: 15px;
width: 30%;
background-color: #47d79f;
border: none;
font-family: "Roboto Condensed", sans-serif;
&:hover {
background-color: #3db184;
}

}
.artcileCreate{
font-family: "Roboto Condensed", sans-serif;
}
.createArticleTitle {
font-family: "Roboto Condensed", sans-serif;
}

.artcileCreate {
padding-bottom: 30px;
}
#bodyInput {
height: 500px;
}
.create-article-form {
width: 80%;
}

.image-upload{
color: turquoise !important;
border-color: turquoise !important; }

.image {
color: white;
}
input[type="file"] {
border-color: turquoise !important;
}
16 changes: 16 additions & 0 deletions src/components/CreateArticle/CreateArticle.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { shallow } from 'enzyme';
import CreateArticle from './index';

describe('<CreateArticle /> ', () => {
const CreateArticleComponent = shallow(
<CreateArticle
onChange={jest.fn()}
onSubmit={jest.fn()}
onClick={jest.fn()}
/>,
);
test('renders the component', () => {
expect(CreateArticleComponent).toMatchSnapshot();
});
});
122 changes: 122 additions & 0 deletions src/components/CreateArticle/__snapshots__/CreateArticle.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<CreateArticle /> renders the component 1`] = `
<div>
<br />
<h3
className="text-center createArticleTitle"
>
Create Your Article
</h3>
<hr
className="col-sm-8 "
/>
<br />
<div
className="col-sm-10 offset-2 artcileCreate"
>
<form
className="create-article-form"
onSubmit={[MockFunction]}
>
<h5>
Title:
</h5>
<small>
Title must be 130 characters maximum and 5 characters minimum
</small>
<div
className="form-group"
>
<textarea
className="form-control"
id="titleInput"
maxLength="130"
minLength="5"
name="title"
onChange={[MockFunction]}
required={true}
rows="3"
/>
</div>
<h5>
Description
</h5>
<small>
Title must be 150 characters maximum and 100 characters minimum
</small>
<div
className="form-group"
>
<textarea
className="form-control"
id="descriptionInput"
maxLength="120"
minLength="100"
name="description"
onChange={[MockFunction]}
required={true}
rows="3"
/>
</div>
<h5>
Tag list
</h5>
<div
className="form-group"
>
<textarea
className="form-control"
id="tag_listInput"
name="tag_list"
onChange={[MockFunction]}
required={true}
rows="3"
/>
</div>
<br />
<h5>
Upload Image
</h5>
<div
className="col-lg-8 mt-2"
>
<input
className="image"
name="image_url"
onClick={[MockFunction]}
type="file"
/>
</div>
<br />
<h5>
Body
</h5>
<div
className="form-group"
>
<textarea
className="form-control"
id="bodyInput"
name="body"
onChange={[MockFunction]}
required={true}
rows="3"
/>
</div>
<div
className="signin-createArticleBt"
>
<button
className="btn btn-primary"
id="createArticleBt"
name="createArticleBt"
type="submit"
>
Publish Article
</button>
</div>
</form>
</div>
</div>
`;
Loading

0 comments on commit 3613f03

Please sign in to comment.