Skip to content

Instantly share code, notes, and snippets.

View carlosble's full-sized avatar

Carlos Ble carlosble

View GitHub Profile
@carlosble
carlosble / index.jsx
Created April 2, 2017 21:41
typical index of a react-redux app
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {Router, browserHistory} from 'react-router';
import routes from './routes';
import configureStore from './store/configureStore';
import {syncHistoryWithStore} from 'react-router-redux';
const store = configureStore();
@carlosble
carlosble / factory.js
Last active January 12, 2018 20:05
Factory in a Redux App
import {connect} from 'react-redux';
import {ProfilePage as OriginalProfilePage} from './containers/ProfilePage';
import createServerApi from './utils/serverApi';
import * as profileActions from './actions/profileActions';
import notifier from './utils/notifications';
export const createProfilePage = (serverApi, notifier) => {
return connect(
(state) => {
return {
@carlosble
carlosble / ProfilePage.js
Created April 2, 2017 22:15
Invoking action from component
onSubmit(event) {
event.preventDefault();
let notifier = this.props.notifier;
this.props.actions.saveProfile(this.props.profile).then((success)=>{
notifier.showSuccess(success);
}, (error) => {
notifier.showError(error);
})
}
@carlosble
carlosble / profileActions.js
Created April 3, 2017 06:09
Different kind of actions
import * as types from '../constants/actionTypes';
export function loadProfile(serverApi) {
return function (dispatch) {
return serverApi.getProfile().then((json) => {
return dispatch({
type: types.GET_PROFILE,
profile: json
});
});
@carlosble
carlosble / profile.spec.js
Last active April 3, 2017 06:50
Coarse-grained tests
import {mount} from "enzyme";
import ProfileForm from "../components/ProfileForm";
import React from "react";
import {Provider} from "react-redux";
import configureStore from "../store/configureStore";
import {mockServerApi} from "../store/serverApi";
import {createProfilePage} from "../factory";
import * as models from "../models";
import {inputById, simulateChangeInField} from "../utils/testHelper";
import notifier from "../utils/notifications";
@carlosble
carlosble / ProfilePage.js
Created April 3, 2017 07:06
Make the test pass
componentDidMount() {
let notifier = this.props.notifier;
notifier.startLoad();
this.props.actions.loadProfile().then(() => {
notifier.stopLoad();
});
}
@carlosble
carlosble / profileActions.js
Created April 3, 2017 21:23
Action creator that combines async request to the server
import * as types from '../constants/actionTypes';
export function loadProfile(serverApi) {
return function (dispatch) {
return serverApi.getProfile().then((json) => {
return dispatch({
type: types.GET_PROFILE,
profile: json
});
});
import * as actionTypes from '../constants/actionTypes';
import initialState from './initialState';
export default function profileReducer(profile = initialState.profile, action) {
if (action.type == actionTypes.GET_PROFILE) {
return Object.assign({}, profile, action.profile);
}
return profile;
}
@carlosble
carlosble / profile.spec.js
Last active April 5, 2017 17:40
Testing the component interaction with the backend
it("saves the profile in the backend", (done) => {
simulateChangeInPhone(change);
let actualProfile;
spyNotifier.slowOperationFinished = () => {
expect(actualProfile.phone).toEqual(change);
done();
};
stubApi.saveProfile = (profile) => {
actualProfile = profile;
return Promise.resolve({message: 'Success'});
@carlosble
carlosble / profile.spec.js
Created April 5, 2017 18:10
Refactoring the test
it("saves the profile in the backend", (done) => {
simulateChangeInPhone(change);
let savedProfile = spyOnSaveProfile();
eventually(() => {
expect(savedProfile.phone).toEqual(change);
}, done);
saveProfileButton().simulate("click");
});