psf-bch-api 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env-local +9 -0
- package/bin/server.js +2 -1
- package/package.json +4 -1
- package/src/adapters/fulcrum-api.js +124 -0
- package/src/adapters/full-node-rpc.js +2 -6
- package/src/adapters/index.js +4 -0
- package/src/adapters/slp-indexer-api.js +124 -0
- package/src/config/env/common.js +21 -24
- package/src/controllers/rest-api/fulcrum/controller.js +563 -0
- package/src/controllers/rest-api/fulcrum/router.js +64 -0
- package/src/controllers/rest-api/full-node/blockchain/controller.js +4 -4
- package/src/controllers/rest-api/full-node/mining/controller.js +99 -0
- package/src/controllers/rest-api/full-node/mining/router.js +52 -0
- package/src/controllers/rest-api/full-node/rawtransactions/controller.js +333 -0
- package/src/controllers/rest-api/full-node/rawtransactions/router.js +58 -0
- package/src/controllers/rest-api/index.js +19 -3
- package/src/controllers/rest-api/slp/controller.js +218 -0
- package/src/controllers/rest-api/slp/router.js +55 -0
- package/src/controllers/timer-controller.js +1 -1
- package/src/use-cases/fulcrum-use-cases.js +155 -0
- package/src/use-cases/full-node-mining-use-cases.js +28 -0
- package/src/use-cases/full-node-rawtransactions-use-cases.js +121 -0
- package/src/use-cases/index.js +8 -0
- package/src/use-cases/slp-use-cases.js +321 -0
- package/test/unit/controllers/blockchain-controller-unit.js +2 -3
- package/test/unit/controllers/fulcrum-controller-unit.js +481 -0
- package/test/unit/controllers/mining-controller-unit.js +139 -0
- package/test/unit/controllers/rawtransactions-controller-unit.js +388 -0
- package/test/unit/controllers/rest-api-index-unit.js +59 -3
- package/test/unit/controllers/slp-controller-unit.js +312 -0
- package/test/unit/use-cases/fulcrum-use-cases-unit.js +297 -0
- package/test/unit/use-cases/full-node-mining-use-cases-unit.js +84 -0
- package/test/unit/use-cases/full-node-rawtransactions-use-cases-unit.js +267 -0
- package/test/unit/use-cases/slp-use-cases-unit.js +296 -0
- package/src/entities/event.js +0 -71
- package/test/integration/api/event-integration.js +0 -250
- package/test/integration/api/req-integration.js +0 -173
- package/test/integration/api/subscription-integration.js +0 -198
- package/test/integration/use-cases/manage-subscription-integration.js +0 -163
- package/test/integration/use-cases/publish-event-integration.js +0 -104
- package/test/integration/use-cases/query-events-integration.js +0 -95
- package/test/unit/entities/event-unit.js +0 -139
- /package/src/controllers/rest-api/full-node/blockchain/{index.js → router.js} +0 -0
- /package/src/controllers/rest-api/full-node/control/{index.js → router.js} +0 -0
- /package/src/controllers/rest-api/full-node/dsproof/{index.js → router.js} +0 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Unit tests for RawTransactionsRESTController.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { assert } from 'chai'
|
|
6
|
+
import sinon from 'sinon'
|
|
7
|
+
|
|
8
|
+
import RawTransactionsRESTController from '../../../src/controllers/rest-api/full-node/rawtransactions/controller.js'
|
|
9
|
+
import { createMockRequest, createMockResponse } from '../mocks/controller-mocks.js'
|
|
10
|
+
|
|
11
|
+
describe('#rawtransactions-controller.js', () => {
|
|
12
|
+
let sandbox
|
|
13
|
+
let mockAdapters
|
|
14
|
+
let mockUseCases
|
|
15
|
+
let uut
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
sandbox = sinon.createSandbox()
|
|
19
|
+
mockAdapters = {
|
|
20
|
+
fullNode: {
|
|
21
|
+
validateArraySize: sandbox.stub().returns(true)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
mockUseCases = {
|
|
25
|
+
rawtransactions: {
|
|
26
|
+
decodeRawTransaction: sandbox.stub().resolves({ txid: 'abc123' }),
|
|
27
|
+
decodeRawTransactions: sandbox.stub().resolves([{ txid: 'abc123' }]),
|
|
28
|
+
decodeScript: sandbox.stub().resolves({ asm: 'OP_DUP' }),
|
|
29
|
+
decodeScripts: sandbox.stub().resolves([{ asm: 'OP_DUP' }]),
|
|
30
|
+
getRawTransaction: sandbox.stub().resolves({ txid: 'abc123' }),
|
|
31
|
+
getRawTransactionWithHeight: sandbox.stub().resolves({ txid: 'abc123', height: 100 }),
|
|
32
|
+
getRawTransactions: sandbox.stub().resolves([{ txid: 'abc123' }]),
|
|
33
|
+
sendRawTransaction: sandbox.stub().resolves('txid123'),
|
|
34
|
+
sendRawTransactions: sandbox.stub().resolves(['txid1', 'txid2'])
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
uut = new RawTransactionsRESTController({
|
|
39
|
+
adapters: mockAdapters,
|
|
40
|
+
useCases: mockUseCases
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
afterEach(() => {
|
|
45
|
+
sandbox.restore()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
describe('#constructor()', () => {
|
|
49
|
+
it('should require adapters', () => {
|
|
50
|
+
assert.throws(() => {
|
|
51
|
+
// eslint-disable-next-line no-new
|
|
52
|
+
new RawTransactionsRESTController({ useCases: mockUseCases })
|
|
53
|
+
}, /Adapters library required/)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should require rawtransactions use cases', () => {
|
|
57
|
+
assert.throws(() => {
|
|
58
|
+
// eslint-disable-next-line no-new
|
|
59
|
+
new RawTransactionsRESTController({ adapters: mockAdapters, useCases: {} })
|
|
60
|
+
}, /RawTransactions use cases required/)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe('#root()', () => {
|
|
65
|
+
it('should return rawtransactions status', async () => {
|
|
66
|
+
const req = createMockRequest()
|
|
67
|
+
const res = createMockResponse()
|
|
68
|
+
|
|
69
|
+
await uut.root(req, res)
|
|
70
|
+
|
|
71
|
+
assert.equal(res.statusValue, 200)
|
|
72
|
+
assert.deepEqual(res.jsonData, { status: 'rawtransactions' })
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
describe('#decodeRawTransactionSingle()', () => {
|
|
77
|
+
it('should return decoded transaction on success', async () => {
|
|
78
|
+
const req = createMockRequest({ params: { hex: '01000000' } })
|
|
79
|
+
const res = createMockResponse()
|
|
80
|
+
|
|
81
|
+
await uut.decodeRawTransactionSingle(req, res)
|
|
82
|
+
|
|
83
|
+
assert.equal(res.statusValue, 200)
|
|
84
|
+
assert.deepEqual(res.jsonData, { txid: 'abc123' })
|
|
85
|
+
assert.isTrue(mockUseCases.rawtransactions.decodeRawTransaction.calledOnce)
|
|
86
|
+
assert.deepEqual(mockUseCases.rawtransactions.decodeRawTransaction.firstCall.args[0], { hex: '01000000' })
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('should return 400 if hex is empty', async () => {
|
|
90
|
+
const req = createMockRequest({ params: { hex: '' } })
|
|
91
|
+
const res = createMockResponse()
|
|
92
|
+
|
|
93
|
+
await uut.decodeRawTransactionSingle(req, res)
|
|
94
|
+
|
|
95
|
+
assert.equal(res.statusValue, 400)
|
|
96
|
+
assert.deepEqual(res.jsonData, { error: 'hex can not be empty' })
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should handle errors via handleError', async () => {
|
|
100
|
+
const error = new Error('RPC error')
|
|
101
|
+
error.status = 500
|
|
102
|
+
mockUseCases.rawtransactions.decodeRawTransaction.rejects(error)
|
|
103
|
+
const req = createMockRequest({ params: { hex: '01000000' } })
|
|
104
|
+
const res = createMockResponse()
|
|
105
|
+
|
|
106
|
+
await uut.decodeRawTransactionSingle(req, res)
|
|
107
|
+
|
|
108
|
+
assert.equal(res.statusValue, 500)
|
|
109
|
+
assert.deepEqual(res.jsonData, { error: 'RPC error' })
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
describe('#decodeRawTransactionBulk()', () => {
|
|
114
|
+
it('should return decoded transactions on success', async () => {
|
|
115
|
+
const req = createMockRequest({ body: { hexes: ['hex1', 'hex2'] } })
|
|
116
|
+
const res = createMockResponse()
|
|
117
|
+
|
|
118
|
+
await uut.decodeRawTransactionBulk(req, res)
|
|
119
|
+
|
|
120
|
+
assert.equal(res.statusValue, 200)
|
|
121
|
+
assert.deepEqual(res.jsonData, [{ txid: 'abc123' }])
|
|
122
|
+
assert.isTrue(mockUseCases.rawtransactions.decodeRawTransactions.calledOnce)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('should return 400 if hexes is not an array', async () => {
|
|
126
|
+
const req = createMockRequest({ body: { hexes: 'not-array' } })
|
|
127
|
+
const res = createMockResponse()
|
|
128
|
+
|
|
129
|
+
await uut.decodeRawTransactionBulk(req, res)
|
|
130
|
+
|
|
131
|
+
assert.equal(res.statusValue, 400)
|
|
132
|
+
assert.deepEqual(res.jsonData, { error: 'hexes must be an array' })
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('should return 400 if array is too large', async () => {
|
|
136
|
+
mockAdapters.fullNode.validateArraySize.returns(false)
|
|
137
|
+
const req = createMockRequest({ body: { hexes: new Array(25).fill('hex') } })
|
|
138
|
+
const res = createMockResponse()
|
|
139
|
+
|
|
140
|
+
await uut.decodeRawTransactionBulk(req, res)
|
|
141
|
+
|
|
142
|
+
assert.equal(res.statusValue, 400)
|
|
143
|
+
assert.deepEqual(res.jsonData, { error: 'Array too large.' })
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('should return 400 if empty hex encountered', async () => {
|
|
147
|
+
const req = createMockRequest({ body: { hexes: ['hex1', '', 'hex2'] } })
|
|
148
|
+
const res = createMockResponse()
|
|
149
|
+
|
|
150
|
+
await uut.decodeRawTransactionBulk(req, res)
|
|
151
|
+
|
|
152
|
+
assert.equal(res.statusValue, 400)
|
|
153
|
+
assert.deepEqual(res.jsonData, { error: 'Encountered empty hex' })
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
describe('#decodeScriptSingle()', () => {
|
|
158
|
+
it('should return decoded script on success', async () => {
|
|
159
|
+
const req = createMockRequest({ params: { hex: '76a914' } })
|
|
160
|
+
const res = createMockResponse()
|
|
161
|
+
|
|
162
|
+
await uut.decodeScriptSingle(req, res)
|
|
163
|
+
|
|
164
|
+
assert.equal(res.statusValue, 200)
|
|
165
|
+
assert.deepEqual(res.jsonData, { asm: 'OP_DUP' })
|
|
166
|
+
assert.isTrue(mockUseCases.rawtransactions.decodeScript.calledOnce)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('should return 400 if hex is empty', async () => {
|
|
170
|
+
const req = createMockRequest({ params: { hex: '' } })
|
|
171
|
+
const res = createMockResponse()
|
|
172
|
+
|
|
173
|
+
await uut.decodeScriptSingle(req, res)
|
|
174
|
+
|
|
175
|
+
assert.equal(res.statusValue, 400)
|
|
176
|
+
assert.deepEqual(res.jsonData, { error: 'hex can not be empty' })
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
describe('#decodeScriptBulk()', () => {
|
|
181
|
+
it('should return decoded scripts on success', async () => {
|
|
182
|
+
const req = createMockRequest({ body: { hexes: ['script1', 'script2'] } })
|
|
183
|
+
const res = createMockResponse()
|
|
184
|
+
|
|
185
|
+
await uut.decodeScriptBulk(req, res)
|
|
186
|
+
|
|
187
|
+
assert.equal(res.statusValue, 200)
|
|
188
|
+
assert.deepEqual(res.jsonData, [{ asm: 'OP_DUP' }])
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it('should return 400 if array is too large', async () => {
|
|
192
|
+
mockAdapters.fullNode.validateArraySize.returns(false)
|
|
193
|
+
const req = createMockRequest({ body: { hexes: new Array(25).fill('script') } })
|
|
194
|
+
const res = createMockResponse()
|
|
195
|
+
|
|
196
|
+
await uut.decodeScriptBulk(req, res)
|
|
197
|
+
|
|
198
|
+
assert.equal(res.statusValue, 400)
|
|
199
|
+
assert.deepEqual(res.jsonData, { error: 'Array too large.' })
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
describe('#getRawTransactionSingle()', () => {
|
|
204
|
+
it('should return raw transaction on success', async () => {
|
|
205
|
+
const req = createMockRequest({ params: { txid: 'a'.repeat(64) }, query: {} })
|
|
206
|
+
const res = createMockResponse()
|
|
207
|
+
|
|
208
|
+
await uut.getRawTransactionSingle(req, res)
|
|
209
|
+
|
|
210
|
+
assert.equal(res.statusValue, 200)
|
|
211
|
+
assert.deepEqual(res.jsonData, { txid: 'abc123', height: 100 })
|
|
212
|
+
assert.isTrue(mockUseCases.rawtransactions.getRawTransactionWithHeight.calledOnce)
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('should pass verbose=true when query param is set', async () => {
|
|
216
|
+
const req = createMockRequest({ params: { txid: 'a'.repeat(64) }, query: { verbose: 'true' } })
|
|
217
|
+
const res = createMockResponse()
|
|
218
|
+
|
|
219
|
+
await uut.getRawTransactionSingle(req, res)
|
|
220
|
+
|
|
221
|
+
assert.isTrue(mockUseCases.rawtransactions.getRawTransactionWithHeight.calledOnce)
|
|
222
|
+
assert.deepEqual(mockUseCases.rawtransactions.getRawTransactionWithHeight.firstCall.args[0], {
|
|
223
|
+
txid: 'a'.repeat(64),
|
|
224
|
+
verbose: true
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
it('should return 400 if txid is empty', async () => {
|
|
229
|
+
const req = createMockRequest({ params: { txid: '' } })
|
|
230
|
+
const res = createMockResponse()
|
|
231
|
+
|
|
232
|
+
await uut.getRawTransactionSingle(req, res)
|
|
233
|
+
|
|
234
|
+
assert.equal(res.statusValue, 400)
|
|
235
|
+
assert.deepEqual(res.jsonData, { error: 'txid can not be empty' })
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
it('should return 400 if txid length is not 64', async () => {
|
|
239
|
+
const req = createMockRequest({ params: { txid: 'short' } })
|
|
240
|
+
const res = createMockResponse()
|
|
241
|
+
|
|
242
|
+
await uut.getRawTransactionSingle(req, res)
|
|
243
|
+
|
|
244
|
+
assert.equal(res.statusValue, 400)
|
|
245
|
+
assert.deepEqual(res.jsonData, { error: 'parameter 1 must be of length 64 (not 5)' })
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
describe('#getRawTransactionBulk()', () => {
|
|
250
|
+
it('should return raw transactions on success', async () => {
|
|
251
|
+
const req = createMockRequest({
|
|
252
|
+
body: {
|
|
253
|
+
txids: ['a'.repeat(64), 'b'.repeat(64)],
|
|
254
|
+
verbose: true
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
const res = createMockResponse()
|
|
258
|
+
|
|
259
|
+
await uut.getRawTransactionBulk(req, res)
|
|
260
|
+
|
|
261
|
+
assert.equal(res.statusValue, 200)
|
|
262
|
+
assert.deepEqual(res.jsonData, [{ txid: 'abc123' }])
|
|
263
|
+
assert.isTrue(mockUseCases.rawtransactions.getRawTransactions.calledOnce)
|
|
264
|
+
assert.deepEqual(mockUseCases.rawtransactions.getRawTransactions.firstCall.args[0], {
|
|
265
|
+
txids: ['a'.repeat(64), 'b'.repeat(64)],
|
|
266
|
+
verbose: true
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
it('should return 400 if txids is not an array', async () => {
|
|
271
|
+
const req = createMockRequest({ body: { txids: 'not-array' } })
|
|
272
|
+
const res = createMockResponse()
|
|
273
|
+
|
|
274
|
+
await uut.getRawTransactionBulk(req, res)
|
|
275
|
+
|
|
276
|
+
assert.equal(res.statusValue, 400)
|
|
277
|
+
assert.deepEqual(res.jsonData, { error: 'txids must be an array' })
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
it('should return 400 if array is too large', async () => {
|
|
281
|
+
mockAdapters.fullNode.validateArraySize.returns(false)
|
|
282
|
+
const req = createMockRequest({ body: { txids: new Array(25).fill('a'.repeat(64)) } })
|
|
283
|
+
const res = createMockResponse()
|
|
284
|
+
|
|
285
|
+
await uut.getRawTransactionBulk(req, res)
|
|
286
|
+
|
|
287
|
+
assert.equal(res.statusValue, 400)
|
|
288
|
+
assert.deepEqual(res.jsonData, { error: 'Array too large.' })
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
it('should return 400 if empty txid encountered', async () => {
|
|
292
|
+
const req = createMockRequest({ body: { txids: ['a'.repeat(64), ''] } })
|
|
293
|
+
const res = createMockResponse()
|
|
294
|
+
|
|
295
|
+
await uut.getRawTransactionBulk(req, res)
|
|
296
|
+
|
|
297
|
+
assert.equal(res.statusValue, 400)
|
|
298
|
+
assert.deepEqual(res.jsonData, { error: 'Encountered empty TXID' })
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
it('should return 400 if txid length is not 64', async () => {
|
|
302
|
+
const req = createMockRequest({ body: { txids: ['short'] } })
|
|
303
|
+
const res = createMockResponse()
|
|
304
|
+
|
|
305
|
+
await uut.getRawTransactionBulk(req, res)
|
|
306
|
+
|
|
307
|
+
assert.equal(res.statusValue, 400)
|
|
308
|
+
assert.deepEqual(res.jsonData, { error: 'parameter 1 must be of length 64 (not 5)' })
|
|
309
|
+
})
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
describe('#sendRawTransactionSingle()', () => {
|
|
313
|
+
it('should return txid on success', async () => {
|
|
314
|
+
const req = createMockRequest({ params: { hex: '01000000' } })
|
|
315
|
+
const res = createMockResponse()
|
|
316
|
+
|
|
317
|
+
await uut.sendRawTransactionSingle(req, res)
|
|
318
|
+
|
|
319
|
+
assert.equal(res.statusValue, 200)
|
|
320
|
+
assert.equal(res.jsonData, 'txid123')
|
|
321
|
+
assert.isTrue(mockUseCases.rawtransactions.sendRawTransaction.calledOnce)
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
it('should return 400 if hex is empty', async () => {
|
|
325
|
+
const req = createMockRequest({ params: { hex: '' } })
|
|
326
|
+
const res = createMockResponse()
|
|
327
|
+
|
|
328
|
+
await uut.sendRawTransactionSingle(req, res)
|
|
329
|
+
|
|
330
|
+
assert.equal(res.statusValue, 400)
|
|
331
|
+
assert.deepEqual(res.jsonData, { error: 'Encountered empty hex' })
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
it('should return 400 if hex is not a string', async () => {
|
|
335
|
+
const req = createMockRequest({ params: { hex: 123 } })
|
|
336
|
+
const res = createMockResponse()
|
|
337
|
+
|
|
338
|
+
await uut.sendRawTransactionSingle(req, res)
|
|
339
|
+
|
|
340
|
+
assert.equal(res.statusValue, 400)
|
|
341
|
+
assert.deepEqual(res.jsonData, { error: 'hex must be a string' })
|
|
342
|
+
})
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
describe('#sendRawTransactionBulk()', () => {
|
|
346
|
+
it('should return txids on success', async () => {
|
|
347
|
+
const req = createMockRequest({ body: { hexes: ['hex1', 'hex2'] } })
|
|
348
|
+
const res = createMockResponse()
|
|
349
|
+
|
|
350
|
+
await uut.sendRawTransactionBulk(req, res)
|
|
351
|
+
|
|
352
|
+
assert.equal(res.statusValue, 200)
|
|
353
|
+
assert.deepEqual(res.jsonData, ['txid1', 'txid2'])
|
|
354
|
+
assert.isTrue(mockUseCases.rawtransactions.sendRawTransactions.calledOnce)
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
it('should return 400 if hexes is not an array', async () => {
|
|
358
|
+
const req = createMockRequest({ body: { hexes: 'not-array' } })
|
|
359
|
+
const res = createMockResponse()
|
|
360
|
+
|
|
361
|
+
await uut.sendRawTransactionBulk(req, res)
|
|
362
|
+
|
|
363
|
+
assert.equal(res.statusValue, 400)
|
|
364
|
+
assert.deepEqual(res.jsonData, { error: 'hex must be an array' })
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
it('should return 400 if array is too large', async () => {
|
|
368
|
+
mockAdapters.fullNode.validateArraySize.returns(false)
|
|
369
|
+
const req = createMockRequest({ body: { hexes: new Array(25).fill('hex') } })
|
|
370
|
+
const res = createMockResponse()
|
|
371
|
+
|
|
372
|
+
await uut.sendRawTransactionBulk(req, res)
|
|
373
|
+
|
|
374
|
+
assert.equal(res.statusValue, 400)
|
|
375
|
+
assert.deepEqual(res.jsonData, { error: 'Array too large.' })
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
it('should return 400 if empty hex encountered', async () => {
|
|
379
|
+
const req = createMockRequest({ body: { hexes: ['hex1', '', 'hex2'] } })
|
|
380
|
+
const res = createMockResponse()
|
|
381
|
+
|
|
382
|
+
await uut.sendRawTransactionBulk(req, res)
|
|
383
|
+
|
|
384
|
+
assert.equal(res.statusValue, 400)
|
|
385
|
+
assert.deepEqual(res.jsonData, { error: 'Encountered empty hex' })
|
|
386
|
+
})
|
|
387
|
+
})
|
|
388
|
+
})
|
|
@@ -6,9 +6,13 @@ import { assert } from 'chai'
|
|
|
6
6
|
import sinon from 'sinon'
|
|
7
7
|
|
|
8
8
|
import RESTControllers from '../../../src/controllers/rest-api/index.js'
|
|
9
|
-
import BlockchainRouter from '../../../src/controllers/rest-api/full-node/blockchain/
|
|
10
|
-
import ControlRouter from '../../../src/controllers/rest-api/full-node/control/
|
|
11
|
-
import DSProofRouter from '../../../src/controllers/rest-api/full-node/dsproof/
|
|
9
|
+
import BlockchainRouter from '../../../src/controllers/rest-api/full-node/blockchain/router.js'
|
|
10
|
+
import ControlRouter from '../../../src/controllers/rest-api/full-node/control/router.js'
|
|
11
|
+
import DSProofRouter from '../../../src/controllers/rest-api/full-node/dsproof/router.js'
|
|
12
|
+
import MiningRouter from '../../../src/controllers/rest-api/full-node/mining/router.js'
|
|
13
|
+
import RawTransactionsRouter from '../../../src/controllers/rest-api/full-node/rawtransactions/router.js'
|
|
14
|
+
import FulcrumRouter from '../../../src/controllers/rest-api/fulcrum/router.js'
|
|
15
|
+
import SlpRouter from '../../../src/controllers/rest-api/slp/router.js'
|
|
12
16
|
|
|
13
17
|
describe('#controllers/rest-api/index.js', () => {
|
|
14
18
|
let sandbox
|
|
@@ -51,6 +55,46 @@ describe('#controllers/rest-api/index.js', () => {
|
|
|
51
55
|
},
|
|
52
56
|
dsproof: {
|
|
53
57
|
getDSProof: () => {}
|
|
58
|
+
},
|
|
59
|
+
fulcrum: {
|
|
60
|
+
getBalance: () => {},
|
|
61
|
+
getBalances: () => {},
|
|
62
|
+
getUtxos: () => {},
|
|
63
|
+
getUtxosBulk: () => {},
|
|
64
|
+
getTransactionDetails: () => {},
|
|
65
|
+
getTransactionDetailsBulk: () => {},
|
|
66
|
+
broadcastTransaction: () => {},
|
|
67
|
+
getBlockHeaders: () => {},
|
|
68
|
+
getBlockHeadersBulk: () => {},
|
|
69
|
+
getTransactions: () => {},
|
|
70
|
+
getTransactionsBulk: () => {},
|
|
71
|
+
getMempool: () => {},
|
|
72
|
+
getMempoolBulk: () => {}
|
|
73
|
+
},
|
|
74
|
+
mining: {
|
|
75
|
+
getMiningInfo: () => {},
|
|
76
|
+
getNetworkHashPS: () => {}
|
|
77
|
+
},
|
|
78
|
+
rawtransactions: {
|
|
79
|
+
decodeRawTransaction: () => {},
|
|
80
|
+
decodeRawTransactions: () => {},
|
|
81
|
+
decodeScript: () => {},
|
|
82
|
+
decodeScripts: () => {},
|
|
83
|
+
getRawTransaction: () => {},
|
|
84
|
+
getRawTransactionWithHeight: () => {},
|
|
85
|
+
getRawTransactions: () => {},
|
|
86
|
+
sendRawTransaction: () => {},
|
|
87
|
+
sendRawTransactions: () => {}
|
|
88
|
+
},
|
|
89
|
+
slp: {
|
|
90
|
+
getStatus: () => {},
|
|
91
|
+
getAddress: () => {},
|
|
92
|
+
getTxid: () => {},
|
|
93
|
+
getTokenStats: () => {},
|
|
94
|
+
getTokenData: () => {},
|
|
95
|
+
getMutableCid: () => {},
|
|
96
|
+
decodeOpReturn: () => {},
|
|
97
|
+
getCIDData: () => {}
|
|
54
98
|
}
|
|
55
99
|
}
|
|
56
100
|
})
|
|
@@ -80,6 +124,10 @@ describe('#controllers/rest-api/index.js', () => {
|
|
|
80
124
|
const blockchainAttachStub = sandbox.stub(BlockchainRouter.prototype, 'attach')
|
|
81
125
|
const controlAttachStub = sandbox.stub(ControlRouter.prototype, 'attach')
|
|
82
126
|
const dsproofAttachStub = sandbox.stub(DSProofRouter.prototype, 'attach')
|
|
127
|
+
const fulcrumAttachStub = sandbox.stub(FulcrumRouter.prototype, 'attach')
|
|
128
|
+
const miningAttachStub = sandbox.stub(MiningRouter.prototype, 'attach')
|
|
129
|
+
const rawtransactionsAttachStub = sandbox.stub(RawTransactionsRouter.prototype, 'attach')
|
|
130
|
+
const slpAttachStub = sandbox.stub(SlpRouter.prototype, 'attach')
|
|
83
131
|
const restControllers = new RESTControllers({
|
|
84
132
|
adapters: mockAdapters,
|
|
85
133
|
useCases: mockUseCases
|
|
@@ -94,6 +142,14 @@ describe('#controllers/rest-api/index.js', () => {
|
|
|
94
142
|
assert.equal(controlAttachStub.getCall(0).args[0], app)
|
|
95
143
|
assert.isTrue(dsproofAttachStub.calledOnce)
|
|
96
144
|
assert.equal(dsproofAttachStub.getCall(0).args[0], app)
|
|
145
|
+
assert.isTrue(fulcrumAttachStub.calledOnce)
|
|
146
|
+
assert.equal(fulcrumAttachStub.getCall(0).args[0], app)
|
|
147
|
+
assert.isTrue(miningAttachStub.calledOnce)
|
|
148
|
+
assert.equal(miningAttachStub.getCall(0).args[0], app)
|
|
149
|
+
assert.isTrue(rawtransactionsAttachStub.calledOnce)
|
|
150
|
+
assert.equal(rawtransactionsAttachStub.getCall(0).args[0], app)
|
|
151
|
+
assert.isTrue(slpAttachStub.calledOnce)
|
|
152
|
+
assert.equal(slpAttachStub.getCall(0).args[0], app)
|
|
97
153
|
})
|
|
98
154
|
})
|
|
99
155
|
})
|