Skip to content

Commit

Permalink
clean up remaining tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jakemmarsh committed May 12, 2016
1 parent 9976b6e commit ae47b41
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 122 deletions.
6 changes: 3 additions & 3 deletions app/js/stores/CurrentUserStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const CurrentUserStore = Reflux.createStore({
if ( this.user ) {
this.setUser(this.user);
} else {
AuthAPI.checkLoginStatus().then(user => {
AuthAPI.checkLoginStatus().then((user) => {
this.hasBeenChecked = true;
this.setUser(user);
}).catch(err => {
Expand All @@ -40,7 +40,7 @@ const CurrentUserStore = Reflux.createStore({
},

loginUser(user) {
AuthAPI.login(user).then(user => {
AuthAPI.login(user).then((user) => {
this.setUser(user);
}).catch(err => {
this.throwError(err);
Expand All @@ -55,4 +55,4 @@ const CurrentUserStore = Reflux.createStore({

});

export default CurrentUserStore;
export default CurrentUserStore;
9 changes: 5 additions & 4 deletions app/js/utils/APIUtils.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
'use strict';

import {camelizeKeys} from 'humps';
import request from 'superagent';
import request from 'superagent';
import {camel} from 'change-case';
import helpers from './Helpers';

const APIUtils = {

root: '//localhost:3000/api/',

normalizeResponse(response) {
return camelizeKeys(response.body);
return helpers.processObjectKeys(response, key => { return camel(key); });
},

get(path) {
Expand Down Expand Up @@ -84,4 +85,4 @@ const APIUtils = {

};

export default APIUtils;
export default APIUtils;
28 changes: 28 additions & 0 deletions app/js/utils/Helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

import _ from 'lodash';

const Helpers = {

processObjectKeys(obj, convert) {
let output;

if ( _.isDate(obj) || _.isRegExp(obj) || !_.isObject(obj) ) {
return obj;
} else if ( _.isArray(obj) ) {
output = _.map(obj, item => {
return this.processObjectKeys(item, convert);
});
} else {
output = {};
_.forOwn(obj, (value, key) => {
output[convert(key)] = this.processObjectKeys(obj[key], convert);
});
}

return output;
}

};

export default Helpers;
13 changes: 7 additions & 6 deletions gulp/tasks/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@ gulp.task('test', () => {

// Ensure that all window/DOM related properties
// are available to all tests
global.document = jsdom('<!DOCTYPE html><html><body></body></html>');
global.window = document.parentWindow;
global.location = { href: '' };
global.navigator = {};
global.navigator.userAgent = 'jsdom';
global.navigator.appVersion = '';
global.document = jsdom('<!DOCTYPE html><html><body></body></html>', {
url: 'http://localhost'
});
global.window = document.defaultView;
global.navigator = window.navigator;
global.KeyboardEvent = window.KeyboardEvent;

// Ensure that 'sinon' and 'chai' library methods will be
// available to all tests
global.sinon = require('sinon');
global.assert = require('chai').assert;
require('sinon-as-promised');

return (gjc.createTask({
src: files,
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"browser-sync": "^2.7.13",
"browserify": "^12.0.1",
"chai": "^3.5.0",
"change-case": "^2.3.1",
"debowerify": "^1.3.1",
"del": "^2.2.0",
"eslint-plugin-react": "^3.6.3",
Expand All @@ -47,7 +48,6 @@
"gulp-uglify": "^1.2.0",
"gulp-util": "^3.0.6",
"history": "^1.17.0",
"humps": "^1.0.0",
"istanbul": "^0.4.0",
"jsdom": "3.1.2",
"lodash": "^3.10.0",
Expand All @@ -60,6 +60,7 @@
"reflux": "^0.3.0",
"run-sequence": "^1.1.1",
"sinon": "^1.17.1",
"sinon-as-promised": "^4.0.0",
"superagent": "^1.2.0",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.2.x",
Expand Down
69 changes: 37 additions & 32 deletions tests/App.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,62 @@
import React from 'react';
import TestUtils from 'react-addons-test-utils';

import fixtures from '../utils/fixtures';
import copyObject from '../utils/copyObject';
import App from '../app/js/App';
import CurrentUserStore from '../app/js/stores/CurrentUserStore';
import CurrentUserActions from '../app/js/actions/CurrentUserActions';
import {ListenerMixin} from 'reflux';
import TestHelpers from '../utils/testHelpers';

describe('App', function() {

it('#componentDidMount should listen to the user store and check login status', function() {
sandbox.mock(ListenerMixin).expects('listenTo').withArgs(CurrentUserStore, App._onUserChange).once();
sandbox.mock(CurrentUserActions).expects('checkLoginStatus').once();
const USER = copyObject(fixtures.user);
let rendered;
let props;

TestUtils.renderIntoDocument(
<App params={{}} query={{}}>
<div />
function renderComponent() {
rendered = TestUtils.renderIntoDocument(
<App {...props}>
<div className="test-child" />
</App>
);
}

beforeEach(function() {
props = {
params: {},
query: {}
};

renderComponent();
});

it('#componentDidMount should listen to the user store and check login status', function() {
sandbox.stub(CurrentUserStore, 'listen');
sandbox.stub(CurrentUserActions, 'checkLoginStatus');

rendered.componentDidMount();

sinon.assert.calledOnce(CurrentUserStore.listen);
sinon.assert.calledWith(CurrentUserStore.listen, rendered.onUserChange);
sinon.assert.calledOnce(CurrentUserActions.checkLoginStatus);
});

it('#onUserChange should set the error state if an error is received', function() {
const err = { message: 'Test error message.' };
const app = TestUtils.renderIntoDocument(
<App params={{}} query={{}}>
<div />
</App>
);

app.onUserChange(err, null);
app.state.error.should.eql(err);
rendered.onUserChange(err, null);

assert.deepEqual(rendered.state.error, err);
});

it('#onUserChange should set the user state and clear error if a new user is received', function() {
const user = TestHelpers.fixtures.user;
const app = TestUtils.renderIntoDocument(
<App params={{}} query={{}}>
<div />
</App>
);
rendered.onUserChange(null, USER);

app.onUserChange(null, user);
app.state.currentUser.should.eql(user);
Should(app.state.error).be.null();
assert.strictEqual(rendered.state.currentUser, USER);
assert.isNull(rendered.state.error);
});

it('#renderChildren should return all the cloned children', function() {
const app = TestUtils.renderIntoDocument(
<App params={{}} query={{}}>
<div className="test-child" />
</App>
);

TestUtils.findRenderedDOMComponentWithClass(app, 'test-child').should.not.throw();
assert.doesNotThrow(TestUtils.findRenderedDOMComponentWithClass.bind(null, rendered, 'test-child'));
});
});
});
2 changes: 1 addition & 1 deletion tests/components/Header.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('Component: Header', function() {
});

it('should render properly', function() {
assert.DoesNotThrow(TestUtils.findRenderedDOMComponentWithTag.bind(null, rendered, 'header'));
assert.doesNotThrow(TestUtils.findRenderedDOMComponentWithTag.bind(null, rendered, 'header'));
});

});
1 change: 1 addition & 0 deletions tests/pages/HomePage.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

import React from 'react';
import TestUtils from 'react-addons-test-utils';

import HomePage from '../../app/js/pages/HomePage';
Expand Down
1 change: 1 addition & 0 deletions tests/pages/NotFoundPage.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

import React from 'react';
import TestUtils from 'react-addons-test-utils';

import NotFoundPage from '../../app/js/pages/NotFoundPage';
Expand Down
5 changes: 3 additions & 2 deletions tests/pages/SearchPage.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

import React from 'react';
import TestUtils from 'react-addons-test-utils';

import SearchPage from '../../app/js/pages/SearchPage';
Expand All @@ -21,7 +22,7 @@ describe('Page: Search', function() {
});

it('should render properly', function() {
TestUtils.findRenderedDOMComponentWithClass.bind(null, rendered, 'search-page').should.not.throw();
assert.doesNotThrow(TestUtils.findRenderedDOMComponentWithClass.bind(null, rendered, 'search-page'));
});

it('should update state on input box change', function() {
Expand All @@ -31,7 +32,7 @@ describe('Page: Search', function() {
input.value = newValue;
TestUtils.Simulate.change(input);

rendered.state.query.should.eql(newValue);
assert.strictEqual(rendered.state.query, newValue);
});

it('should render the updated state in the related span', function() {
Expand Down
65 changes: 41 additions & 24 deletions tests/stores/CurrentUserStore.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
'use strict';

import TestHelpers from '../../utils/testHelpers';
import fixtures from '../../utils/fixtures';
import copyObject from '../../utils/copyObject';
import CurrentUserStore from '../../app/js/stores/CurrentUserStore';
import CurrentUserActions from '../../app/js/actions/CurrentUserActions';
import AuthAPI from '../../app/js/utils/AuthAPI';

describe('Store: CurrentUser', function() {

const USER = TestHelpers.fixtures.user;
const USER = copyObject(fixtures.user);

beforeEach(function() {
CurrentUserStore.user = null;
});

it('#setUser should set this.user and trigger the store', function() {
sandbox.stub(CurrentUserStore, 'trigger');
Expand All @@ -29,38 +34,50 @@ describe('Store: CurrentUser', function() {
sinon.assert.calledWith(CurrentUserStore.trigger, err);
});

it('#checkLoginStatus should check user\'s login status on action', function() {
sandbox.stub(AuthAPI, 'checkLoginStatus').returns(Promise.resolve(USER));
sandbox.stub(CurrentUserStore, 'setUser');
it('#checkLoginStatus should check user\'s login status on action', function(done) {
sandbox.stub(AuthAPI, 'checkLoginStatus').resolves(USER);
sandbox.spy(CurrentUserStore, 'setUser');

CurrentUserActions.checkLoginStatus();
sandbox.stub(CurrentUserStore, 'trigger', () => {
sinon.assert.calledOnce(AuthAPI.checkLoginStatus);
sinon.assert.calledOnce(CurrentUserStore.setUser);
sinon.assert.calledWith(CurrentUserStore.setUser, USER);

sinon.assert.calledOnce(AuthAPI.checkLoginStatus);
sinon.assert.calledOnce(CurrentUserStore.setUser);
sinon.assert.calledWith(CurrentUserStore.setUser, USER);
done();
});

CurrentUserActions.checkLoginStatus();
});

it('#loginUser should log user in on action if API response is successful', function() {
sandbox.stub(AuthAPI, 'login').returns(Promise.resolve(USER));
sandbox.stub(CurrentUserStore, 'setUser');
it('#loginUser should log user in on action if API response is successful', function(done) {
sandbox.stub(AuthAPI, 'login').resolves(USER);
sandbox.spy(CurrentUserStore, 'setUser');

CurrentUserActions.login(USER);
sandbox.stub(CurrentUserStore, 'trigger', () => {
sinon.assert.calledOnce(AuthAPI.login);
sinon.assert.calledWith(AuthAPI.login, USER);
sinon.assert.calledOnce(CurrentUserStore.setUser);
sinon.assert.calledWith(CurrentUserStore.setUser, USER);

sinon.assert.calledOnce(AuthAPI.login);
sinon.assert.calledWith(AuthAPI.login, USER);
sinon.assert.calledOnce(CurrentUserStore.setUser);
sinon.assert.calledWith(CurrentUserStore.setUser, USER);
done();
});

CurrentUserActions.login(USER);
});

it('#logoutUser should log user out on action', function() {
sandbox.stub(AuthAPI, 'logout').returns(Promise.resolve());
sandbox.stub(CurrentUserStore, 'setUser');
it('#logoutUser should log user out on action', function(done) {
sandbox.stub(AuthAPI, 'logout').resolves();
sandbox.spy(CurrentUserStore, 'setUser');

CurrentUserActions.logout();
sandbox.stub(CurrentUserStore, 'trigger', () => {
sinon.assert.calledOnce(AuthAPI.logout);
sinon.assert.calledOnce(CurrentUserStore.setUser);
sinon.assert.calledWith(CurrentUserStore.setUser, null);

sinon.assert.calledOnce(AuthAPI.logout);
sinon.assert.calledOnce(CurrentUserStore.setUser);
sinon.assert.calledWith(CurrentUserStore.setUser, null);
done();
});

CurrentUserActions.logout();
});

});
Loading

0 comments on commit ae47b41

Please sign in to comment.