Skip to content

Commit

Permalink
feat(view article): allow user view one article (#21)
Browse files Browse the repository at this point in the history
- Ensures that a user can view a single article.

[Delivers #163356764]
  • Loading branch information
SilasKenneth authored and dotNesh committed Jan 25, 2019
1 parent 281111e commit 8ffa669
Show file tree
Hide file tree
Showing 14 changed files with 813 additions and 16 deletions.
59 changes: 48 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint src/**/*.js src/**/*.jsx"
"lint": "eslint src/**/*.js src/**/*.jsx --fix"
},
"eslintConfig": {
"extends": "react-app"
Expand Down
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
homescreen on Android. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lora|Quicksand">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand Down
4 changes: 2 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SearchResultsPage from './components/Search/SearchResultsPage';
import Error from './components/ErrorHandlers/MissingPageError';
import ArticleContainer from './components/Articles/ArticlesContainer';
import LoginContainer from './components/Authentication/Login/LoginContainer';

import ViewSingleArticleComponent from "./container/viewArticleContainer";

class App extends Component {
render() {
Expand All @@ -21,7 +21,7 @@ class App extends Component {
<Route path="/register" component={RegistrationPage} exact />
<Route exact path="/login" component={LoginContainer} />
<Route path="/search" component={SearchResultsPage} exact />

<Route exact path='/articles/:slug' component={ViewSingleArticleComponent}/>
<Route component={Error} />
</Switch>
</BrowserRouter>
Expand Down
82 changes: 82 additions & 0 deletions src/actions/__tests__/viewArticlesActions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import thunk from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import moxios from 'moxios';
import * as actions from '../viewArticleActions';
import {getErr} from "../viewArticleActions";

const middleWare = [thunk];
const mockStore = configureMockStore(middleWare);

describe('Registration Actions', () => {
describe('register user', () => {
beforeEach(() => {
moxios.install();
});
afterEach(() => {
moxios.uninstall();
});

it('should return GET_ARTICLE action', () => {
const expectedAction = {
type: actions.ARTICLE_GET_DONE,
article: {},
};
const action = actions.articleGetDone({})
expect(action).toEqual(expectedAction);
});
it('', () => {
moxios.wait(() => {
const request = moxios.requests.mostRecent();
request.respondWith({
status: 200,
response: {},
});
});

const processing = true;
const processed = false;
const slug = "test";
const success = true;
const article = {};
const expectedActions = [
{ type: actions.ARTICLE_GET_PROCESSING, processing },
{ type: actions.ARTICLE_GET_DONE, article},
{type:actions.ARTICLE_GET_SUCCESS, success},
{ type: actions.ARTICLE_GET_PROCESSING, processing:processed },
];
const store = mockStore({ user: {}, expectedActions });
return store.dispatch(actions.fetchArticle(slug)).then(() => {
expect(store.getActions()).toEqual(expectedActions);
},
);
});

it('Returns an error on fail', () => {
moxios.wait(() => {
const request = moxios.requests.mostRecent();
request.respondWith({
status: 500,
response: {reason: "Some"},
});
});
const error = "Some";
const processing = true;
const processed = false;
const slug = "test";
const reason = getErr(error);
const success = false;
const article = {};
const expectedActions = [
{ type: actions.ARTICLE_GET_PROCESSING, processing },
{ type: actions.ARTICLE_GET_ERROR, reason: reason},
{ type: actions.ARTICLE_GET_PROCESSING, processing:processed },
{type:actions.ARTICLE_GET_SUCCESS, success},
];
const store = mockStore({ user: {}, expectedActions });
return store.dispatch(actions.fetchArticle(slug)).catch(() => {
expect(store.getActions()).toEqual(expectedActions);
},
);
});
});
});
42 changes: 42 additions & 0 deletions src/actions/viewArticleActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import axios from 'axios';

export const ARTICLE_GET_PROCESSING = 'ARTICLE_GET_PROCESSING';
export const articleGetProcessing = processing => ({
type: ARTICLE_GET_PROCESSING,
processing,
});

export const ARTICLE_GET_DONE = 'ARTICLE_GET_DONE';
export const articleGetDone = article => ({
type: ARTICLE_GET_DONE,
article,
});

export const ARTICLE_GET_ERROR = 'ARTICLE_GET_ERROR';
export const articleGetError = reason => ({
type: ARTICLE_GET_ERROR,
reason,
});

export const ARTICLE_GET_SUCCESS = 'ARTICLE_GET_SUCCESS';
export const articleGetSuccess = success => ({
type: ARTICLE_GET_SUCCESS,
success,
});

export const getErr = error => (error || 'Something went wrong');

export const fetchArticle = slug => (dispatch) => {
dispatch(articleGetProcessing(true));
return axios.get(
`https://ah-technocrats.herokuapp.com/api/articles/${slug}`,
).then((response) => {
dispatch(articleGetDone(response.data));
dispatch(articleGetSuccess(true));
dispatch(articleGetProcessing(false));
}).catch((error) => {
dispatch(articleGetError(getErr(error)));
dispatch(articleGetProcessing(false));
dispatch(articleGetSuccess(false));
});
};
Loading

0 comments on commit 8ffa669

Please sign in to comment.