From c3317508b9d4562c654e721fd14859d677b10ad1 Mon Sep 17 00:00:00 2001 From: Marco Araujo Date: Thu, 5 Jan 2017 11:33:00 -0200 Subject: [PATCH 1/4] Update codecov.yml --- codecov.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index f253b79..8a8f4f3 100644 --- a/codecov.yml +++ b/codecov.yml @@ -4,7 +4,7 @@ codecov: require_ci_to_pass: true comment: behavior: default - layout: header, diff + layout: header, diff, sunburst require_changes: false coverage: precision: 2 @@ -26,3 +26,13 @@ parsers: javascript: enable_partials: false +status: + project: + default: + enabled: yes + target: auto + branches: null + threshold: null + if_no_uploads: error + if_not_found: success + if_ci_failed: error From 168458cb03d73c3b3dd5826eb96931b50438c6ae Mon Sep 17 00:00:00 2001 From: Marco Araujo Date: Thu, 5 Jan 2017 11:34:51 -0200 Subject: [PATCH 2/4] Tuning codecov.yml --- codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/codecov.yml b/codecov.yml index 8a8f4f3..d31ec33 100644 --- a/codecov.yml +++ b/codecov.yml @@ -36,3 +36,4 @@ status: if_no_uploads: error if_not_found: success if_ci_failed: error + From 90f5555c3a5bffc0f35e9c764c50c23c1612869f Mon Sep 17 00:00:00 2001 From: Gabriel Goncalves Date: Fri, 6 Jan 2017 14:59:43 -0200 Subject: [PATCH 3/4] * Create component to list areas * Create test to cover the component list area * Changing the test of menu * Adding item of navigation --- app/App.js | 4 +- app/components/Area/Area.js | 13 ---- app/components/Area/List/Area.js | 75 ++++++++++++++++++++++ app/components/Menu/Menu.js | 1 + tests/List.Area.test.js | 105 +++++++++++++++++++++++++++++++ tests/Menu.test.js | 3 +- 6 files changed, 186 insertions(+), 15 deletions(-) create mode 100644 app/components/Area/List/Area.js create mode 100644 tests/List.Area.test.js diff --git a/app/App.js b/app/App.js index 33ba226..8c09e77 100644 --- a/app/App.js +++ b/app/App.js @@ -6,7 +6,8 @@ import 'style-loader!css-loader!less-loader!font-awesome-webpack/font-awesome-st import iClientComponent from 'components/IClient/IClient' import HomeComponent from 'components/Home/Home' -import AreaComponent from 'components/Area/Area' +import AreaComponent from 'components/Area/List/Area' +import LastVisitsComponent from 'components/Area/Area' import ListClientComponent from 'components/Client/List/Client' import ProfileClientComponent from 'components/Client/Profile/Client' import SaveClientComponent from 'components/Client/Save/Client' @@ -25,6 +26,7 @@ ReactDOM.render( + , document.getElementById('app') diff --git a/app/components/Area/Area.js b/app/components/Area/Area.js index ac8cbf3..0fcba56 100644 --- a/app/components/Area/Area.js +++ b/app/components/Area/Area.js @@ -57,19 +57,6 @@ class Area extends React.Component } return (
-
-
-

iClient

