1 | const { expect, assert } = require('chai')
|
2 | const nock = require('nock')
|
3 |
|
4 | describe('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
|
102 | },
|
103 | improveSummary (summary, checkResult) {
|
104 | summary.whatDidISay = checkResult.iAm
|
105 | }
|
106 | })
|
107 |
|
108 | return dependency
|
109 | .check()
|
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()
|
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()
|
145 | .then(reject)
|
146 | .catch(() => {
|
147 | const summary = dependency.healthSummary
|
148 | expect(summary.healthy).to.equal(false)
|
149 | assert.isUndefined(summary.whatDidISay)
|
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 | })
|