Skip to content
This repository was archived by the owner on Nov 16, 2018. It is now read-only.

Jest #20

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open

Jest #20

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
29228b7
add jest testing
Aug 16, 2017
52aa013
start
Aug 16, 2017
c7879c6
Add test for Home
codeBelt Aug 17, 2017
882037b
add tests
codeBelt Aug 17, 2017
a4d08f8
update test stuff
codeBelt Aug 17, 2017
6339e05
add and update tests
codeBelt Aug 18, 2017
d26560a
Merge branch 'master' into jest
Aug 18, 2017
02118b7
update lock file
Aug 18, 2017
a71f16f
Update README.md
codeBelt Aug 18, 2017
35fb1b4
add action test
Aug 18, 2017
4db3715
Merge remote-tracking branch 'origin/jest' into jest
Aug 18, 2017
b345ec7
Merge branch 'master' into jest
codeBelt Aug 20, 2017
0a7fae1
Merge branch 'master' into jest
codeBelt Aug 20, 2017
359d730
Merge branch 'master' into jest
codeBelt Aug 24, 2017
6121b8a
fix test paths
codeBelt Aug 24, 2017
3623749
Merge branch 'master' into jest
codeBelt Aug 25, 2017
14b433a
update package
codeBelt Aug 25, 2017
5187e9f
fix test
codeBelt Aug 25, 2017
27d4f7e
Add MetaReducer test
codeBelt Aug 25, 2017
44553a3
update tests
Aug 25, 2017
593ead3
add nock
Aug 25, 2017
f07d709
add link
Aug 25, 2017
a953d6d
update tests
codeBelt Aug 26, 2017
60971dd
Add broken tests
codeBelt Aug 26, 2017
a302a64
Merge branch 'master' into jest
codeBelt Aug 27, 2017
2d83f5f
rename store to stores
codeBelt Aug 27, 2017
d3699a7
Merge branch 'master' into jest
codeBelt Aug 27, 2017
af118c2
remove default action
Aug 28, 2017
df8d057
Merge branch 'master' into jest
Aug 28, 2017
9dbe95a
Merge branch 'master' into jest
Sep 7, 2017
114abcb
update
Sep 7, 2017
23a6cae
Merge branch 'master' into jest
codeBelt Sep 23, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,18 @@
"---------- TESTING -----------------------------------------------------------------------------": "",
"test": "npm run lint && npm run unit",
"lint": "eslint src --ext .js,.jsx",
"unit": "jest",
"unit": "cross-env BABEL_ENV=server NODE_ENV=production jest",
"unit:watch": "cross-env BABEL_ENV=server NODE_ENV=production jest --watch",
"unit:coverage": "cross-env BABEL_ENV=server NODE_ENV=production jest --coverage",
"------------------------------------------------------------------------------------------------": ""
},
"jest": {
"setupFiles": [],
"roots": [
"<rootDir>/src/",
"<rootDir>/test/"
]
},
"repository": {
"type": "git",
"url": "https://github.com/codeBelt/hapi-react-hot-loader-example"
Expand All @@ -50,6 +59,7 @@
"babel-cli": "6.26.0",
"babel-core": "6.26.0",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"babel-plugin-system-import-transformer": "3.1.0",
"babel-plugin-transform-class-properties": "6.24.1",
Expand All @@ -59,11 +69,14 @@
"babel-preset-react": "6.24.1",
"babel-preset-stage-2": "6.24.1",
"babel-watch": "2.0.7",
"chance": "1.0.10",
"concurrently": "3.5.0",
"copy-webpack-plugin": "4.0.1",
"cross-env": "5.0.5",
"css-hot-loader": "1.3.0",
"css-loader": "0.28.7",
"enzyme": "2.9.1",
"enzyme-to-json": "1.5.1",
"eslint": "4.5.0",
"eslint-config-airbnb": "15.1.0",
"eslint-config-airbnb-base": "11.3.2",
Expand All @@ -74,11 +87,17 @@
"extract-text-webpack-plugin": "3.0.0",
"html-webpack-harddisk-plugin": "0.1.0",
"html-webpack-plugin": "2.30.1",
"jest": "20.0.4",
"jsdom": "11.2.0",
"nock": "9.0.14",
"nodemon": "1.11.0",
"postcss-apply": "0.8.0",
"postcss-cssnext": "3.0.2",
"postcss-import": "10.0.0",
"postcss-loader": "2.0.6",
"react-test-renderer": "15.6.1",
"redux-mock-store": "1.2.3",
"regenerator-runtime": "0.11.0",
"rimraf": "2.6.1",
"robotstxt-webpack-plugin": "2.0.0",
"style-loader": "0.18.2",
Expand Down
21 changes: 21 additions & 0 deletions test/_setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// https://github.com/airbnb/enzyme/blob/master/docs/guides/jsdom.md

const {JSDOM} = require('jsdom');

const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
const {window} = jsdom;

function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));

