Skip to content

Commit

Permalink
Merge pull request #23 from andela/ft-rating-readtime-165412878
Browse files Browse the repository at this point in the history
#165412889 & #165412878 Add article rating and article read time
  • Loading branch information
Denis Niwemugisha authored and sengayire committed Jul 19, 2019
2 parents 9e07184 + 8eddf16 commit 3b01688
Show file tree
Hide file tree
Showing 49 changed files with 1,259 additions and 33 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
env:
global:
- NODE_ENV=test
- CI=true
- REACT_APP_URL_BACKEND=http://localhost:3000
- REACT_APP_URL_FRONTEND=http://localhost:5000
- CC_TEST_REPORTER_ID=d43031f55998206172c77fb2bc3c560af8d54e2747e10927abeea54ca5740e95
Expand Down
12 changes: 12 additions & 0 deletions src/__tests__/actions/articles/getPublished.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { getPublished } from '../../../actions/articles';
import article from '../../../__mocks__/article';

const dispatch = jest.fn(action => action);

describe('published article articles', () => {
it('returns publish information', async () => {
const result = getPublished()(dispatch);
expect(result).toHaveProperty('type');
expect(result).toHaveProperty('payload');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<RatingComponent /> should render a <CreateRatingComponent /> component 1`] = `ShallowWrapper {}`;
34 changes: 34 additions & 0 deletions src/__tests__/actions/rating/createRate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'react-thunk';
import { Provider } from 'react-redux';
import { createRate } from '../../../actions/rating';
import { Rating as RatingComponent } from '../../../components/Articles/Article/Rating';
import { shallow, mount } from '../../../../config/enzymeConfig';

describe('<RatingComponent />', () => {
const props = {
slug: 'slug-slug',
rating: 1,
errors: { error: ['12'] },
createRate: jest.fn(),
fetchOneArticle: jest.fn()
};
const rating = {
slug: 'slug-slug',
rating: 1
};
const component = shallow(<RatingComponent {...props} />);
it('should render a <CreateRatingComponent /> component ', () => {
expect(component).toMatchSnapshot();
});
const dispatch = jest.fn(action => action);

describe('Create rating', () => {
test('returns rating information', async () => {
const result = createRate(rating)(dispatch);
expect(result).toHaveProperty('type');
expect(result).toHaveProperty('payload');
});
});
});
87 changes: 87 additions & 0 deletions src/__tests__/components/Articles/Rating.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'react-thunk';
import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router-dom';
import { mockStore, initialState } from '../../../__mocks__/store';
import {
Rating as RatingComponent,
mapStateToProps
} from '../../../components/Articles/Article/Rating';
import { shallow, mount } from '../../../../config/enzymeConfig';

describe('<Article />', () => {
const props = {
message: 'Thank you for rating this article',
errors: { token: 'Failed to authenticate token' },
submitRate: jest.fn(),
createRate: jest.fn(),
closeMessage: jest.fn(),
ratingStars: jest.fn(),
fetchOneArticle: jest.fn(),
getSpecificArticle: jest.fn(),
isAuth: true,
slug: 'slug-article-12fg51x',
article: {
title: 'yes man',
rating: 1,
description: 'yes'
},
loading: false
};
const component = shallow(<RatingComponent {...props} />);
it('should create <RatingComponent /> snapshot ', () => {
expect(component).toMatchSnapshot();
});
it('should trigger submit rate ', () => {
component.setProps({ message: props.message, slug: props.slug, isAuth: true });
component.instance().submitRate(4);
});
it('should trigger close message ', () => {
component.setState({ message: { rating: 'updated' } });
component
.find('.rating-errors i')
.at(1)
.simulate('click');
component.instance().closeMessage();
});
it('should trigger close message ', () => {
component.setState({ message: { rating: 'updated' } });
component
.find('.rating-errors i')
.at(0)
.simulate('click');
component.instance().closeMessage();
});
it('should trigger submit rate ', () => {
component.setProps({ message: props.message, slug: props.slug, isAuth: false });
component.setState({ errors: { token: 'some' } });
component.instance().submitRate(4);
});
it('should trigger submit rate ', () => {
component.setProps({ message: props.message, slug: props.slug, isAuth: false });
component.setState({ errors: { token: 'token' } });
component.instance().submitRate(4);
});
it('should trigger submit rate ', () => {
component
.find('.one-star')
.at(1)
.simulate('click', 5);
});

it('should test map state', () => {
mapStateToProps({
user: { isAuth: true },
articles: { article: props.article },
rating: {
createRate: {
loading: false,
message: 'yes',
errors: { token: 'token' }
}
}
});
expect(mapStateToProps).toBeDefined();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Article /> should create <RatingComponent /> snapshot 1`] = `ShallowWrapper {}`;
100 changes: 100 additions & 0 deletions src/__tests__/components/Profile/MyArticles/Published.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'react-thunk';
import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router-dom';
import URL from '../../../../__mocks__/URL';
import articles from '../../../../__mocks__/articles';
import { mockStore, initialState } from '../../../../__mocks__/store';
import { PublishedArticles as PublishedArticlesComponent } from '../../../../components/Profile/Articles/MyArticles/Published';
import { mount, shallow } from '../../../../../config/enzymeConfig';

const props = {
errors: {},
article: {
title: 'Hello John Doe',
description: 'John Doe, Mocker',
body: 'body of the article',
slug: 'slug-slug-slug'
},
message: { message: 'Published' },
fetchOneArticle: jest.fn(),
history: {},
match: { params: { slug: 'slug-slug-slug' } },
publishArticle: jest.fn(),
unpublishArticle: jest.fn(),
deleteArticle: jest.fn(),
fileSelectedHandler: jest.fn(),
createObjectURL: jest.fn(),
getPublished: jest.fn()
};
const store = mockStore({
...initialState,
articles: { articles },
getPublished: jest.fn(true)
});
const state = {
article: {
title: 'Hello John Doe',
description: 'John Doe, Mocker',
body: JSON.stringify({
blocks: [
{
key: 'cnu26',
text: 'test componentWillReceiveProps failedtest componentWillReceiveProps failed',
type: 'unstyled',
depth: 0,
inlineStyleRanges: [
{ offset: 0, length: 74, style: 'color-rgb(36,41,46)' },
{ offset: 0, length: 74, style: 'bgcolor-rgb(255,255,255)' },
{ offset: 0, length: 74, style: 'fontsize-32' },
{
offset: 0,
length: 74,
style:
'fontfamily--apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol'
}
],
entityRanges: [],
data: { 'text-align': 'start' }
},
{
key: 'emuik',
text: 'Okey',
type: 'unstyled',
depth: 0,
inlineStyleRanges: [
{ offset: 0, length: 4, style: 'color-rgb(36,41,46)' },
{ offset: 0, length: 4, style: 'bgcolor-rgb(255,255,255)' },
{ offset: 0, length: 4, style: 'fontsize-32' },
{
offset: 0,
length: 4,
style:
'fontfamily--apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol'
}
],
entityRanges: [],
data: {}
}
],
entityMap: {}
}),
slug: 'slug-slug-slug'
},
message: { message: 'Published' },
getPublished: jest.fn()
};
describe('<PublishedArticlesComponent />', () => {
const component = shallow(<PublishedArticlesComponent {...props} />);
it('should render a <PublishedArticlesComponent /> component ', () => {
const component = mount(<Provider store={store}>
<MemoryRouter>
<PublishedArticlesComponent {...props} />
</MemoryRouter>
</Provider>);
});
it('should trigger publish ', () => {
component.setProps({ articles });
});
});
18 changes: 18 additions & 0 deletions src/__tests__/components/Routes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import Article from '../../components/Articles/Article/Article';
import CreateArticle from '../../components/Profile/Articles/CreateArticle';
import EditArticle from '../../components/Profile/Articles/EditArticle';
import PreviewArticle from '../../components/Profile/Articles/PreviewArticle';
import PublishedArticles from '../../components/Profile/Articles/MyArticles/Published';
import SearchArticles from '../../components/SearchArticles/SearchArticles';

describe('<Routes />', () => {
test('renders <Home /> without crashing', () => {
Expand Down Expand Up @@ -147,4 +149,20 @@ describe('<Routes />', () => {
</Provider>);
expect(component.find(PreviewArticle).length).toBe(1);
});
test('renders <PublishedArticles/> without crashing', () => {
const component = mount(<Provider store={store}>
<MemoryRouter initialEntries={['/profile/articles']}>
<Routes />
</MemoryRouter>
</Provider>);
expect(component.find(PublishedArticles).length).toBe(1);
});
test('renders <SearchArticles/> without crashing', () => {
const component = mount(<Provider store={store}>
<MemoryRouter initialEntries={['/search']}>
<Routes />
</MemoryRouter>
</Provider>);
expect(component.find(SearchArticles).length).toBe(1);
});
});
61 changes: 61 additions & 0 deletions src/__tests__/components/SearchArticles.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import { MemoryRouter, Link } from 'react-router-dom';
import { Provider } from 'react-redux';
import { configure, mount, shallow } from '../../../config/enzymeConfig';
import store from '../../__mocks__/store';
import SearchArticles from '../../components/SearchArticles/SearchArticles';

describe('<SearchArticles /> component', () => {
const searchArticles = jest.fn(() => ({ artcles: [], errors: '' }));
const props = {
articles: [
{
id: 1,
title: 'Hello John Doe',
description: 'John Doe, Mocker',
body: 'body of the article',
author: { username: 'prince' }
}
],
match: { params: { slug: 'slug-slug-slug' } },
SearchArticles: jest.fn()
};

const onOpenModal = jest.fn();
const component = mount(<Provider store={store}>
<MemoryRouter>
<SearchArticles {...props} />
</MemoryRouter>
</Provider>);

it('<SearchArticles />', () => {
expect(component).toHaveLength(1);
});
it('it open advanced seach', () => {
const testIt = component
.find('input[name="searchArticle"]')
.simulate('change', { target: { value: 'prince@gmail.com' } });
expect(testIt).toHaveLength(1);
});
it('it open advanced seach', () => {
const testIt = component.find('Link[testID="link-test"]').simulate('click', {});
expect(testIt).toHaveLength(1);
});
it('it open advanced search', () => {
component
.find('input[name="keyword"]')
.simulate('change', { target: { name: 'keyword', value: 'prince@gmail.com' } });

component
.find('input[name="author"]')
.simulate('change', { target: { name: 'author', value: 'prince@gmail.com' } });

component
.find('input[name="tag"]')
.simulate('change', { target: { name: 'tag', value: 'prince@gmail.com' } });

const testIt = component.find('Form[testID="seacrchForm"]');
testIt.simulate('submit');
expect(testIt).toHaveLength(1);
});
});
22 changes: 21 additions & 1 deletion src/__tests__/reducers/articlesReducers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,27 @@ describe('Articles reducers', () => {
});
expect(reducer.errors).toBeInstanceOf(Object);
});

it('FETCH_MY_PUBLISHED_ARTICLES_START', () => {
const reducer = articlesReducer(initialState, {
type: articlesType.FETCH_MY_PUBLISHED_ARTICLES_START,
payload: []
});
expect(reducer.errors).toBeInstanceOf(Object);
});
it('FETCH_MY_PUBLISHED_ARTICLES_SUCCESS', () => {
const reducer = articlesReducer(initialState, {
type: articlesType.FETCH_MY_PUBLISHED_ARTICLES_SUCCESS,
payload: { articles }
});
expect(reducer.articles).toBeInstanceOf(Array);
});
it('FETCH_MY_PUBLISHED_ARTICLES_FAILURE', () => {
const reducer = articlesReducer(initialState, {
type: articlesType.FETCH_MY_PUBLISHED_ARTICLES_FAILURE,
payload: { errors }
});
expect(reducer.errors).toBeInstanceOf(Object);
});
it('DEFAULT', () => {
articlesReducer(initialState, {
type: null,
Expand Down
Loading

0 comments on commit 3b01688

Please sign in to comment.