Completed
Push — master ( ebbfd2...019445 )
by Jeroen De
62:46
created

ing the subscription handler created by makeEventHandlerWaitForAsyncFinish and no longer validating, event handler is calledꞌ)   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 13
rs 9.4285
c 1
b 0
f 0
1
'use strict';
2
3
var test = require( 'tape' ),
4
	sinon = require( 'sinon' ),
5
	storeUpdateHandling = require( '../lib/store_update_handling' )
6
	;
7
8
function createFakeStore( storeData ) {
9
	var unsubscribe = sinon.spy();
10
	return {
11
		// not an actual method of Redux store but convenient to access in tests
12
		unsubscribe: unsubscribe,
13
		subscribe: sinon.stub().returns( unsubscribe ),
14
		getState: sinon.stub().returns( storeData ),
15
		// Call all callback functions that were registered through calls to `subscribe`
16
		fakeUpdate: function () {
17
			var subscribeCalls = this.subscribe.args;
18
			subscribeCalls.forEach( function ( subscribeArguments ) {
19
				// get the first argument to the `subscribe` call
20
				var updateCallback = subscribeArguments[ 0 ];
21
				// call the callback, using its own context
22
				updateCallback.call( updateCallback );
23
			} );
24
		}
25
	};
26
}
27
28
test( 'connect validators to store updates', function ( t ) {
29
	var validator = {
30
			dispatchIfChanged: sinon.spy()
31
		},
32
		validatorFactory = sinon.stub().returns( [ validator ] ),
33
		storeData = { formContent: { test: 'dummy store contents' } },
34
		store = createFakeStore( storeData );
35
36
	storeUpdateHandling.connectValidatorsToStore( validatorFactory, store, {}, 'formContent' );
37
	store.fakeUpdate();
38
39
	t.ok( validator.dispatchIfChanged.calledOnce, 'validator dispatch method is only called once' );
40
	t.ok( validator.dispatchIfChanged.calledWith( storeData.formContent ), 'validator dispatch method is called with the form contents' );
41
	t.end();
42
} );
43
44
test( 'initial values passed to validator factory default to formValues from the store', function ( t ) {
45
	var validator = {
46
			dispatchIfChanged: sinon.spy()
47
		},
48
		validatorFactory = sinon.stub().returns( [ validator ] ),
49
		initialStoreFormContent = { paymentType: 'PPL' },
50
		storeData = { formContent: initialStoreFormContent },
51
		store = createFakeStore( storeData );
52
53
	storeUpdateHandling.connectValidatorsToStore( validatorFactory, store, {}, 'formContent' );
54
55
	t.ok(
56
		validatorFactory.firstCall.calledWith( initialStoreFormContent ),
57
		'validator factory is called with initial values from store'
58
	);
59
	t.end();
60
} );
61
62
test( 'initial values are passed to validator factory can be changed on initialization', function ( t ) {
63
	var validator = {
64
			dispatchIfChanged: sinon.spy()
65
		},
66
		validatorFactory = sinon.stub().returns( [ validator ] ),
67
		initialStoreFormContent = { paymentType: 'PPL' },
68
		storeData = { formContent: initialStoreFormContent },
69
		store = createFakeStore( storeData ),
70
		initialValues = { paymentType: 'BTC' };
71
72
	storeUpdateHandling.connectValidatorsToStore( validatorFactory, store, initialValues, 'formContent' );
73
74
	t.ok(
75
		validatorFactory.firstCall.calledWith( initialValues ),
76
		'validator factory is called with initial values from store'
77
	);
78
	t.end();
79
} );
80
81
test( 'connect components to store updates', function ( t ) {
82
	var component = {
83
			render: sinon.spy()
84
		},
85
		storeData = { formContent: { test: 'dummy store contents' } },
86
		store = createFakeStore( storeData );
87
88
	storeUpdateHandling.connectComponentsToStore( [ component ], store, 'formContent' );
89
	store.fakeUpdate();
90
91
	t.ok( component.render.calledOnce, 'render method of component is called once' );
92
	t.ok( component.render.calledWith( storeData.formContent ), 'render method is called with the form contents' );
93
	t.end();
94
} );
95
96
test( 'connect view handlers to store updates', function ( t ) {
97
	var viewHandler = {
98
			update: sinon.spy()
99
		},
100
		viewHandlerConfig = {
101
			viewHandler: viewHandler,
102
			stateKey: 'numberOfCats'
103
		},
104
		storeData = { numberOfCats: 42, numberOfDogs: 23 },
105
		store = createFakeStore( storeData );
106
107
	storeUpdateHandling.connectViewHandlersToStore( [ viewHandlerConfig ], store );
108
	store.fakeUpdate();
109
110
	t.ok( viewHandler.update.calledOnce, 'view handler update method is only called once' );
111
	t.ok( viewHandler.update.calledWith( 42 ), 'view handler get passed only selected state parts' );
112
	t.end();
113
} );
114
115
test( 'connect view handlers to deeply nested store values', function ( t ) {
116
	var viewHandler = {
117
			update: sinon.spy()
118
		},
119
		viewHandlerConfig = {
120
			viewHandler: viewHandler,
121
			stateKey: 'facts.cats.number'
122
		},
123
		storeData = { facts: { cats: { number: 42, owners: 3 } } },
124
		store = createFakeStore( storeData );
125
126
	storeUpdateHandling.connectViewHandlersToStore( [ viewHandlerConfig ], store );
127
	store.fakeUpdate();
128
129
	t.ok( viewHandler.update.calledOnce, 'view handler update method is only called once' );
130
	t.ok( viewHandler.update.calledWith( 42 ), 'view handler get passed only selected state parts' );
131
	t.end();
132
} );
133
134
test( 'when not validating, makeEventHandlerWaitForAsyncFinish executes handler instantly ', function ( t ) {
135
	var eventHandler = sinon.spy(),
136
		storeData = { asynchronousRequests: { isValidating: false } },
137
		store = createFakeStore( storeData ),
138
		wrappedHandler = storeUpdateHandling.makeEventHandlerWaitForAsyncFinish( eventHandler, store );
139
140
	wrappedHandler();
141
142
	t.ok( eventHandler.calledOnce );
143
	t.end();
144
} );
145
146
test( 'when validating, makeEventHandlerWaitForAsyncFinish adds a new subscription to store ', function ( t ) {
147
	var eventHandler = sinon.spy(),
148
		storeData = { asynchronousRequests: { isValidating: true } },
149
		store = createFakeStore( storeData ),
150
		wrappedHandler = storeUpdateHandling.makeEventHandlerWaitForAsyncFinish( eventHandler, store );
151
152
	wrappedHandler();
153
154
	t.ok( store.subscribe.calledOnce, 'a new subscription was added' );
155
	t.notOk( eventHandler.called, 'event handler should not be called' );
156
	t.end();
157
} );
158
159
test( 'calling the subscription handler created by makeEventHandlerWaitForAsyncFinish and still validating, nothing happens', function ( t ) {
160
	var eventHandler = sinon.spy(),
161
		storeData = { asynchronousRequests: { isValidating: true } },
162
		store = createFakeStore( storeData ),
163
		wrappedHandler = storeUpdateHandling.makeEventHandlerWaitForAsyncFinish( eventHandler, store );
164
165
	wrappedHandler();
166
	store.fakeUpdate();
167
168
	t.notOk( eventHandler.called, 'event handler should not be called' );
169
	t.end();
170
} );
171
172
test( 'calling the subscription handler created by makeEventHandlerWaitForAsyncFinish and no longer validating, event handler is called', function ( t ) {
173
	var eventHandler = sinon.spy(),
174
		storeData = { asynchronousRequests: { isValidating: true } },
175
		store = createFakeStore( storeData ),
176
		wrappedHandler = storeUpdateHandling.makeEventHandlerWaitForAsyncFinish( eventHandler, store );
177
178
	wrappedHandler();
179
	store.getState = sinon.stub().returns( { asynchronousRequests: { isValidating: false } } );
180
	store.fakeUpdate();
181
182
	t.ok( eventHandler.calledOnce, 'event handler must be be called' );
183
	t.end();
184
} );
185
186
test( 'calling the subscription handler created by makeEventHandlerWaitForAsyncFinish and no longer validating, unsubscribes from store', function ( t ) {
187
	var eventHandler = sinon.spy(),
188
		storeData = { asynchronousRequests: { isValidating: true } },
189
		store = createFakeStore( storeData ),
190
		wrappedHandler = storeUpdateHandling.makeEventHandlerWaitForAsyncFinish( eventHandler, store );
191
192
	wrappedHandler();
193
	store.getState = sinon.stub().returns( { asynchronousRequests: { isValidating: false } } );
194
	store.fakeUpdate();
195
196
	t.ok( store.unsubscribe.calledOnce, 'event handler must be be called' );
197
	t.end();
198
} );
199