Object.defineProperties(target, props);
}

global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
copyProps(window, global);
17 changes: 17 additions & 0 deletions test/stores/loading/LoadingAction.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Chance from 'chance';
import LoadingAction from '../../../src/stores/loading/LoadingAction';

describe('LoadingAction', () => {
const chance = new Chance();
const expectedData = chance.bool();

test('should create an action', () => {
const actual = LoadingAction.showLoader(expectedData);
const expected = {
type: LoadingAction.SET_LOADING,
payload: expectedData,
};

expect(actual).toEqual(expected);
});
});
28 changes: 28 additions & 0 deletions test/stores/loading/LoadingReducer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Chance from 'chance';
import LoadingReducer from '../../../src/stores/loading/LoadingReducer';
import LoadingAction from '../../../src/stores/loading/LoadingAction';

describe('LoadingAction', () => {
const chance = new Chance();

test('should return the initial state', () => {
const actual = LoadingReducer.reduce(undefined, {});
const expected = LoadingReducer._initialState;

expect(actual).toEqual(expected);
});

test('should set loading', () => {
const action = {
type: LoadingAction.SET_LOADING,
payload: chance.bool(),
};
const actual = LoadingReducer.reduce(undefined, action);
const expected = {
isLoading: action.payload,
};

expect(actual).toEqual(expected);
});

});
20 changes: 20 additions & 0 deletions test/stores/meta/MetaAction.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Chance from 'chance';
import MetaAction from '../../../src/stores/meta/MetaAction';

describe('MetaAction', () => {
const chance = new Chance();
const expectedData = {
title: chance.string(),
description: chance.string(),
};

test('should create an action', () => {
const actual = MetaAction.setMeta(expectedData);
const expected = {
type: MetaAction.SET_META,
payload: expectedData,
};

expect(actual).toEqual(expected);
});
});
29 changes: 29 additions & 0 deletions test/stores/meta/MetaReducer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Chance from 'chance';
import MetaReducer from '../../../src/stores/meta/MetaReducer';
import MetaAction from '../../../src/stores/meta/MetaAction';

describe('MetaReducer', () => {
const chance = new Chance();

test('should return the initial state', () => {
const actual = MetaReducer.reduce(undefined, {});
const expected = MetaReducer._initialState;

expect(actual).toEqual(expected);
});

test('should set title and description', () => {
const action = {
type: MetaAction.SET_META,
payload: {
title: chance.string(),
description: chance.string(),
},
};
const actual = MetaReducer.reduce(undefined, action);
const expected = action.payload;

expect(actual).toEqual(expected);
});

});
24 changes: 24 additions & 0 deletions test/stores/render/RenderReducer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Chance from 'chance';
import RenderReducer from '../../../src/stores/render/RenderReducer';

describe('RenderReducer', () => {
const chance = new Chance();

test('should return the initial state', () => {
const actual = RenderReducer.reduce(undefined, {});
const expected = RenderReducer._initialState;

expect(actual).toEqual(expected);
});

test('should set isServerSide state', () => {
const state = {
isServerSide: chance.bool(),
};
const actual = RenderReducer.reduce(state, {});
const expected = state;

expect(actual).toEqual(expected);
});

});
29 changes: 29 additions & 0 deletions test/stores/rootSaga.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'fetch-everywhere';
import jest from 'jest';
import {fork, takeLatest} from 'redux-saga/effects';
import rootSaga from '../../src/stores/rootSaga';
import UserAction from '../../src/stores/user/UserAction';
import UserSaga from '../../src/stores/user/UserSaga';

