Skip to content

Commit 398eb3d

Browse files
authored
test(express): added supertest for pendingApproval
2 parents 3b078e2 + 02bee65 commit 398eb3d

File tree

1 file changed

+265
-0
lines changed

1 file changed

+265
-0
lines changed

modules/express/test/unit/typedRoutes/pendingApproval.ts

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ import {
66
PutPendingApproval,
77
} from '../../../src/typedRoutes/api/v1/pendingApproval';
88
import { assertDecode } from './common';
9+
import 'should';
10+
import 'should-http';
11+
import 'should-sinon';
12+
import * as sinon from 'sinon';
13+
import { BitGo } from 'bitgo';
14+
import { setupAgent } from '../../lib/testutil';
915
/**
1016
* Helper function to test io-ts codec decoding
1117
*/
@@ -204,4 +210,263 @@ describe('PendingApproval codec tests', function () {
204210
assert.ok(PutPendingApproval.response[400]);
205211
});
206212
});
213+
214+
describe('Supertest Integration Tests', function () {
215+
const agent = setupAgent();
216+
217+
const mockApprovedResponse = {
218+
id: 'approval123',
219+
state: 'approved',
220+
wallet: 'wallet123',
221+
enterprise: 'enterprise123',
222+
};
223+
224+
const mockRejectedResponse = {
225+
id: 'approval123',
226+
state: 'rejected',
227+
wallet: 'wallet123',
228+
enterprise: 'enterprise123',
229+
};
230+
231+
afterEach(function () {
232+
sinon.restore();
233+
});
234+
235+
it('should successfully approve pending approval', async function () {
236+
const approvalId = '123456789abcdef';
237+
const requestBody = {
238+
state: 'approved',
239+
walletPassphrase: 'mySecurePassword',
240+
};
241+
242+
const mockPendingApprovalObject = {
243+
approve: sinon.stub().resolves(mockApprovedResponse),
244+
reject: sinon.stub().resolves(mockRejectedResponse),
245+
};
246+
247+
sinon.stub(BitGo.prototype, 'pendingApprovals').returns({
248+
get: sinon.stub().resolves(mockPendingApprovalObject),
249+
} as any);
250+
251+
const result = await agent
252+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
253+
.set('Authorization', 'Bearer test_access_token_12345')
254+
.set('Content-Type', 'application/json')
255+
.send(requestBody);
256+
257+
assert.strictEqual(result.status, 200);
258+
result.body.should.have.property('id');
259+
result.body.should.have.property('state');
260+
assert.strictEqual(result.body.id, mockApprovedResponse.id);
261+
assert.strictEqual(result.body.state, 'approved');
262+
assert.strictEqual(result.body.wallet, mockApprovedResponse.wallet);
263+
assert.strictEqual(result.body.enterprise, mockApprovedResponse.enterprise);
264+
});
265+
266+
it('should successfully reject pending approval', async function () {
267+
const approvalId = '123456789abcdef';
268+
const requestBody = {
269+
state: 'rejected',
270+
walletPassphrase: 'mySecurePassword',
271+
};
272+
273+
const mockPendingApprovalObject = {
274+
approve: sinon.stub().resolves(mockApprovedResponse),
275+
reject: sinon.stub().resolves(mockRejectedResponse),
276+
};
277+
278+
sinon.stub(BitGo.prototype, 'pendingApprovals').returns({
279+
get: sinon.stub().resolves(mockPendingApprovalObject),
280+
} as any);
281+
282+
const result = await agent
283+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
284+
.set('Authorization', 'Bearer test_access_token_12345')
285+
.set('Content-Type', 'application/json')
286+
.send(requestBody);
287+
288+
assert.strictEqual(result.status, 200);
289+
result.body.should.have.property('id');
290+
result.body.should.have.property('state');
291+
assert.strictEqual(result.body.id, mockRejectedResponse.id);
292+
assert.strictEqual(result.body.state, 'rejected');
293+
assert.strictEqual(result.body.wallet, mockRejectedResponse.wallet);
294+
assert.strictEqual(result.body.enterprise, mockRejectedResponse.enterprise);
295+
});
296+
297+
it('should successfully approve with otp', async function () {
298+
const approvalId = '123456789abcdef';
299+
const requestBody = {
300+
state: 'approved',
301+
walletPassphrase: 'mySecurePassword',
302+
otp: '123456',
303+
};
304+
305+
const mockPendingApprovalObject = {
306+
approve: sinon.stub().resolves(mockApprovedResponse),
307+
reject: sinon.stub().resolves(mockRejectedResponse),
308+
};
309+
310+
sinon.stub(BitGo.prototype, 'pendingApprovals').returns({
311+
get: sinon.stub().resolves(mockPendingApprovalObject),
312+
} as any);
313+
314+
const result = await agent
315+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
316+
.set('Authorization', 'Bearer test_access_token_12345')
317+
.set('Content-Type', 'application/json')
318+
.send(requestBody);
319+
320+
assert.strictEqual(result.status, 200);
321+
assert.strictEqual(result.body.id, mockApprovedResponse.id);
322+
assert.strictEqual(result.body.state, 'approved');
323+
});
324+
325+
it('should successfully approve with xprv', async function () {
326+
const approvalId = '123456789abcdef';
327+
const requestBody = {
328+
state: 'approved',
329+
xprv: 'xprvString',
330+
};
331+
332+
const mockPendingApprovalObject = {
333+
approve: sinon.stub().resolves(mockApprovedResponse),
334+
reject: sinon.stub().resolves(mockRejectedResponse),
335+
};
336+
337+
sinon.stub(BitGo.prototype, 'pendingApprovals').returns({
338+
get: sinon.stub().resolves(mockPendingApprovalObject),
339+
} as any);
340+
341+
const result = await agent
342+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
343+
.set('Authorization', 'Bearer test_access_token_12345')
344+
.set('Content-Type', 'application/json')
345+
.send(requestBody);
346+
347+
assert.strictEqual(result.status, 200);
348+
assert.strictEqual(result.body.id, mockApprovedResponse.id);
349+
assert.strictEqual(result.body.state, 'approved');
350+
});
351+
352+
it('should successfully preview pending transactions', async function () {
353+
const approvalId = '123456789abcdef';
354+
const requestBody = {
355+
previewPendingTxs: true,
356+
};
357+
358+
const mockPreviewResponse = {
359+
id: 'approval123',
360+
txHex: '0x123456789',
361+
pendingTransactions: [],
362+
};
363+
364+
const mockPendingApprovalObject = {
365+
approve: sinon.stub().resolves(mockPreviewResponse),
366+
reject: sinon.stub().resolves(mockPreviewResponse),
367+
};
368+
369+
sinon.stub(BitGo.prototype, 'pendingApprovals').returns({
370+
get: sinon.stub().resolves(mockPendingApprovalObject),
371+
} as any);
372+
373+
const result = await agent
374+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
375+
.set('Authorization', 'Bearer test_access_token_12345')
376+
.set('Content-Type', 'application/json')
377+
.send(requestBody);
378+
379+
assert.strictEqual(result.status, 200);
380+
assert.strictEqual(result.body.id, mockPreviewResponse.id);
381+
assert.strictEqual(result.body.txHex, mockPreviewResponse.txHex);
382+
result.body.should.have.property('pendingTransactions');
383+
});
384+
385+
it('should successfully reject with empty body (defaults to reject)', async function () {
386+
const approvalId = '123456789abcdef';
387+
const requestBody = {};
388+
389+
const mockPendingApprovalObject = {
390+
approve: sinon.stub().resolves(mockApprovedResponse),
391+
reject: sinon.stub().resolves(mockRejectedResponse),
392+
};
393+
394+
sinon.stub(BitGo.prototype, 'pendingApprovals').returns({
395+
get: sinon.stub().resolves(mockPendingApprovalObject),
396+
} as any);
397+
398+
const result = await agent
399+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
400+
.set('Authorization', 'Bearer test_access_token_12345')
401+
.set('Content-Type', 'application/json')
402+
.send(requestBody);
403+
404+
assert.strictEqual(result.status, 200);
405+
assert.strictEqual(result.body.id, mockRejectedResponse.id);
406+
assert.strictEqual(result.body.state, 'rejected');
407+
});
408+
});
409+
410+
describe('Error Handling Tests', function () {
411+
const agent = setupAgent();
412+
413+
afterEach(function () {
414+
sinon.restore();
415+
});
416+
417+
it('should handle SDK method failure', async function () {
418+
const approvalId = '123456789abcdef';
419+
const requestBody = {
420+
walletPassphrase: 'mySecurePassword',
421+
};
422+
423+
const mockPendingApprovalObject = {
424+
approve: sinon.stub().rejects(new Error('Failed to update pending approval')),
425+
reject: sinon.stub().rejects(new Error('Failed to update pending approval')),
426+
};
427+
428+
sinon.stub(BitGo.prototype, 'pendingApprovals').returns({
429+
get: sinon.stub().resolves(mockPendingApprovalObject),
430+
} as any);
431+
432+
const result = await agent
433+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
434+
.set('Authorization', 'Bearer test_access_token_12345')
435+
.set('Content-Type', 'application/json')
436+
.send(requestBody);
437+
438+
assert.strictEqual(result.status, 500);
439+
result.body.should.have.property('error');
440+
});
441+
442+
it('should handle invalid type in request field', async function () {
443+
const approvalId = '123456789abcdef';
444+
const requestBody = {
445+
walletPassphrase: 12345, // number instead of string
446+
};
447+
448+
const result = await agent
449+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
450+
.set('Authorization', 'Bearer test_access_token_12345')
451+
.set('Content-Type', 'application/json')
452+
.send(requestBody);
453+
454+
assert.ok(result.status >= 400);
455+
});
456+
457+
it('should handle invalid previewPendingTxs type', async function () {
458+
const approvalId = '123456789abcdef';
459+
const requestBody = {
460+
previewPendingTxs: 'true', // string instead of boolean
461+
};
462+
463+
const result = await agent
464+
.put(`/api/v1/pendingapprovals/${approvalId}/express`)
465+
.set('Authorization', 'Bearer test_access_token_12345')
466+
.set('Content-Type', 'application/json')
467+
.send(requestBody);
468+
469+
assert.ok(result.status >= 400);
470+
});
471+
});
207472
});

0 commit comments

Comments
 (0)