UNPKG

10.6 kBJavaScriptView Raw
1describe('Copacetic', () => {
2 const expect = require('chai').expect
3 const nock = require('nock')
4
5 let Copacetic
6 let dependencyLevel
7
8 before(() => {
9 const Dependency = require('../lib/dependency')
10 const Injector = require('../lib/util/injector')
11 const CodependencyMock = require('./mocks/codependency')
12
13 dependencyLevel = require('../lib/dependency-level')
14 Copacetic = require('../lib/copacetic')(
15 Dependency(Injector(CodependencyMock({
16 'node-fetch': require('node-fetch')
17 })))
18 )
19 })
20
21 it('should export a function', () => {
22 expect(Copacetic).to.be.a('function')
23 })
24
25 it('should return an instance of Copacetic', () => {
26 expect(Copacetic()).to.be.a('object')
27 })
28
29 describe('isCopacetic', () => {
30 it('should return true if a hard dependency is unhealthy', () => {
31 const copacetic = Copacetic()
32 copacetic.registerDependency({
33 name: 'My-Dependency',
34 url: 'http://example.com',
35 level: dependencyLevel.HARD
36 })
37
38 nock('http://example.com')
39 .get('/')
40 .reply(400)
41
42 copacetic
43 .check({ name: 'My-Dependency' })
44 .on('unhealthy', () => {
45 expect(copacetic.isCopaceticy).to.equal(true)
46 })
47 })
48
49 it('should return false if a soft dependency is unhealthy', () => {
50 const copacetic = Copacetic()
51 copacetic.registerDependency({
52 name: 'My-Dependency',
53 url: 'http://example.com',
54 level: dependencyLevel.SOFT
55 })
56
57 nock('http://example.com')
58 .get('/')
59 .reply(400)
60
61 copacetic
62 .check({ name: 'My-Dependency' })
63 .on('unhealthy', () => {
64 expect(copacetic.hasHardDependencyFailure).to.equal(false)
65 })
66 })
67
68 it('should return false if all dependencies are health', () => {
69 const copacetic = Copacetic()
70 copacetic.registerDependency({
71 name: 'My-Dependency',
72 url: 'http://example.com',
73 level: dependencyLevel.SOFT
74 })
75
76 nock('http://example.com')
77 .get('/')
78 .reply(200)
79
80 copacetic
81 .check({ name: 'My-Dependency' })
82 .on('healthy', () => {
83 expect(copacetic.hasHardDependencyFailure).to.equal(false)
84 })
85 })
86 })
87
88 describe('getCopaceticInfo', () => {
89 it('should return the health info for all registered dependencies', () => {
90 const copacetic = Copacetic()
91 copacetic.registerDependency({
92 name: 'My-Dependency',
93 url: 'http://example.com'
94 })
95
96 expect(copacetic.healthInfo).to.deep.equal(
97 [
98 {
99 name: 'My-Dependency',
100 healthy: true,
101 level: 'SOFT',
102 lastChecked: undefined
103 }
104 ]
105 )
106 })
107 })
108
109 describe('getDependency()', () => {
110 let copacetic
111
112 it('should look up a dependency given a dependency name', () => {
113 copacetic = Copacetic()
114 copacetic.registerDependency({
115 name: 'My-Dependency',
116 url: 'http://example.com'
117 })
118
119 expect(copacetic.getDependency('My-Dependency').name).to.equal('My-Dependency')
120 })
121
122 it('should look up a dependency given a dependency object', () => {
123 expect(
124 copacetic.getDependency(copacetic.getDependency('My-Dependency')).name
125 ).to.equal('My-Dependency')
126 })
127 })
128
129 describe('isDependencyRegistered', () => {
130 let copacetic
131
132 it('should return true if a dependency exists', () => {
133 copacetic = Copacetic()
134 copacetic.registerDependency({
135 name: 'My-Dependency',
136 url: 'http://example.com'
137 })
138
139 expect(copacetic.isDependencyRegistered('My-Dependency')).to.equal(true)
140 })
141
142 it('should return false if a dependency does not exist', () => {
143 expect(copacetic.isDependencyRegistered('Test-Dependency')).to.equal(false)
144 })
145 })
146
147 describe('registerDependency()', () => {
148 let copacetic
149
150 it('should register a dependency if it does not exist', () => {
151 copacetic = Copacetic()
152 copacetic.registerDependency({
153 name: 'My-Dependency',
154 url: 'http://example.com'
155 })
156
157 expect(copacetic.getDependency('My-Dependency').name).to.equal('My-Dependency')
158 })
159
160 it('should throw an error if a dependency exists', () => {
161 expect(() => copacetic.registerDependency({
162 name: 'My-Dependency',
163 url: 'http://example.com'
164 })).to.throw(Error)
165 })
166 })
167
168 describe('deregister()', () => {
169 let copacetic
170
171 it('should deregister a dependency if it does exist', () => {
172 copacetic = Copacetic()
173
174 copacetic.registerDependency({
175 name: 'My-Dependency',
176 url: 'http://example.com'
177 })
178
179 expect(copacetic.dependencyNames.indexOf('My-Dependency')).not.to.equal(-1)
180 expect(() => copacetic.deregisterDependency('My-Dependency')).not.to.throw(Error)
181 expect(copacetic.dependencyNames.indexOf('My-Dependency')).to.equal(-1)
182 })
183
184 it('should throw an error if the dependency does not exist', () => {
185 expect(() => copacetic.deregisterDependency('My-Dependencyyy')).to.throw(Error)
186 })
187 })
188
189 describe('checkAll()', () => {
190 it('should check the health of all registered dependencies', () => {
191 const copacetic = Copacetic()
192 copacetic.registerDependency({
193 name: 'My-Dependency',
194 url: 'http://example.com'
195 })
196 copacetic.registerDependency({
197 name: 'My-Other-Dependency',
198 url: 'http://other-example.com'
199 })
200
201 nock('http://example.com')
202 .get('/')
203 .reply(200)
204 nock('http://other-example.com')
205 .get('/')
206 .reply(200)
207
208 copacetic
209 .checkAll()
210 .on('healthy', (dependencyCopacetic) => {
211 expect(dependencyCopacetic).to.deep.equal([
212 {
213 name: 'My-Dependency',
214 healthy: true,
215 level: 'SOFT',
216 lastChecked: dependencyCopacetic.lastChecked
217 },
218 {
219 name: 'My-Other-Dependency',
220 healthy: true,
221 level: 'SOFT',
222 lastChecked: dependencyCopacetic.lastChecked
223 }
224 ])
225 })
226 })
227 })
228
229 describe('check()', () => {
230 describe('when checking one dependency', () => {
231 let copacetic
232
233 it('should emit an "healthy" event when checking a single healthy dependency', () => {
234 copacetic = Copacetic()
235 copacetic.registerDependency({
236 name: 'My-Dependency',
237 url: 'http://example.com'
238 })
239
240 nock('http://example.com')
241 .get('/')
242 .reply(200)
243
244 copacetic
245 .check({ name: 'My-Dependency' })
246 .on('healthy', (dependencyCopacetic) => {
247 expect(dependencyCopacetic).to.deep.equal({
248 name: 'My-Dependency',
249 healthy: true,
250 level: 'SOFT',
251 lastChecked: dependencyCopacetic.lastChecked
252 })
253 })
254 })
255 it('should emit an "unhealthy" event when checking a single unhealthy dependency', () => {
256 nock('http://example.com')
257 .get('/')
258 .reply(200)
259
260 copacetic
261 .check({ name: 'My-Dependency' })
262 .on('unhealthy', (dependencyCopacetic) => {
263 expect(dependencyCopacetic).to.deep.equal({
264 name: 'My-Dependency',
265 healthy: false,
266 level: 'SOFT',
267 lastChecked: dependencyCopacetic.lastChecked
268 })
269 })
270 })
271 })
272
273 describe('when checking multiple dependencies', () => {
274 it('should emit a "health" event when checking dependencies', () => {
275 let copacetic = Copacetic()
276 copacetic.registerDependency({
277 name: 'My-Dependency',
278 url: 'http://example.com'
279 })
280 .registerDependency({
281 name: 'My-Other-Dependency',
282 url: 'http://dankdependency.com'
283 })
284
285 nock('http://example.com')
286 .get('/')
287 .reply(200)
288 nock('http://dankdependency.com')
289 .get('/')
290 .reply(400)
291
292 copacetic
293 .check({
294 dependencies: [
295 { name: 'My-Dependency' },
296 { name: 'My-Other-Dependency' }
297 ],
298 parallel: false
299 })
300 .on('health', (healthSummary) => {
301 expect(healthSummary).to.deep.equal([
302 {
303 name: 'My-Dependency',
304 healthy: true,
305 level: 'SOFT',
306 lastChecked: healthSummary[0].lastChecked
307 },
308 {
309 name: 'My-Other-Dependency',
310 healthy: false,
311 level: 'SOFT',
312 lastChecked: healthSummary[1].lastChecked
313 }
314 ])
315 })
316 })
317 })
318 })
319
320 describe('poll()', () => {
321 it('should emit a "health" event, describing the status of dependencies', () => {
322 const copacetic = Copacetic()
323 copacetic.registerDependency({
324 name: 'My-Dependency',
325 url: 'http://example.com'
326 })
327 copacetic.registerDependency({
328 name: 'My-Other-Dependency',
329 url: 'http://dankdependency.com'
330 })
331
332 nock('http://example.com')
333 .get('/')
334 .reply(200)
335 nock('http://dankdependency.com')
336 .get('/')
337 .reply(400)
338
339 copacetic
340 .poll({
341 dependencies: [
342 { name: 'My-Dependency' },
343 { name: 'My-Other-Dependency' }
344 ]
345 })
346 .on('health', (healthSummary) => {
347 expect(healthSummary).to.deep.equal([
348 {
349 name: 'My-Dependency',
350 healthy: true,
351 level: 'SOFT',
352 lastChecked: healthSummary[0].lastChecked
353 },
354 {
355 name: 'My-Other-Dependency',
356 healthy: false,
357 level: 'SOFT',
358 lastChecked: healthSummary[1].lastChecked
359 }
360 ])
361 })
362
363 setTimeout(() => copacetic.stop(), 100)
364 })
365 })
366
367 describe('stop()', () => {
368 it('should stop polling dependencies', () => {
369 const copacetic = Copacetic()
370 copacetic.registerDependency({
371 name: 'My-Dependency',
372 url: 'http://example.com'
373 })
374
375 nock('http://example.com')
376 .get('/')
377 .reply(200)
378
379 copacetic.pollAll()
380 expect(copacetic.isPolling).to.equal(true)
381 copacetic.stop()
382 expect(copacetic.isPolling).to.equal(false)
383 })
384 })
385})