describe('rootSaga', () => {
const expectStoreData = {
renderReducer: {
isServerSide: true,
},
};

// TODO: mock 'const stores = yield select();` to return expectStoreData.
// const select = jest.fn();

test('should start root saga', async () => {
const generator = rootSaga();

expect(generator.next().value).toEqual(expectStoreData);

expect(generator.next().value).toEqual([
fork(UserSaga.loadUser),
takeLatest(UserAction.LOAD_USER, UserSaga.loadUser),
]);
});

});
15 changes: 15 additions & 0 deletions test/stores/user/UserAction.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Chance from 'chance';
import UserAction from '../../../src/stores/user/UserAction';

describe('UserAction', () => {
const chance = new Chance();

test('should create an action', () => {
const actual = UserAction.loadUser();
const expected = {
type: UserAction.LOAD_USER,
};

expect(actual).toEqual(expected);
});
});
24 changes: 24 additions & 0 deletions test/stores/user/UserReducer.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import UserReducer from '../../../src/stores/user/UserReducer';
import UserAction from '../../../src/stores/user/UserAction';

describe('UserReducer', () => {

test('should return the initial state', () => {
const actual = UserReducer.reduce(undefined, {});
const expected = UserReducer._initialState;

expect(actual).toEqual(expected);
});

test('should set user data', () => {
const action = {
type: UserAction.LOAD_USER,
payload: UserReducer._initialState,
};
const actual = UserReducer.reduce(undefined, action);
const expected = action.payload;

expect(actual).toEqual(expected);
});

});
66 changes: 66 additions & 0 deletions test/stores/user/UserSaga.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'fetch-everywhere';
import jest from 'jest';
import nock from 'nock';
import UserSaga from '../../../src/stores/user/UserSaga';
import {put} from 'redux-saga/effects';
import LoadingAction from '../../../src/stores/loading/LoadingAction';
import UserAction from '../../../src/stores/user/UserAction';

describe('UserSaga', () => {

// https://codereviewvideos.com/course/react-redux-and-redux-saga-with-symfony-3/video/testing-javascript-s-fetch-with-jest-happy-path

beforeEach(() => {
// global.fetch = jest.fn().mockImplementation(() => {
// return new Promise((resolve, reject) => {
// resolve({
// ok: true,
// json: () => {
// return {Id: '123'};
// },
// });
// });
// });
});

afterEach(() => {
nock.cleanAll();
});

test('should loadUser', async () => {
const expectedBody = {
status: 200,
results: [{}],
};

nock('https://randomuser.me')
.get('/api/?inc=picture,name,email,phone,id,dob')
.reply(200, expectedBody);

const generator = UserSaga.loadUser();

expect(generator.next().value).toEqual(put({
type: LoadingAction.SET_LOADING,
payload: true,
}));

// TODO: Do I use await here or should I use generator.next().value ?
const response = await generator.next().value;
const json = await response.json();

expect(json).toEqual(expectedBody);

expect(generator.next().value).toEqual(put({
type: UserAction.LOAD_USER_SUCCESS,
payload: {},
meta: null,
error: {},
}));

expect(generator.next().value).toEqual(put({
type: LoadingAction.SET_LOADING,
payload: false,
}));
});

});
51 changes: 51 additions & 0 deletions test/views/about/About.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import {Provider} from 'react-redux';
import {shallow, mount, render} from 'enzyme';
import configureStore from 'redux-mock-store';
import MetaAction from '../../../src/stores/meta/MetaAction';
import About from '../../../src/views/about/About';

describe('About', () => {
const initialState = {};
const mockStore = configureStore();
let store;
let wrapper;
let component;

beforeEach(() => {
store = mockStore(initialState);
wrapper = mount(
<Provider store={store}>
<About />
</Provider>
);

component = wrapper.find(About).first();
});

test('should match mapStateToProps', () => {
// TODO: how to test mapStateToProps
});

test('should call setMeta action', () => {
const actions = store.getActions();
const actual = actions[0];
const expected = {
type: MetaAction.SET_META,
payload: {
title: 'About Page',
},
};

expect(actual).toEqual(expected);
});

test('should call X number of actions', () => {
const actions = store.getActions();
const actual = actions.length;
const expected = 1;

expect(actual).toBe(expected);
});

});
Loading