The Speaker Detail component

We are now ready to create our SpeakerDetailPage. There isn't much to this component. It will need to be another container component so that it can use the get speaker action. Because it is a container component, we will not be placing any markup directly into this component. The good news for us is that it means our tests will be short and simple.

To get the tests started, create an existence test.

describe('Speaker Detail Page', () => {
it('exists', () => {
expect(SpeakerDetailPage).to.exist;
});
});

Create a SpeakerDetailPage file and add a component to it.

export class SpeakerDetailPage extends Component {
render() {
return (<div></div>);
}
}

The next thing we want to test, the only other thing we can test without directly specifying the design, is that the model is received and somehow makes it to the screen. We only need to test one property of the model for now. We will write a test that shows that the first name of the speaker is displayed.

describe('Render', () => {
it('renders', () => {
// arrange
const props = {
match: { params: { id: 'test-speaker' } },
actions: { getSpeaker: (id) => { return Promise.resolve(); } },
speaker: { firstName: 'Test' }
};

// act
const component = mount(<SpeakerDetailPage { ...props } />);

// assert
expect(component.find('first-name').text()).to.contain('Test');
});
});

If you are paying attention, you might have wondered why the get speaker action is just returning an empty resolved promise. We are not attached to Redux, so kicking off the action doesn't trigger a reducer, which doesn't update the store and doesn't trigger a refresh of the component state. We still want to complete the contract of the component in the test setup though and this component will call that function. We could leave this line out, but we will be adding it back as soon as we wire up Redux.

To make the test pass, we will need to make a couple of simple changes in the SpeakerDetailPage component, and create a whole new component. Following are the changes to this component, but it will be an exercise for you to create the next component. It is only for display and we are testing that it gets populated here so all you have to do is write the presentational component.

export class SpeakerDetailPage extends Component {
constructor(state, context) {
super(state, context);

this.state = {
speaker: Object.assign({}, this.props.speaker)
};
}

render() {
return (
<SpeakerDetail speaker={this.state.speaker} />
);
}
}

The previous code will make the test pass, but now we have to connect the component to Redux. We will be adding a call to the getSpeaker action, binding to the componentWillReceiveProps life cycle event, and mapping props and dispatch using the connect function. Here is the final SpeakerDetailPage component.

export class SpeakerDetailPage extends Component {
constructor(state, context) {
super(state, context);

this.state = {
speaker: Object.assign({}, this.props.speaker)
};

this.props.actions.getSpeaker(this.props.match.params.id)
}

componentWillReceiveProps(nextProps) {
if(this.props.speaker.id !== nextProps.speaker.id) {
this.setState({ speaker: Object.assign({}, nextProps.speaker) });
}
}

render() {
return (
<SpeakerDetail speaker={this.state.speaker} />
);
}
}

function mapStateToProps(state, ownProps) {
let speaker = { id: '', firstName: '', lastName: '' }

return {
speaker: state.speaker || speaker
};
}

function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(speakerActions, dispatch)
}
}

export default connect(
mapStateToProps,
mapDispatchToProps
)(SpeakerDetailPage);

Now that everything passes the tests, we have one last thing we need to do before we can properly develop further. Earlier we replaced the mock API with a call to a factory. We did this so that the tests could affect the state of the mock API in the actions. That same modification has made it possible to configure a starting point for our application. In the index.js file, add the following code after the store has been configured; now, when you run the app, you will have speakers available to test the UI with.

const speakers = [{
id: 'clayton-hunt',
firstName: 'Clayton',
lastName: 'Hunt'
}, {
id: 'john-callaway',
firstName: 'John',
lastName: 'Callaway'
}];

let service = factory.createSpeakerService();
speakers.forEach((speaker) => {
service.create(speaker);
});
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.206.43