138 lines
3.8 KiB
JavaScript
138 lines
3.8 KiB
JavaScript
![]() |
import { Observable, config } from 'rx';
|
||
|
import test from 'tape';
|
||
|
import proxy from 'proxyquire';
|
||
|
import sinon from 'sinon';
|
||
|
import types from './types';
|
||
|
|
||
|
config.longStackSupport = true;
|
||
|
const challengeSelectorStub = {};
|
||
|
const stepChallengeEpic = proxy(
|
||
|
'./step-challenge-epic',
|
||
|
{ './selectors': challengeSelectorStub }
|
||
|
);
|
||
|
|
||
|
const file = 'common/app/routes/challenges/redux/step-challenge-epic';
|
||
|
test(file, function(t) {
|
||
|
t.test('does not respond to random actions', t => {
|
||
|
const actions = Observable.of({ type: 'NotTheMomma' });
|
||
|
let called = false;
|
||
|
stepChallengeEpic(actions, () => {})
|
||
|
.subscribe(
|
||
|
() => { called = true; },
|
||
|
e => t.fail(e),
|
||
|
() => {
|
||
|
if (!called) {
|
||
|
t.pass();
|
||
|
} else {
|
||
|
t.fail(new Error('epic should not respond'));
|
||
|
}
|
||
|
t.end();
|
||
|
}
|
||
|
);
|
||
|
});
|
||
|
t.test('steps back', t => {
|
||
|
const actions = Observable.of({ type: types.stepBackward });
|
||
|
const state = { challengesApp: { currentIndex: 1 } };
|
||
|
const onNextSpy = sinon.spy();
|
||
|
challengeSelectorStub.challengeSelector = sinon.spy(_state => {
|
||
|
t.assert(_state === state, 'challenge selector not called with state');
|
||
|
return {
|
||
|
challenge: {
|
||
|
description: new Array(2)
|
||
|
}
|
||
|
};
|
||
|
});
|
||
|
stepChallengeEpic(actions, () => state)
|
||
|
.subscribe(
|
||
|
onNextSpy,
|
||
|
e => {
|
||
|
throw e;
|
||
|
},
|
||
|
() => {
|
||
|
t.assert(
|
||
|
onNextSpy.calledOnce,
|
||
|
'epic not called exactly once'
|
||
|
);
|
||
|
t.assert(
|
||
|
onNextSpy.calledWithMatch({
|
||
|
type: types.goToStep,
|
||
|
payload: 0
|
||
|
}),
|
||
|
'Epic did not return the expected action'
|
||
|
);
|
||
|
delete challengeSelectorStub.challengeSelector;
|
||
|
t.end();
|
||
|
}
|
||
|
);
|
||
|
});
|
||
|
t.test('steps forward', t => {
|
||
|
const actions = Observable.of({ type: types.stepForward });
|
||
|
const state = { challengesApp: { currentIndex: 0 } };
|
||
|
const onNextSpy = sinon.spy();
|
||
|
challengeSelectorStub.challengeSelector = sinon.spy(_state => {
|
||
|
t.assert(_state === state, 'challenge selector not called with state');
|
||
|
return {
|
||
|
challenge: {
|
||
|
description: new Array(2)
|
||
|
}
|
||
|
};
|
||
|
});
|
||
|
stepChallengeEpic(actions, () => state)
|
||
|
.subscribe(
|
||
|
onNextSpy,
|
||
|
e => {
|
||
|
throw e;
|
||
|
},
|
||
|
() => {
|
||
|
t.assert(
|
||
|
onNextSpy.calledOnce,
|
||
|
'epic not called exactly once'
|
||
|
);
|
||
|
t.assert(
|
||
|
onNextSpy.calledWithMatch({
|
||
|
type: types.goToStep,
|
||
|
payload: 1
|
||
|
}),
|
||
|
'Epic did not return the expected action'
|
||
|
);
|
||
|
delete challengeSelectorStub.challengeSelector;
|
||
|
t.end();
|
||
|
}
|
||
|
);
|
||
|
});
|
||
|
t.test('submits on last step forward', t => {
|
||
|
const actions = Observable.of({ type: types.stepForward });
|
||
|
const state = { challengesApp: { currentIndex: 1 } };
|
||
|
const onNextSpy = sinon.spy();
|
||
|
challengeSelectorStub.challengeSelector = sinon.spy(_state => {
|
||
|
t.assert(_state === state, 'challenge selector not called with state');
|
||
|
return {
|
||
|
challenge: {
|
||
|
description: new Array(2)
|
||
|
}
|
||
|
};
|
||
|
});
|
||
|
stepChallengeEpic(actions, () => state)
|
||
|
.subscribe(
|
||
|
onNextSpy,
|
||
|
e => {
|
||
|
throw e;
|
||
|
},
|
||
|
() => {
|
||
|
t.assert(
|
||
|
onNextSpy.calledOnce,
|
||
|
'epic not called exactly once'
|
||
|
);
|
||
|
t.assert(
|
||
|
onNextSpy.calledWithMatch({
|
||
|
type: types.submitChallenge
|
||
|
}),
|
||
|
'Epic did not return the expected action'
|
||
|
);
|
||
|
delete challengeSelectorStub.challengeSelector;
|
||
|
t.end();
|
||
|
}
|
||
|
);
|
||
|
});
|
||
|
});
|