UNPKG

7.33 kBJavaScriptView Raw
1const { expect, assert } = require('chai')
2const nock = require('nock')
3
4describe('Dependency', () => {
5 let Dependency
6 let dependency
7 let DependencyFactory
8
9 function makeDependencyWithStrategy (dependencyConfig, strategy) {
10 const Injector = require('../lib/util/injector')
11 const mockedStrategyInjector = Injector((name) => strategy)
12 DependencyFactory = require('../lib/dependency')
13 dependencyConfig.strategy = { type: 'mockedStrategy' }
14 return DependencyFactory(mockedStrategyInjector)(dependencyConfig)
15 }
16
17 before(() => {
18 DependencyFactory = require('../lib/dependency')
19 const CodependencyMock = require('./mocks/codependency')
20 const Injector = require('../lib/util/injector')
21
22 Dependency = DependencyFactory(
23 Injector(CodependencyMock({
24 'node-fetch': require('node-fetch')
25 }))
26 )
27 })
28
29 beforeEach(() => {
30 dependency = Dependency({ name: 'test-dependency', url: 'http://example.com' })
31 })
32
33 it('should export a function', () => {
34 expect(Dependency).to.be.a('function')
35 })
36
37 it('should accept not having a url parameter', () => {
38 const dependency = Dependency({ name: 'test-dependency' })
39 assert.isUndefined(dependency.url)
40 })
41
42 describe('onHealthy()', () => {
43 it('should mark a dependency as healthy', () => {
44 dependency.onHealthy()
45
46 expect(dependency.healthy).to.equal(true)
47 })
48 })
49
50 describe('onUnhealthy()', () => {
51 it('should mark a dependency as unhealthy', () => {
52 dependency.onUnhealthy()
53
54 expect(dependency.healthy).to.equal(false)
55 })
56 })
57
58 describe('healthSummary', () => {
59 const baseDependencyConfig = {
60 name: 'token',
61 url: 'kitty-kitty'
62 }
63
64 it('should return health summary of the dependency', () => {
65 dependency.onHealthy()
66
67 expect({
68 name: 'test-dependency',
69 healthy: true,
70 level: 'SOFT',
71 lastChecked: dependency.lastChecked
72 }).to.deep.equal(dependency.healthSummary)
73 })
74
75 it('Can improve the summary on healthy', () => {
76 const dependency = makeDependencyWithStrategy(baseDependencyConfig, {
77 check () {
78 return Promise.resolve({ iAm: 'fine' })
79 },
80 improveSummary (summary, checkResult) {
81 summary.whatDidISay = checkResult.iAm
82 }
83 })
84
85 return dependency
86 .check()
87 .then(() => {
88 const summary = dependency.healthSummary
89 expect(summary.healthy).to.equal(true)
90 assert.isDefined(summary.whatDidISay)
91 expect(summary.whatDidISay).to.equal('fine')
92 })
93 })
94
95 it('Can report on unhealthy if information is provided', () => {
96 const dependency = makeDependencyWithStrategy(baseDependencyConfig, {
97 check () {
98 return Promise.resolve({ iAm: 'not fine' })
99 },
100 areYouOk (result) {
101 return false // this dependency is never healthy
102 },
103 improveSummary (summary, checkResult) {
104 summary.whatDidISay = checkResult.iAm
105 }
106 })
107
108 return dependency
109 .check() // will throw, cause unhealthy
110 .catch(() => {
111 const summary = dependency.healthSummary
112 expect(summary.healthy).to.equal(false)
113 assert.isDefined(summary.whatDidISay)
114 expect(summary.whatDidISay).to.equal('not fine')
115 })
116 })
117
118 it('Cleanes up past enhancement when in throw mode and unhealthly', () => {
119 let howIFeel = 'fine'
120 const dependency = makeDependencyWithStrategy(baseDependencyConfig, {
121 check () {
122 const iAmHealthy = howIFeel === 'fine'
123 if (iAmHealthy) {
124 return Promise.resolve({ iAm: howIFeel })
125 }
126 return Promise.reject(new Error('Argh'))
127 },
128 improveSummary (summary, checkResult) {
129 if (checkResult) {
130 summary.whatDidISay = checkResult.iAm
131 }
132 }
133 })
134
135 return dependency
136 .check() // check once, healthy
137 .then(() => {
138 howIFeel = 'not fine'
139 const summary = dependency.healthSummary
140 expect(summary.healthy).to.equal(true)
141 assert.isDefined(summary.whatDidISay)
142 expect(summary.whatDidISay).to.equal('fine')
143 return new Promise((resolve, reject) => {
144 dependency.check() // check again, unhealthy
145 .then(reject)
146 .catch(() => {
147 const summary = dependency.healthSummary
148 expect(summary.healthy).to.equal(false)
149 assert.isUndefined(summary.whatDidISay) // when in throwing mode, there is no way to provide health information to the summary
150 resolve()
151 })
152 })
153 })
154 })
155 })
156
157 describe('check()', () => {
158 it('should return a promise', () => {
159 nock('http://example.com')
160 .get('/')
161 .reply(200)
162
163 expect(dependency.check().then).to.be.a('function')
164 })
165
166 it('should return health info when healthy', () => {
167 nock('http://example.com')
168 .get('/')
169 .reply(200)
170
171 return dependency
172 .check()
173 .then((r) => {
174 expect({
175 name: 'test-dependency',
176 healthy: true,
177 level: 'SOFT',
178 lastChecked: r.lastChecked
179 }).to.deep.equal(r)
180 })
181 })
182
183 it('should return health info when unhealthy', () => {
184 nock('http://example.com')
185 .get('/')
186 .reply(404)
187
188 return dependency
189 .check(1, 500)
190 .catch((r) => {
191 expect({
192 name: 'test-dependency',
193 healthy: false,
194 level: 'SOFT',
195 lastChecked: r.lastChecked
196 }).to.deep.equal(r)
197 })
198 })
199
200 it('should check a dependency\'s health if retries > 1', () => {
201 nock('http://example.com')
202 .get('/')
203 .reply(400)
204
205 return dependency
206 .check(2, 100)
207 .catch((r) => {
208 expect({
209 name: 'test-dependency',
210 healthy: false,
211 level: 'SOFT',
212 lastChecked: r.lastChecked
213 }).to.deep.equal(r)
214 })
215 })
216
217 describe('with a nominally non-throwing dependency', () => {
218 const baseDependencyConfig = {
219 name: 'token',
220 url: 'kitty-kitty'
221 }
222
223 it('reports healthy', () => {
224 const dependency = makeDependencyWithStrategy(baseDependencyConfig, {
225 check () {
226 return Promise.resolve({ iAm: 'fine' })
227 },
228 areYouOk (data) {
229 return data.iAm === 'fine'
230 }
231 })
232 return dependency
233 .check()
234 .then((r) => {
235 expect(r.healthy).to.equal(true)
236 })
237 })
238
239 it('reports unhealthy', () => {
240 const dependency = makeDependencyWithStrategy(baseDependencyConfig, {
241 check () {
242 return Promise.resolve({ iAm: 'not fine' })
243 },
244 areYouOk (data) {
245 return data.iAm === 'fine'
246 }
247 })
248 return new Promise((resolve, reject) => {
249 dependency
250 .check()
251 .then(reject)
252 .catch((r) => {
253 expect(r.healthy).to.equal(false)
254 resolve()
255 })
256 })
257 })
258 })
259 })
260})