Skip to content

Commit b10f052

Browse files
committed
Add unit tests
1 parent 27443a7 commit b10f052

File tree

5 files changed

+218
-21
lines changed

5 files changed

+218
-21
lines changed

providers/upgrade/defUpgradeQueue.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class DefinitionQueueUpgrader extends DefinitionVersionChecker {
3434
return this._upgrade.initialize()
3535
}
3636

37-
setupProcessing(definitionService, logger) {
38-
return setup(this._upgrade, definitionService, logger)
37+
setupProcessing(definitionService, logger, once) {
38+
return setup(this._upgrade, definitionService, logger, once)
3939
}
4040
}
4141

providers/upgrade/process.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class DefinitionUpgrader {
5959
let queueHandler
6060
let defUpgrader
6161

62-
function setup(_queue, _definitionService, _logger, _defVersionChecker = factory(), once = false) {
62+
function setup(_queue, _definitionService, _logger, once = false, _defVersionChecker = factory()) {
6363
defUpgrader = new DefinitionUpgrader(_definitionService, _logger, _defVersionChecker)
6464
queueHandler = new QueueHandler(_queue, _logger, defUpgrader)
6565
return queueHandler.work(once)
+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// (c) Copyright 2024, SAP SE and ClearlyDefined contributors. Licensed under the MIT license.
2+
// SPDX-License-Identifier: MIT
3+
4+
const chaiAsPromised = require('chai-as-promised')
5+
const chai = require('chai')
6+
chai.use(chaiAsPromised)
7+
const { expect } = require('chai')
8+
const sinon = require('sinon')
9+
const DefinitionQueueUpgrader = require('../../../providers/upgrade/defUpgradeQueue')
10+
11+
describe('DefinitionQueueUpgrader', () => {
12+
const definition = { coordinates: 'test', _meta: { schemaVersion: '1.0.0' } }
13+
let queue, upgrader
14+
15+
beforeEach(async () => {
16+
const logger = { debug: sinon.stub() }
17+
queue = {
18+
queue: sinon.stub().resolves(),
19+
initialize: sinon.stub().resolves()
20+
}
21+
const queueFactory = sinon.stub().returns(queue)
22+
upgrader = new DefinitionQueueUpgrader({ logger, queue: queueFactory })
23+
})
24+
25+
it('returns an instance of DefinitionQueueUpgrader', () => {
26+
expect(upgrader).to.be.an.instanceOf(DefinitionQueueUpgrader)
27+
})
28+
29+
it('sets and gets current schema version', () => {
30+
upgrader.currentSchema = '1.0.0'
31+
expect(upgrader.currentSchema).to.equal('1.0.0')
32+
})
33+
34+
it('initializes', async () => {
35+
await upgrader.initialize()
36+
expect(queue.initialize.calledOnce).to.be.true
37+
})
38+
39+
it('connects to queue after setupProcessing', async () => {
40+
await upgrader.initialize()
41+
const definitionService = { currentSchema: '1.0.0' }
42+
const logger = { debug: sinon.stub() }
43+
queue.dequeueMultiple = sinon.stub().resolves([])
44+
upgrader.setupProcessing(definitionService, logger, true)
45+
expect(queue.dequeueMultiple.calledOnce).to.be.true
46+
})
47+
48+
context('validate', () => {
49+
it('should fail if current schema version is not set', async () => {
50+
await expect(upgrader.validate(definition)).to.be.rejectedWith(Error)
51+
})
52+
53+
it('fails if it is not initialized', async () => {
54+
upgrader.currentSchema = '1.0.0'
55+
const stale = { coordinates: 'test', _meta: { schemaVersion: '0.0.1' } }
56+
await expect(upgrader.validate(stale)).to.be.rejectedWith(Error)
57+
})
58+
})
59+
60+
context('validate after set up', () => {
61+
beforeEach(async () => {
62+
await upgrader.initialize()
63+
upgrader.currentSchema = '1.0.0'
64+
})
65+
66+
it('does not queue null definition', async () => {
67+
const result = await upgrader.validate(null)
68+
expect(result).to.be.not.ok
69+
expect(queue.queue.called).to.be.false
70+
})
71+
72+
it('does not queue an up-to-date definition', async () => {
73+
const definition = { coordinates: 'test', _meta: { schemaVersion: '1.0.0' } }
74+
const result = await upgrader.validate(definition)
75+
expect(result).to.deep.equal(definition)
76+
expect(queue.queue.called).to.be.false
77+
})
78+
79+
it('queues and returns a stale definition', async () => {
80+
const definition = { coordinates: 'test', _meta: { schemaVersion: '0.0.1' } }
81+
const result = await upgrader.validate(definition)
82+
expect(result).to.deep.equal(definition)
83+
expect(queue.queue.calledOnce).to.be.true
84+
})
85+
})
86+
})
+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// (c) Copyright 2024, SAP SE and ClearlyDefined contributors. Licensed under the MIT license.
2+
// SPDX-License-Identifier: MIT
3+
4+
const { expect } = require('chai')
5+
const sinon = require('sinon')
6+
const { DefinitionVersionChecker, factory } = require('../../../providers/upgrade/defVersionCheck')
7+
8+
describe('DefinitionVersionChecker', () => {
9+
let logger, checker
10+
beforeEach(() => {
11+
logger = { debug: sinon.stub() }
12+
checker = new DefinitionVersionChecker({ logger })
13+
})
14+
15+
it('returns an instance of DefinitionVersionChecker', () => {
16+
expect(checker).to.be.an.instanceOf(DefinitionVersionChecker)
17+
})
18+
19+
it('creates a new instance of DefinitionVersionChecker using factory', () => {
20+
const checker = factory({ logger: logger })
21+
expect(checker).to.be.an.instanceOf(DefinitionVersionChecker)
22+
})
23+
24+
it('sets and gets current schema version', () => {
25+
checker.currentSchema = '1.0.0'
26+
expect(checker.currentSchema).to.equal('1.0.0')
27+
})
28+
29+
it('initializes and returns undefined', async () => {
30+
const result = await checker.initialize()
31+
expect(result).to.be.not.ok
32+
})
33+
34+
it('returns after setupProcessing', async () => {
35+
const result = checker.setupProcessing()
36+
expect(result).to.be.not.ok
37+
})
38+
39+
it('throws an error in validate if current schema version is not set', async () => {
40+
const definition = { _meta: { schemaVersion: '1.0.0' } }
41+
let errorMessage = ''
42+
try {
43+
await checker.validate(definition)
44+
fail('should have failed')
45+
} catch (error) {
46+
errorMessage = error.message
47+
}
48+
expect(errorMessage).to.be.not.empty
49+
})
50+
51+
context('validate after current schema version is set', () => {
52+
beforeEach(() => {
53+
checker.currentSchema = '1.0.0'
54+
})
55+
56+
it('returns the definition if it is up-to-date', async () => {
57+
const definition = { _meta: { schemaVersion: '1.0.0' } }
58+
const result = await checker.validate(definition)
59+
expect(result).to.deep.equal(definition)
60+
})
61+
62+
it('returns undefined for a stale definition', async () => {
63+
const definition = { _meta: { schemaVersion: '0.1.0' } }
64+
const result = await checker.validate(definition)
65+
expect(result).to.be.undefined
66+
})
67+
68+
it('returns undefined for a definition without schema version', async () => {
69+
const definition = {}
70+
const result = await checker.validate(definition)
71+
expect(result).to.be.undefined
72+
})
73+
74+
it('handles null', async () => {
75+
checker.currentSchema = '1.0.0'
76+
const result = await checker.validate(null)
77+
expect(result).to.be.not.ok
78+
})
79+
})
80+
})

test/providers/upgrade/process.js test/providers/upgrade/processTest.js

+49-18
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@ const sinon = require('sinon')
66
const { QueueHandler, DefinitionUpgrader } = require('../../../providers/upgrade/process')
77

88
describe('Definition Upgrade Queue Processing', () => {
9+
let logger
10+
11+
beforeEach(() => {
12+
logger = {
13+
info: sinon.stub(),
14+
error: sinon.stub(),
15+
debug: sinon.stub()
16+
}
17+
})
18+
919
describe('QueueHandler', () => {
10-
let logger, queue, messageHandler, handler
20+
let queue, messageHandler, handler
21+
1122
beforeEach(() => {
12-
logger = {
13-
info: sinon.stub(),
14-
error: sinon.stub()
15-
}
1623
queue = {
1724
dequeueMultiple: sinon.stub(),
1825
delete: sinon.stub().resolves()
@@ -23,35 +30,45 @@ describe('Definition Upgrade Queue Processing', () => {
2330
handler = new QueueHandler(queue, logger, messageHandler)
2431
})
2532

26-
it('should return an instance of QueueHandler', () => {
33+
it('returns an instance of QueueHandler', () => {
2734
expect(handler).to.be.an.instanceOf(QueueHandler)
2835
})
2936

30-
it('should work on a queue', () => {
37+
it('works on a queue', () => {
3138
queue.dequeueMultiple.resolves([])
3239
handler.work(true)
3340
expect(queue.dequeueMultiple.calledOnce).to.be.true
3441
expect(messageHandler.processMessage.notCalled).to.be.true
3542
expect(queue.delete.notCalled).to.be.true
3643
})
3744

38-
it('should process one message', async () => {
45+
it('processes one message', async () => {
3946
queue.dequeueMultiple.resolves([{ message: 'test' }])
4047
await handler.work(true)
4148
expect(queue.dequeueMultiple.calledOnce).to.be.true
4249
expect(messageHandler.processMessage.calledOnce).to.be.true
4350
expect(queue.delete.calledOnce).to.be.true
4451
})
4552

46-
it('should process multiple messages', async () => {
53+
it('processes multiple messages', async () => {
4754
queue.dequeueMultiple.resolves([{ message: 'testA' }, { message: 'testB' }])
4855
await handler.work(true)
4956
expect(queue.dequeueMultiple.calledOnce).to.be.true
5057
expect(messageHandler.processMessage.calledTwice).to.be.true
5158
expect(queue.delete.calledTwice).to.be.true
5259
})
5360

54-
it('should log error and not delete the message', async () => {
61+
it('handles if error is thrown', async () => {
62+
queue.dequeueMultiple.resolves([{ message: 'testA' }])
63+
messageHandler.processMessage = sinon.stub().throws()
64+
await handler.work(true)
65+
expect(queue.dequeueMultiple.calledOnce).to.be.true
66+
expect(messageHandler.processMessage.calledOnce).to.be.true
67+
expect(queue.delete.called).to.be.false
68+
expect(logger.error.calledOnce).to.be.true
69+
})
70+
71+
it('handles both sucessful and unsucessful messages', async () => {
5572
queue.dequeueMultiple.resolves([{ message: 'testA' }, { message: 'testB' }])
5673
messageHandler.processMessage = sinon.stub().onFirstCall().throws().onSecondCall().resolves()
5774
await handler.work(true)
@@ -63,13 +80,10 @@ describe('Definition Upgrade Queue Processing', () => {
6380
})
6481

6582
describe('DefinitionUpgrader', () => {
66-
const definition = { coordinates: 'pypi/pypi/-/test/revision' }
67-
let logger, definitionService, versionChecker, upgrader
83+
const definition = Object.freeze({ coordinates: 'pypi/pypi/-/test/revision' })
84+
let definitionService, versionChecker, upgrader
85+
6886
beforeEach(() => {
69-
logger = {
70-
info: sinon.stub(),
71-
debug: sinon.stub()
72-
}
7387
definitionService = {
7488
getStored: sinon.stub(),
7589
computeStoreAndCurate: sinon.stub().resolves()
@@ -80,7 +94,7 @@ describe('Definition Upgrade Queue Processing', () => {
8094
upgrader = new DefinitionUpgrader(definitionService, logger, versionChecker)
8195
})
8296

83-
it('should recompute a definition', async () => {
97+
it('recomputes a definition, if a definition is not up-to-date', async () => {
8498
definitionService.getStored.resolves(definition)
8599
versionChecker.validate.resolves()
86100

@@ -90,7 +104,7 @@ describe('Definition Upgrade Queue Processing', () => {
90104
expect(definitionService.computeStoreAndCurate.calledOnce).to.be.true
91105
})
92106

93-
it('should skip compute when a definition is up-to-date', async () => {
107+
it('skips compute if a definition is up-to-date', async () => {
94108
definitionService.getStored.resolves(definition)
95109
versionChecker.validate.resolves(definition)
96110

@@ -99,5 +113,22 @@ describe('Definition Upgrade Queue Processing', () => {
99113
expect(versionChecker.validate.calledOnce).to.be.true
100114
expect(definitionService.computeStoreAndCurate.notCalled).to.be.true
101115
})
116+
117+
it('computes if a definition does not exist', async () => {
118+
definitionService.getStored.resolves()
119+
versionChecker.validate.resolves()
120+
121+
await upgrader.processMessage({ data: { coordinates: 'pypi/pypi/-/test/revision' } })
122+
expect(definitionService.getStored.calledOnce).to.be.true
123+
expect(versionChecker.validate.calledOnce).to.be.true
124+
expect(definitionService.computeStoreAndCurate.calledOnce).to.be.true
125+
})
126+
127+
it('skips if there is no coordinates', async () => {
128+
await upgrader.processMessage({ data: {} })
129+
expect(definitionService.getStored.notCalled).to.be.true
130+
expect(versionChecker.validate.notCalled).to.be.true
131+
expect(definitionService.computeStoreAndCurate.notCalled).to.be.true
132+
})
102133
})
103134
})

0 commit comments

Comments
 (0)