-
-
- - - - - New Area - -
-
{ this.state.areas }
); diff --git a/app/components/Area/List/Area.js b/app/components/Area/List/Area.js new file mode 100644 index 0000000..56a5b9f --- /dev/null +++ b/app/components/Area/List/Area.js @@ -0,0 +1,75 @@ +import React from 'react'; +import { Link } from 'react-router' + +import AreaService from 'services/Area' + +import Error from 'components/Error/Error' + +class Area extends React.Component +{ + constructor(props) { + super(props); + this.state = { + areas : null, + error : '' + }; + this.getAreas(); + } + + getAreas() { + AreaService.getAll().then((response) => { + this.setState({areas: response.data.areas}); + }).catch((error) => { + this.setState({error: 'Error Found: Trying get area'}); + if (typeof error.response.data.error !== 'undefined') { + this.setState({error: error.response.data.error}); + } + }); + } + + render() { + if (this.state.error) { + return (); + } + if (!this.state.areas) { + return
Loading...
; + } + const areaList = this.state.areas.map((area, key) => { + let line = ((key % 2) ? 'is-success' : 'is-info'); + return ( + + + { area._id } + + + ); + }); + + return ( +
+
+
+
+

Areas

+
+
+ + + + + New Area + +
+
+ + + { areaList } + +
+
+
+ ); + } +} + +export default Area; diff --git a/app/components/Menu/Menu.js b/app/components/Menu/Menu.js index 06211bb..d750b4a 100644 --- a/app/components/Menu/Menu.js +++ b/app/components/Menu/Menu.js @@ -14,6 +14,7 @@ class Menu extends React.Component{ links: [ [ '/', 'Home'], ['/clients', 'Clients'], + ['/lastVisits', 'Last Visits'], ['/areas', 'Areas'] ] }; diff --git a/tests/List.Area.test.js b/tests/List.Area.test.js new file mode 100644 index 0000000..e358bda --- /dev/null +++ b/tests/List.Area.test.js @@ -0,0 +1,105 @@ +jest.enableAutomock(); +jest.dontMock('components/Area/List/Area'); +jest.dontMock('components/Error/Error'); +jest.dontMock('react'); +jest.dontMock('axios'); +jest.dontMock('axios-mock-adapter'); +jest.dontMock('enzyme'); +jest.dontMock('services/Area'); + +describe('Test Area', () => { + require('../tests/__mocks__/LocalStorageMock'); + + const React = require('react'); + const Enzyme = require('enzyme'); + const shallow = Enzyme.shallow; + + let axios = require('axios'); + let MockAdapter = require('axios-mock-adapter'); + + it('Area should show error message', (done) => { + + let response = {error:"Area Not Found"}; + let Area; + let component; + let mockAdapter = new MockAdapter(axios); + + mockAdapter.onGet(HOST + '/api/v1/area').reply(404, response); + + Area = require('components/Area/List/Area').default; + + component = shallow( + + ); + + setTimeout(() => { + try { + component.update(); + expect(component.render().text()).toEqual('Area Not Found'); + done(); + } catch (e) { + console.log(e); + } + + }, 0); + }); + + it('Area should show default error message', (done) => { + + let response = {}; + let Area; + let component; + let mockAdapter = new MockAdapter(axios); + + mockAdapter.onGet(HOST + '/api/v1/area').reply(503, response); + + Area = require('components/Area/List/Area').default; + + component = shallow( + + ); + + setTimeout(() => { + try { + component.update(); + expect(component.render().text()).toEqual('Error Found: Trying get area'); + done(); + } catch (e) { + console.log(e); + } + }, 0); + }); + + it('Area should show mocked data', (done) => { + + let response = { + areas: [ + {_id: 'South', parent: 'Center', ancestors: 'Center'}, + {_id: 'North', parent: 'Center', ancestors: 'Center'}, + ] + }; + let Area; + let component; + let mockAdapter = new MockAdapter(axios); + + mockAdapter.onGet(HOST + '/api/v1/area').reply(200, response); + + Area = require('components/Area/List/Area').default; + + component = shallow( + + ); + + setTimeout(() => { + try { + component.update(); + expect(component.find('tbody td').at(0).text()).toEqual('South'); + done(); + } catch (e) { + console.log(e); + } + }, 0); + }); + +}); + diff --git a/tests/Menu.test.js b/tests/Menu.test.js index ceb4b24..89140a4 100644 --- a/tests/Menu.test.js +++ b/tests/Menu.test.js @@ -21,6 +21,7 @@ describe('Test Menu', () => { let expectedLinks = [ ['/', 'Home'], ['/clients', 'Clients'], + ['/lastVisits', 'Last Visits'], ['/areas', 'Areas'], ]; @@ -55,7 +56,7 @@ describe('Test Menu', () => { expect(window.localStorage.getItem('token')).toEqual('test_menu'); expect(component.childAt(0).text()).toEqual(''); - expect(component.childAt(0).render().find('.nav-item.is-tab').length).toEqual(3); + expect(component.childAt(0).render().find('.nav-item.is-tab').length).toEqual(4); expect(component.childAt(1).text()).toEqual('Logout'); done(); }); From 4fea6ebeb4519b10de2a3c9573d12f2176c78d78 Mon Sep 17 00:00:00 2001 From: Gabriel Goncalves Date: Mon, 9 Jan 2017 14:22:20 -0200 Subject: [PATCH 4/4] * Create component to show datails of visites * Covering of test this component --- app/App.js | 3 +- app/components/Visit/Show/Visit.js | 78 ++++++++++++++++ app/components/Visit/Show/styles.css | 90 ++++++++++++++++++ app/helpers/DateHelper.js | 13 +++ app/services/Visit.js | 7 ++ tests/Show.Visit.test.js | 131 +++++++++++++++++++++++++++ 6 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 app/components/Visit/Show/Visit.js create mode 100644 app/components/Visit/Show/styles.css create mode 100644 app/helpers/DateHelper.js create mode 100644 tests/Show.Visit.test.js diff --git a/app/App.js b/app/App.js index 8c09e77..ed4ac20 100644 --- a/app/App.js +++ b/app/App.js @@ -12,6 +12,7 @@ import ListClientComponent from 'components/Client/List/Client' import ProfileClientComponent from 'components/Client/Profile/Client' import SaveClientComponent from 'components/Client/Save/Client' import CreateVisitComponent from 'components/Visit/Create/Visit' +import ShowVisitComponent from 'components/Visit/Show/Visit' import CreateAreaComponent from 'components/Area/Create/Area' ReactDOM.render( @@ -25,7 +26,7 @@ ReactDOM.render( - + , diff --git a/app/components/Visit/Show/Visit.js b/app/components/Visit/Show/Visit.js new file mode 100644 index 0000000..0ee99c1 --- /dev/null +++ b/app/components/Visit/Show/Visit.js @@ -0,0 +1,78 @@ +import React from 'react'; +import { Link } from 'react-router' + +import VisitService from 'services/Visit' +import Error from 'components/Error/Error' +import styles from 'components/Visit/Show/styles.css' +import DateHelper from 'helpers/DateHelper' + +class Visit extends React.Component +{ + constructor(props) { + super(props); + this.state = { + visit : null, + error: '' + }; + this.getVisit(this.props.params.id); + } + + getVisit(id) { + VisitService.find(id).then((response) => { + this.setState({visit: response.data.visit.shift()}); + }).catch((error) => { + this.setState({error: 'Error Found: Trying get visit'}); + let isValidResponse = typeof error.response.data !== 'undefined' + if (typeof error.response.data.error !== 'undefined') { + this.setState({error: error.response.data.error}); + } + }); + } + + render() { + if (this.state.error) { + return (); + } + if (!this.state.visit) { + return
Loading...
; + } + + return ( +
+
+
+
+
+ +
+
+
+

+ {this.state.visit.client.name} +

+

+ Visit Date: {DateHelper.formateDate(this.state.visit.visit_date)} +

+

+ Address: {this.state.visit.client.address} +

+

+ Area: {this.state.visit.client.area._id} +

+
+
+

R$ {this.state.visit.value_received}

+

Value Received

+
+
+

{this.state.visit.sales_quantity}

+

Sales Quantity

+
+
+
+
+ ); + } +} + +export default Visit; diff --git a/app/components/Visit/Show/styles.css b/app/components/Visit/Show/styles.css new file mode 100644 index 0000000..b77a0f4 --- /dev/null +++ b/app/components/Visit/Show/styles.css @@ -0,0 +1,90 @@ +body { + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; +} +.container.profile { + margin-top:50px; +} +.section.profile-visit { + padding-bottom: 50px!important; +} +.section.profile-visit .stat-key{ + font-weight: normal!important; + font-size: 14px!important; +} +.section.profile-visit .tagline { + padding: 20px 0; + line-height: 0.1; + font-size: 14px!important; +} + +.profile-heading .followers, .profile-heading .following { + border-right: 1px solid #f1f1f1; + margin: -30px 0; + padding: 70px 30px; +} +.profile-heading .likes { + margin: -30px 0; + padding: 70px 30px; + border-right:none!important; +} +.profile-heading .name { + border-right: 1px solid #f1f1f1; + margin:-30px 0; + padding: 40px 30px 0 30px; +} +.profile-heading .followers, .profile-heading .following { + border-right: 1px solid #f1f1f1; + margin:-30px 0; + padding: 70px 30px; +} +.profile-heading .likes { + margin:-30px 0; + padding: 70px 30px; +} +.profile-heading .stat-key { + font-size: 20px; + font-weight: 200; +} +.profile-heading .stat-val { + font-size: 35px; + font-weight: bold; +} +.profile-options { + background-color: #f1f1f1; + margin:-20px 0 20px 0; +} +.profile-options .link a { + padding:18px; + font-size: 18px; +} +.profile-options .link .icon { + font-size: 16px; + padding-top:2px; +} +.tagline { + padding:20px 0; + font-size: 16px; + line-height: 1.4; +} +.avatar { + float: right; +} +.follow { + float: right; +} +.avatar img { + border-radius: 200px; +} +p.title.is-bold { + font-weight: bold; +} +.card .timestamp { + float:right; + color:#bbb; +} +.profile-heading-color { + color: #333; +} +.color-black { + color: black !important; +} diff --git a/app/helpers/DateHelper.js b/app/helpers/DateHelper.js new file mode 100644 index 0000000..6fbcac9 --- /dev/null +++ b/app/helpers/DateHelper.js @@ -0,0 +1,13 @@ +const DateHelper = { + formateDate(date) { + let dateObj = new Date(date); + let options = { + day: '2-digit', + month: '2-digit', + year: 'numeric' + } + return dateObj.toLocaleDateString("en-US", options); + } +} + +export default DateHelper; diff --git a/app/services/Visit.js b/app/services/Visit.js index 8c46aa5..cf4c65d 100644 --- a/app/services/Visit.js +++ b/app/services/Visit.js @@ -22,6 +22,13 @@ const Visit = { save(data) { return axios.post(this.getEntryPoint().join('/'), data, this.getConfig()); + }, + + find(id) { + let url = this.getEntryPoint(); + url.push(id); + + return axios.get(url.join('/'), this.getConfig()); } }; diff --git a/tests/Show.Visit.test.js b/tests/Show.Visit.test.js new file mode 100644 index 0000000..260bcf2 --- /dev/null +++ b/tests/Show.Visit.test.js @@ -0,0 +1,131 @@ +jest.enableAutomock(); +jest.dontMock('components/Visit/Show/Visit'); +jest.dontMock('components/Error/Error'); +jest.dontMock('react'); +jest.dontMock('react-router'); +jest.dontMock('axios'); +jest.dontMock('axios-mock-adapter'); +jest.dontMock('enzyme'); +jest.dontMock('services/Visit'); +jest.dontMock('helpers/DateHelper'); + +describe('Test Visit', () => { + require('../tests/__mocks__/LocalStorageMock'); + + const React = require('react'); + const Enzyme = require('enzyme'); + const shallow = Enzyme.shallow; + const mount = Enzyme.mount; + + let axios = require('axios'); + let MockAdapter = require('axios-mock-adapter'); + + it('Visit should show mocked data', (done) => { + + let id = '123abc'; + let response = { + visit: [{ + visit_date: "2017-10-01", + value_received: 300, + sales_quantity: 150, + client: { + id: id, + name: 'Jon Snow', + address: '7 Street', + city: 'Winterfell', + ability: 200, + frequency: 10, + area: { + _id: 'Center', + parents: 'Center' + } + }, + }] + }; + let Visit; + let component; + let mockAdapter = new MockAdapter(axios); + + mockAdapter.onGet(HOST + '/api/v1/visit/' + id).reply(200, response); + + Visit = require('components/Visit/Show/Visit').default; + + component = mount( + + ); + + setTimeout(() => { + + try { + expect(component.find('.name p').at(0).text()).toEqual('Visit Date: 10/01/2017'); + expect(component.find('.name p').at(1).text()).toEqual('Address: 7 Street'); + expect(component.find('.name p').at(2).text()).toEqual('Area: Center'); + expect(component.find('.followers p').at(0).text()).toEqual('R$ 300'); + expect(component.find('.followers p').at(1).text()).toEqual('Value Received'); + expect(component.find('.likes p').at(0).text()).toEqual('150'); + expect(component.find('.likes p').at(1).text()).toEqual('Sales Quantity'); + done(); + } catch(e) { + console.log(e); + } + }, 0); + }); + + it('Visit should show error message', (done) => { + + let id = '123abc'; + let response = { error:"Visit Not Found" }; + let Visit; + let component; + let mockAdapter = new MockAdapter(axios); + + mockAdapter.onGet(HOST + '/api/v1/visit/' + id).reply(404, response); + + Visit = require('components/Visit/Show/Visit').default; + + component = shallow( + + ); + + setTimeout(() => { + + try { + component.update(); + expect(component.render().text()).toEqual('Visit Not Found'); + done(); + } catch(e) { + console.log(e); + } + }, 0); + }); + + it('Visit should show default error message', (done) => { + + let id = '123abc'; + let response = {}; + let Visit; + let component; + let mockAdapter = new MockAdapter(axios); + + mockAdapter.onGet(HOST + '/api/v1/visit/' + id).reply(503, response); + + Visit = require('components/Visit/Show/Visit').default; + + component = shallow( + + ); + + setTimeout(() => { + try { + component.update(); + expect(component.render().text()).toEqual('Error Found: Trying get visit'); + done(); + } catch(e) { + console.log(e); + } + }, 0); + }); + +}); + +