This commit is contained in:
Kumar McMillan 2015-06-17 16:41:13 -05:00
Родитель 098aa2d742
Коммит 26c7e5d50d
9 изменённых файлов: 64 добавлений и 51 удалений

Просмотреть файл

@ -51,6 +51,7 @@
"no-script-url": 2,
"no-sequences": 2,
"no-undef": 2,
"no-underscore-dangle": 0,
"no-unused-vars": 2,
"no-with": 2,
"quotes": [2, "single"],

Просмотреть файл

@ -1,5 +1,6 @@
'use strict';
var RewirePlugin = require('rewire-webpack');
var webpackConfig = require('./webpack.config.js');
// Remove the bits from the shared config
@ -7,6 +8,11 @@ var webpackConfig = require('./webpack.config.js');
delete webpackConfig.output;
delete webpackConfig.entry;
// Add this just for testing:
webpackConfig.plugins = [
new RewirePlugin(),
];
module.exports = function (config) {
config.set({

Просмотреть файл

@ -53,6 +53,8 @@
"mocha": "^2.2.5",
"node-libs-browser": "0.5.0",
"payment-icons": "git://github.com/muffinresearch/payment-icons.git#0.0.4",
"rewire": "^2.1.3",
"rewire-webpack": "^1.0.0",
"sinon": "1.14.1",
"webpack": "^1.9.5",
"webpack-dev-server": "^1.8.2"

Просмотреть файл

@ -5,26 +5,17 @@ var assign = require('object-assign');
var dispatcher = require('dispatcher');
//
// A helper object to perform user-related actions.
// Each action will dispatch messages so that stores can
// update their state accordingly.
//
function UserActions(localDispatcher) {
//
// A helper object to perform user-related actions.
// Each action will dispatch messages so that stores can
// update their state accordingly.
//
this.dispatcher = localDispatcher;
}
module.exports = assign({}, {
signIn: function(accessToken) {
UserActions.prototype = assign({}, {
signIn: function(accessToken, opt) {
opt = opt || {};
if (!opt.jquery) {
opt.jquery = $;
}
opt.jquery.ajax({
$.ajax({
data: {
access_token: accessToken,
},
@ -41,7 +32,7 @@ UserActions.prototype = assign({}, {
console.log('setting CSRF token for subsequent requests:',
data.csrf_token);
opt.jquery.ajaxSetup({
$.ajaxSetup({
headers: {
'X-CSRFToken': data.csrf_token,
},
@ -59,14 +50,10 @@ UserActions.prototype = assign({}, {
setCurrentUser: function(user) {
console.log('UserActions: setting current user', user);
this.dispatcher.dispatch({
dispatcher.dispatch({
actionType: 'set-user',
user: user,
});
},
});
module.exports = new UserActions(dispatcher);
module.exports.Class = UserActions;

Просмотреть файл

@ -46,4 +46,3 @@ UserStore.prototype = assign({}, EventEmitter.prototype, {
module.exports = new UserStore(dispatcher);
module.exports.Class = UserStore;

Просмотреть файл

@ -14,8 +14,6 @@ module.exports = React.createClass({
displayName: 'LoginView',
mixins: [Navigation],
UserActions: UserActions,
UserStore: UserStore,
contextTypes: {
router: React.PropTypes.func,
@ -23,12 +21,12 @@ module.exports = React.createClass({
componentDidMount: function() {
var { router } = this.context;
this.UserStore.addSetUserListener(this.onSetUser);
this.UserActions.signIn(router.getCurrentQuery().access_token);
UserStore.addSetUserListener(this.onSetUser);
UserActions.signIn(router.getCurrentQuery().access_token);
},
componentWillUnmount: function() {
this.UserStore.removeSetUserListener(this.onSetUser);
UserStore.removeSetUserListener(this.onSetUser);
},
onSetUser: function() {
@ -36,7 +34,7 @@ module.exports = React.createClass({
console.log('ignoring events while unmounted');
return;
}
var user = this.UserStore.getCurrentUser();
var user = UserStore.getCurrentUser();
if (user.is_logged_in) {
console.log('current user is logged in; continuing to card-listing');
this.transitionTo('card-listing');

Просмотреть файл

@ -1,43 +1,47 @@
'use strict';
var Login = require('views/login');
var rewire = require('rewire');
var helpers = require('./helpers');
describe('Login', function() {
beforeEach(function() {
var stubs = helpers.getUserStubs();
this.UserActions = stubs.UserActions;
this.UserStore = stubs.UserStore;
var Login = rewire('views/login');
Login.__set__({
UserActions: this.UserActions,
UserStore: this.UserStore,
});
var routed = helpers.getRoutedComponent(Login);
this.Login = routed.component;
var stubs = helpers.getUserStubs();
this.Login.UserActions = stubs.UserActions;
this.Login.UserStore = stubs.UserStore;
});
it('should sign in on mount', function() {
this.Login.componentDidMount();
assert.ok(this.Login.UserActions.signIn.called);
assert.ok(this.UserActions.signIn.called);
});
it('should listen to user change', function() {
this.Login.componentDidMount();
var store = this.Login.UserStore;
var store = this.UserStore;
assert.equal(store.addSetUserListener.firstCall.args[0],
this.Login.onSetUser);
});
it('should clean up user listeners', function() {
this.Login.componentWillUnmount();
var store = this.Login.UserStore;
assert.equal(store.removeSetUserListener.firstCall.args[0],
assert.equal(this.UserStore.removeSetUserListener.firstCall.args[0],
this.Login.onSetUser);
});
it('should navigate to card-listing when user signs in', function() {
var transition = sinon.spy(this.Login, 'transitionTo');
this.Login.UserStore.getCurrentUser = function() {
this.UserStore.getCurrentUser = function() {
return {
is_logged_in: true,
};

Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
var UserActions = require('user-actions');
var rewire = require('rewire');
var helpers = require('./helpers');
@ -15,7 +15,14 @@ describe('UserActions', function() {
dispatch: function() {},
};
sinon.spy(dispatcher, 'dispatch');
userActions = new UserActions.Class(dispatcher);
userActions = rewire('user-actions');
userActions.__set__({
dispatcher: dispatcher,
// Replace with a non-functioning stub by default until overidden.
'$': {},
});
});
function fakeSignInResult() {
@ -35,11 +42,13 @@ describe('UserActions', function() {
});
it('should set user from sign-in', function() {
var setUser = sinon.spy(userActions, 'setCurrentUser');
var data = fakeSignInResult();
var jquery = helpers.fakeJquery({returnedData: data});
userActions.__set__('$', jquery.stub);
userActions.signIn('access-token', {jquery: jquery.stub});
var setUser = sinon.spy(userActions, 'setCurrentUser');
userActions.signIn('access-token');
assert.deepEqual(setUser.firstCall.args[0],
{email: data.buyer_email, is_logged_in: true});
@ -47,8 +56,9 @@ describe('UserActions', function() {
it('should sign-in with access token', function() {
var jquery = helpers.fakeJquery({returnedData: fakeSignInResult()});
userActions.__set__('$', jquery.stub);
userActions.signIn('access-token', {jquery: jquery.stub});
userActions.signIn('access-token');
assert.equal(jquery.ajaxSpy.firstCall.args[0].data.access_token,
'access-token');
@ -57,18 +67,20 @@ describe('UserActions', function() {
it('should configure CSRF headers on sign-in', function() {
var data = fakeSignInResult();
var jquery = helpers.fakeJquery({returnedData: data});
userActions.__set__('$', jquery.stub);
userActions.signIn('access-token', {jquery: jquery.stub});
userActions.signIn('access-token');
assert.deepEqual(jquery.ajaxSetupSpy.firstCall.args[0].headers,
{'X-CSRFToken': data.csrf_token});
});
it('should set signed out user on failure', function() {
var setUser = sinon.spy(userActions, 'setCurrentUser');
var jquery = helpers.fakeJquery({result: 'fail'});
userActions.__set__('$', jquery.stub);
var setUser = sinon.spy(userActions, 'setCurrentUser');
userActions.signIn('access-token', {jquery: jquery.stub});
userActions.signIn('access-token');
assert.deepEqual(setUser.firstCall.args[0],
{email: null, is_logged_in: false});

Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
var UserStore = require('user-store');
var rewire = require('rewire');
describe('UserStore', function() {
@ -18,13 +18,17 @@ describe('UserStore', function() {
}
beforeEach(function() {
var module = rewire('user-store');
var dispatcher = {
register: function(receiver) {
// Reference the callback so we can dispatch messages directly.
dispatch = receiver;
},
};
userStore = new UserStore.Class(dispatcher);
var UserStore = module.__get__('UserStore');
userStore = new UserStore(dispatcher);
// Stub out the event emitter.
userStore.emit = function(event) {