how to test react routes with connected components
I am trying to follow this guide here but it does not show how to do it with connected components https://medium.com/@antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303
so far i have managed to get the following test
import React from 'react';
import ReactDOM from 'react-dom';
import { mount, shallow } from 'enzyme';
import { MemoryRouter } from 'react-router';
//START imports from APP
import Admin from '../../app/components/admin/admin';
import AggregateView from '../../app/components/commsmatrix/aggregate_view';
import Approve from '../../app/components/commsmatrix/approve';
...
import UAM from '../../app/components/reports/UAM';
import WorkerJobs from '../../app/components/reports/workerjobs';
//END imports from APP
import App from '../../app/App';
const jQuery = require('jquery');
window.jQuery = window.$ = jQuery;
import configureStore from 'redux-mock-store';
import promise from 'redux-promise';
const modals = {confirmTitle: ''};
//create any initial state needed
const initialState = { activeUser: {id:1}, modals };
// here it is possible to pass in any middleware if needed into //configureStore
const middlewares = [promise]
const mockStore = configureStore(middlewares);
const mockedCallback = () => Promise.resolve();
test('valid path should not redirect to 404', () => {
let store = mockStore(initialState)
const wrapper = shallow(mount(
<MemoryRouter initialEntries={[ '/' ]}>
<App store={store} modals = {modals} />
</MemoryRouter>
) );
expect(wrapper.find(HomeContent)).toHaveLength(1);
});
It is now throwing an error which i cannot seem to solve. TypeError: ShallowWrapper can only wrap valid elements
UPDATE
if i remove shallow i get
(node:45153) UnhandledPromiseRejectionWarning: SyntaxError: The string did not match the expected pattern.
at XMLHttpRequest.open (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:482:15)
at dispatchXhrRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:45:13)
at new Promise (<anonymous>)
at xhrAdapter (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:12:10)
at dispatchRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/core/dispatchRequest.js:59:10)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
(node:45153) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:45153) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
if i remove mount i get
Expected value to have length:
1
Received:
{Symbol(enzyme.__root__): {Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/"]}><withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): {"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}, Symbol(enzyme.__nodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}}, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): , Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}, Symbol(enzyme.__rootNodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}]}
received.length:
0
70 | </MemoryRouter>
71 | ) ;
> 72 | expect(wrapper.find(HomeContent)).toHaveLength(1);
73 | });
74 |
content of home
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchContents } from '../actions';
import { Link } from 'react-router-dom';
import { fetchActiveUser } from '../actions/index';
import { bindActionCreators } from 'redux';
export class HomeContent extends Component {
constructor(props){
super(props);
this.state = {
message: '',
data:
}
this.meta = { title: 'Home', description: '' };
this.runOnce = false;
this.passMetaBack = this.passMetaBack.bind(this);
}
passMetaBack = () => {
this.props.passMetaBack(this.meta);
}
componentDidMount() {
document.title = "Home | Connectivity Compliance Portal (CCP)";
this.passMetaBack();
}
htmlDecode(input){
let e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
initData(){
if(this.props.isReady && this.props.priv != undefined){
let self = this;
this.props.fetchContents()
.then(response => {
let data = response.payload.data;
if (data.header.error) {
self.handleShowError({
show: true,
errorMsg: data.header.message
});
} else {
self.setState({
data: _.mapKeys(data.body.recordset.record, 'target')
});
}
})
}
}
renderContent(classname) {
if(Object.keys(this.state.data).length>0 ){
let content = this.props.content[classname].content;
return (
<div dangerouslySetInnerHTML={{ __html: content}} />
);
}
}
render() {
if(!this.runOnce && this.props.isReady){
this.runOnce = true;
this.initData();
}
return (
<div className="container-fluid">
<div className="row-fluid" >
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">INTRODUCTION</h3>
</div>
<div className="panel-body panel_introduction ql-editor">
{this.renderContent('panel_introduction')}
</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">Whats New!</h3>
</div>
<div className="panel-body panel_whats_new ql-editor">{this.renderContent('panel_whats_new')}</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">DISCLAIMER</h3>
</div>
<div className="panel-body panel_disclaimer ql-editor">{this.renderContent('panel_disclaimer')}</div>
</div>
</div>
<div className="modal fade bs-example-modal-lg" id="modalIntro" tabIndex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title" id="myModalLabel">Welcome to the Connectivity Compliance Portal (CCP)</h4>
</div>
<div className="modal-body">
You are receiving this message as you are a guest and require elevated privileges to make best use of the service. In order to do this you'll need to:
<ol start="1">
<li>Go to <a target="_blank" href="https://iam.com/identity" target="_blank" >WIAM (https://iam.com/identity)</a></li>
<li>Click on <i>"Request Access"</i> at the top</li>
<li>Search for <i>"CCP"</i></li>
<li>Select the relevant group and add it to the cart</li>
<li>Check Out!</li>
</ol>
<p>You can confirm if you have been added to the group by going to <Link to={`/ldapuser`}>https://ccp.com/ldapuser</Link>. Once you see you have been added to the group log out of CCP and log back in and you should have the correct permissions. The process can take a few hours to a couple of days depending on how long the approvers take.</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return { content: state.content }
}
//Anything returned from this function will end up as props
//on this container
function mapDispatchToProps(dispatch){
// Whenever getUser is called, the result should be passed
// to all our reducers
return bindActionCreators({ fetchContents, fetchActiveUser }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeContent);
I have crated a sandbox as best i can. is this correct? https://codesandbox.io/s/9yyvnrkrrp
reactjs jestjs enzyme
add a comment |
I am trying to follow this guide here but it does not show how to do it with connected components https://medium.com/@antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303
so far i have managed to get the following test
import React from 'react';
import ReactDOM from 'react-dom';
import { mount, shallow } from 'enzyme';
import { MemoryRouter } from 'react-router';
//START imports from APP
import Admin from '../../app/components/admin/admin';
import AggregateView from '../../app/components/commsmatrix/aggregate_view';
import Approve from '../../app/components/commsmatrix/approve';
...
import UAM from '../../app/components/reports/UAM';
import WorkerJobs from '../../app/components/reports/workerjobs';
//END imports from APP
import App from '../../app/App';
const jQuery = require('jquery');
window.jQuery = window.$ = jQuery;
import configureStore from 'redux-mock-store';
import promise from 'redux-promise';
const modals = {confirmTitle: ''};
//create any initial state needed
const initialState = { activeUser: {id:1}, modals };
// here it is possible to pass in any middleware if needed into //configureStore
const middlewares = [promise]
const mockStore = configureStore(middlewares);
const mockedCallback = () => Promise.resolve();
test('valid path should not redirect to 404', () => {
let store = mockStore(initialState)
const wrapper = shallow(mount(
<MemoryRouter initialEntries={[ '/' ]}>
<App store={store} modals = {modals} />
</MemoryRouter>
) );
expect(wrapper.find(HomeContent)).toHaveLength(1);
});
It is now throwing an error which i cannot seem to solve. TypeError: ShallowWrapper can only wrap valid elements
UPDATE
if i remove shallow i get
(node:45153) UnhandledPromiseRejectionWarning: SyntaxError: The string did not match the expected pattern.
at XMLHttpRequest.open (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:482:15)
at dispatchXhrRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:45:13)
at new Promise (<anonymous>)
at xhrAdapter (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:12:10)
at dispatchRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/core/dispatchRequest.js:59:10)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
(node:45153) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:45153) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
if i remove mount i get
Expected value to have length:
1
Received:
{Symbol(enzyme.__root__): {Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/"]}><withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): {"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}, Symbol(enzyme.__nodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}}, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): , Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}, Symbol(enzyme.__rootNodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}]}
received.length:
0
70 | </MemoryRouter>
71 | ) ;
> 72 | expect(wrapper.find(HomeContent)).toHaveLength(1);
73 | });
74 |
content of home
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchContents } from '../actions';
import { Link } from 'react-router-dom';
import { fetchActiveUser } from '../actions/index';
import { bindActionCreators } from 'redux';
export class HomeContent extends Component {
constructor(props){
super(props);
this.state = {
message: '',
data:
}
this.meta = { title: 'Home', description: '' };
this.runOnce = false;
this.passMetaBack = this.passMetaBack.bind(this);
}
passMetaBack = () => {
this.props.passMetaBack(this.meta);
}
componentDidMount() {
document.title = "Home | Connectivity Compliance Portal (CCP)";
this.passMetaBack();
}
htmlDecode(input){
let e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
initData(){
if(this.props.isReady && this.props.priv != undefined){
let self = this;
this.props.fetchContents()
.then(response => {
let data = response.payload.data;
if (data.header.error) {
self.handleShowError({
show: true,
errorMsg: data.header.message
});
} else {
self.setState({
data: _.mapKeys(data.body.recordset.record, 'target')
});
}
})
}
}
renderContent(classname) {
if(Object.keys(this.state.data).length>0 ){
let content = this.props.content[classname].content;
return (
<div dangerouslySetInnerHTML={{ __html: content}} />
);
}
}
render() {
if(!this.runOnce && this.props.isReady){
this.runOnce = true;
this.initData();
}
return (
<div className="container-fluid">
<div className="row-fluid" >
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">INTRODUCTION</h3>
</div>
<div className="panel-body panel_introduction ql-editor">
{this.renderContent('panel_introduction')}
</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">Whats New!</h3>
</div>
<div className="panel-body panel_whats_new ql-editor">{this.renderContent('panel_whats_new')}</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">DISCLAIMER</h3>
</div>
<div className="panel-body panel_disclaimer ql-editor">{this.renderContent('panel_disclaimer')}</div>
</div>
</div>
<div className="modal fade bs-example-modal-lg" id="modalIntro" tabIndex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title" id="myModalLabel">Welcome to the Connectivity Compliance Portal (CCP)</h4>
</div>
<div className="modal-body">
You are receiving this message as you are a guest and require elevated privileges to make best use of the service. In order to do this you'll need to:
<ol start="1">
<li>Go to <a target="_blank" href="https://iam.com/identity" target="_blank" >WIAM (https://iam.com/identity)</a></li>
<li>Click on <i>"Request Access"</i> at the top</li>
<li>Search for <i>"CCP"</i></li>
<li>Select the relevant group and add it to the cart</li>
<li>Check Out!</li>
</ol>
<p>You can confirm if you have been added to the group by going to <Link to={`/ldapuser`}>https://ccp.com/ldapuser</Link>. Once you see you have been added to the group log out of CCP and log back in and you should have the correct permissions. The process can take a few hours to a couple of days depending on how long the approvers take.</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return { content: state.content }
}
//Anything returned from this function will end up as props
//on this container
function mapDispatchToProps(dispatch){
// Whenever getUser is called, the result should be passed
// to all our reducers
return bindActionCreators({ fetchContents, fetchActiveUser }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeContent);
I have crated a sandbox as best i can. is this correct? https://codesandbox.io/s/9yyvnrkrrp
reactjs jestjs enzyme
shallow(mount(
- it should be eithershallow()
ormount()
but not both
– skyboyer
Nov 22 '18 at 19:41
I added UPDATE for shallow and mount
– shorif2000
Nov 23 '18 at 10:41
add a comment |
I am trying to follow this guide here but it does not show how to do it with connected components https://medium.com/@antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303
so far i have managed to get the following test
import React from 'react';
import ReactDOM from 'react-dom';
import { mount, shallow } from 'enzyme';
import { MemoryRouter } from 'react-router';
//START imports from APP
import Admin from '../../app/components/admin/admin';
import AggregateView from '../../app/components/commsmatrix/aggregate_view';
import Approve from '../../app/components/commsmatrix/approve';
...
import UAM from '../../app/components/reports/UAM';
import WorkerJobs from '../../app/components/reports/workerjobs';
//END imports from APP
import App from '../../app/App';
const jQuery = require('jquery');
window.jQuery = window.$ = jQuery;
import configureStore from 'redux-mock-store';
import promise from 'redux-promise';
const modals = {confirmTitle: ''};
//create any initial state needed
const initialState = { activeUser: {id:1}, modals };
// here it is possible to pass in any middleware if needed into //configureStore
const middlewares = [promise]
const mockStore = configureStore(middlewares);
const mockedCallback = () => Promise.resolve();
test('valid path should not redirect to 404', () => {
let store = mockStore(initialState)
const wrapper = shallow(mount(
<MemoryRouter initialEntries={[ '/' ]}>
<App store={store} modals = {modals} />
</MemoryRouter>
) );
expect(wrapper.find(HomeContent)).toHaveLength(1);
});
It is now throwing an error which i cannot seem to solve. TypeError: ShallowWrapper can only wrap valid elements
UPDATE
if i remove shallow i get
(node:45153) UnhandledPromiseRejectionWarning: SyntaxError: The string did not match the expected pattern.
at XMLHttpRequest.open (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:482:15)
at dispatchXhrRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:45:13)
at new Promise (<anonymous>)
at xhrAdapter (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:12:10)
at dispatchRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/core/dispatchRequest.js:59:10)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
(node:45153) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:45153) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
if i remove mount i get
Expected value to have length:
1
Received:
{Symbol(enzyme.__root__): {Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/"]}><withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): {"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}, Symbol(enzyme.__nodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}}, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): , Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}, Symbol(enzyme.__rootNodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}]}
received.length:
0
70 | </MemoryRouter>
71 | ) ;
> 72 | expect(wrapper.find(HomeContent)).toHaveLength(1);
73 | });
74 |
content of home
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchContents } from '../actions';
import { Link } from 'react-router-dom';
import { fetchActiveUser } from '../actions/index';
import { bindActionCreators } from 'redux';
export class HomeContent extends Component {
constructor(props){
super(props);
this.state = {
message: '',
data:
}
this.meta = { title: 'Home', description: '' };
this.runOnce = false;
this.passMetaBack = this.passMetaBack.bind(this);
}
passMetaBack = () => {
this.props.passMetaBack(this.meta);
}
componentDidMount() {
document.title = "Home | Connectivity Compliance Portal (CCP)";
this.passMetaBack();
}
htmlDecode(input){
let e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
initData(){
if(this.props.isReady && this.props.priv != undefined){
let self = this;
this.props.fetchContents()
.then(response => {
let data = response.payload.data;
if (data.header.error) {
self.handleShowError({
show: true,
errorMsg: data.header.message
});
} else {
self.setState({
data: _.mapKeys(data.body.recordset.record, 'target')
});
}
})
}
}
renderContent(classname) {
if(Object.keys(this.state.data).length>0 ){
let content = this.props.content[classname].content;
return (
<div dangerouslySetInnerHTML={{ __html: content}} />
);
}
}
render() {
if(!this.runOnce && this.props.isReady){
this.runOnce = true;
this.initData();
}
return (
<div className="container-fluid">
<div className="row-fluid" >
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">INTRODUCTION</h3>
</div>
<div className="panel-body panel_introduction ql-editor">
{this.renderContent('panel_introduction')}
</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">Whats New!</h3>
</div>
<div className="panel-body panel_whats_new ql-editor">{this.renderContent('panel_whats_new')}</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">DISCLAIMER</h3>
</div>
<div className="panel-body panel_disclaimer ql-editor">{this.renderContent('panel_disclaimer')}</div>
</div>
</div>
<div className="modal fade bs-example-modal-lg" id="modalIntro" tabIndex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title" id="myModalLabel">Welcome to the Connectivity Compliance Portal (CCP)</h4>
</div>
<div className="modal-body">
You are receiving this message as you are a guest and require elevated privileges to make best use of the service. In order to do this you'll need to:
<ol start="1">
<li>Go to <a target="_blank" href="https://iam.com/identity" target="_blank" >WIAM (https://iam.com/identity)</a></li>
<li>Click on <i>"Request Access"</i> at the top</li>
<li>Search for <i>"CCP"</i></li>
<li>Select the relevant group and add it to the cart</li>
<li>Check Out!</li>
</ol>
<p>You can confirm if you have been added to the group by going to <Link to={`/ldapuser`}>https://ccp.com/ldapuser</Link>. Once you see you have been added to the group log out of CCP and log back in and you should have the correct permissions. The process can take a few hours to a couple of days depending on how long the approvers take.</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return { content: state.content }
}
//Anything returned from this function will end up as props
//on this container
function mapDispatchToProps(dispatch){
// Whenever getUser is called, the result should be passed
// to all our reducers
return bindActionCreators({ fetchContents, fetchActiveUser }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeContent);
I have crated a sandbox as best i can. is this correct? https://codesandbox.io/s/9yyvnrkrrp
reactjs jestjs enzyme
I am trying to follow this guide here but it does not show how to do it with connected components https://medium.com/@antonybudianto/react-router-testing-with-jest-and-enzyme-17294fefd303
so far i have managed to get the following test
import React from 'react';
import ReactDOM from 'react-dom';
import { mount, shallow } from 'enzyme';
import { MemoryRouter } from 'react-router';
//START imports from APP
import Admin from '../../app/components/admin/admin';
import AggregateView from '../../app/components/commsmatrix/aggregate_view';
import Approve from '../../app/components/commsmatrix/approve';
...
import UAM from '../../app/components/reports/UAM';
import WorkerJobs from '../../app/components/reports/workerjobs';
//END imports from APP
import App from '../../app/App';
const jQuery = require('jquery');
window.jQuery = window.$ = jQuery;
import configureStore from 'redux-mock-store';
import promise from 'redux-promise';
const modals = {confirmTitle: ''};
//create any initial state needed
const initialState = { activeUser: {id:1}, modals };
// here it is possible to pass in any middleware if needed into //configureStore
const middlewares = [promise]
const mockStore = configureStore(middlewares);
const mockedCallback = () => Promise.resolve();
test('valid path should not redirect to 404', () => {
let store = mockStore(initialState)
const wrapper = shallow(mount(
<MemoryRouter initialEntries={[ '/' ]}>
<App store={store} modals = {modals} />
</MemoryRouter>
) );
expect(wrapper.find(HomeContent)).toHaveLength(1);
});
It is now throwing an error which i cannot seem to solve. TypeError: ShallowWrapper can only wrap valid elements
UPDATE
if i remove shallow i get
(node:45153) UnhandledPromiseRejectionWarning: SyntaxError: The string did not match the expected pattern.
at XMLHttpRequest.open (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:482:15)
at dispatchXhrRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:45:13)
at new Promise (<anonymous>)
at xhrAdapter (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/adapters/xhr.js:12:10)
at dispatchRequest (/var/SP/httpd/ccp-test-alpha/ccp-test-alpha.com/node_modules/axios/lib/core/dispatchRequest.js:59:10)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
(node:45153) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:45153) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
if i remove mount i get
Expected value to have length:
1
Received:
{Symbol(enzyme.__root__): {Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/"]}><withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): {"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}, Symbol(enzyme.__nodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}}, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): , Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}}, Symbol(enzyme.__rootNodes__): [{"instance": null, "key": undefined, "nodeType": "class", "props": {"children": <withRouter(Connect(App)) modals={{"confirmTitle": ""}} store={{"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}} />, "history": {"action": "POP", "block": [Function block], "canGo": [Function canGo], "createHref": [Function createPath], "entries": [{"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}], "go": [Function go], "goBack": [Function goBack], "goForward": [Function goForward], "index": 0, "length": 1, "listen": [Function listen], "location": {"hash": "", "key": "xxk9vz", "pathname": "/", "search": "", "state": undefined}, "push": [Function push], "replace": [Function replace]}}, "ref": null, "rendered": {"instance": null, "key": undefined, "nodeType": "function", "props": {"modals": {"confirmTitle": ""}, "store": {"clearActions": [Function clearActions], "dispatch": [Function anonymous], "getActions": [Function getActions], "getState": [Function getState], "replaceReducer": [Function replaceReducer], "subscribe": [Function subscribe]}}, "ref": null, "rendered": null, "type": [Function C]}, "type": [Function Router]}]}
received.length:
0
70 | </MemoryRouter>
71 | ) ;
> 72 | expect(wrapper.find(HomeContent)).toHaveLength(1);
73 | });
74 |
content of home
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchContents } from '../actions';
import { Link } from 'react-router-dom';
import { fetchActiveUser } from '../actions/index';
import { bindActionCreators } from 'redux';
export class HomeContent extends Component {
constructor(props){
super(props);
this.state = {
message: '',
data:
}
this.meta = { title: 'Home', description: '' };
this.runOnce = false;
this.passMetaBack = this.passMetaBack.bind(this);
}
passMetaBack = () => {
this.props.passMetaBack(this.meta);
}
componentDidMount() {
document.title = "Home | Connectivity Compliance Portal (CCP)";
this.passMetaBack();
}
htmlDecode(input){
let e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
initData(){
if(this.props.isReady && this.props.priv != undefined){
let self = this;
this.props.fetchContents()
.then(response => {
let data = response.payload.data;
if (data.header.error) {
self.handleShowError({
show: true,
errorMsg: data.header.message
});
} else {
self.setState({
data: _.mapKeys(data.body.recordset.record, 'target')
});
}
})
}
}
renderContent(classname) {
if(Object.keys(this.state.data).length>0 ){
let content = this.props.content[classname].content;
return (
<div dangerouslySetInnerHTML={{ __html: content}} />
);
}
}
render() {
if(!this.runOnce && this.props.isReady){
this.runOnce = true;
this.initData();
}
return (
<div className="container-fluid">
<div className="row-fluid" >
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">INTRODUCTION</h3>
</div>
<div className="panel-body panel_introduction ql-editor">
{this.renderContent('panel_introduction')}
</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">Whats New!</h3>
</div>
<div className="panel-body panel_whats_new ql-editor">{this.renderContent('panel_whats_new')}</div>
</div>
</div>
<div className="row-fluid top-buffer">
<div className="panel panel-default disclaimer">
<div className="panel-heading">
<h3 className="panel-title">DISCLAIMER</h3>
</div>
<div className="panel-body panel_disclaimer ql-editor">{this.renderContent('panel_disclaimer')}</div>
</div>
</div>
<div className="modal fade bs-example-modal-lg" id="modalIntro" tabIndex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title" id="myModalLabel">Welcome to the Connectivity Compliance Portal (CCP)</h4>
</div>
<div className="modal-body">
You are receiving this message as you are a guest and require elevated privileges to make best use of the service. In order to do this you'll need to:
<ol start="1">
<li>Go to <a target="_blank" href="https://iam.com/identity" target="_blank" >WIAM (https://iam.com/identity)</a></li>
<li>Click on <i>"Request Access"</i> at the top</li>
<li>Search for <i>"CCP"</i></li>
<li>Select the relevant group and add it to the cart</li>
<li>Check Out!</li>
</ol>
<p>You can confirm if you have been added to the group by going to <Link to={`/ldapuser`}>https://ccp.com/ldapuser</Link>. Once you see you have been added to the group log out of CCP and log back in and you should have the correct permissions. The process can take a few hours to a couple of days depending on how long the approvers take.</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return { content: state.content }
}
//Anything returned from this function will end up as props
//on this container
function mapDispatchToProps(dispatch){
// Whenever getUser is called, the result should be passed
// to all our reducers
return bindActionCreators({ fetchContents, fetchActiveUser }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(HomeContent);
I have crated a sandbox as best i can. is this correct? https://codesandbox.io/s/9yyvnrkrrp
reactjs jestjs enzyme
reactjs jestjs enzyme
edited Nov 26 '18 at 17:25
shorif2000
asked Nov 22 '18 at 13:41


shorif2000shorif2000
80863581
80863581
shallow(mount(
- it should be eithershallow()
ormount()
but not both
– skyboyer
Nov 22 '18 at 19:41
I added UPDATE for shallow and mount
– shorif2000
Nov 23 '18 at 10:41
add a comment |
shallow(mount(
- it should be eithershallow()
ormount()
but not both
– skyboyer
Nov 22 '18 at 19:41
I added UPDATE for shallow and mount
– shorif2000
Nov 23 '18 at 10:41
shallow(mount(
- it should be either shallow()
or mount()
but not both– skyboyer
Nov 22 '18 at 19:41
shallow(mount(
- it should be either shallow()
or mount()
but not both– skyboyer
Nov 22 '18 at 19:41
I added UPDATE for shallow and mount
– shorif2000
Nov 23 '18 at 10:41
I added UPDATE for shallow and mount
– shorif2000
Nov 23 '18 at 10:41
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432299%2fhow-to-test-react-routes-with-connected-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53432299%2fhow-to-test-react-routes-with-connected-components%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
shallow(mount(
- it should be eithershallow()
ormount()
but not both– skyboyer
Nov 22 '18 at 19:41
I added UPDATE for shallow and mount
– shorif2000
Nov 23 '18 at 10:41