PHP WebShell
Текущая директория: /opt/BitGoJS/modules/express/test/unit/lightning
Просмотр файла: lightningInvoiceRoutes.test.ts
import * as sinon from 'sinon';
import * as should from 'should';
import * as express from 'express';
import { handlePayLightningInvoice, handleCreateLightningInvoice } from '../../../src/lightning/lightningInvoiceRoutes';
import { Invoice, PayInvoiceResponse } from '@bitgo/abstract-lightning';
import { BitGo } from 'bitgo';
import * as assert from 'node:assert';
describe('Lightning Invoice Routes', () => {
let bitgo;
const coin = 'tlnbtc';
const mockRequestObject = (params: { body?: any; params?: any; query?: any; bitgo?: any }) => {
const req: Partial<express.Request> = {};
req.body = params.body || {};
req.params = params.params || {};
req.query = params.query || {};
req.bitgo = params.bitgo;
return req as express.Request;
};
afterEach(() => {
sinon.restore();
});
describe('Create Lightning Invoice', () => {
it('should successfully create a lightning invoice', async () => {
const inputParams = {
valueMsat: '10000',
memo: 'test invoice',
expiry: 3600,
};
const expectedResponse = {
valueMsat: 10000n,
memo: 'test invoice',
paymentHash: 'abc123',
invoice: 'lntb100u1p3h2jk3pp5yndyvx4zmv...',
walletId: 'testWalletId',
status: 'open' as const,
expiresAt: new Date('2025-02-21T10:00:00.000Z'),
};
const createInvoiceSpy = sinon.stub().resolves(expectedResponse);
const mockLightningWallet = {
createInvoice: createInvoiceSpy,
};
// Mock the module import
const proxyquire = require('proxyquire');
const lightningRoutes = proxyquire('../../../src/lightning/lightningInvoiceRoutes', {
'@bitgo/abstract-lightning': {
getLightningWallet: () => mockLightningWallet,
},
});
const walletStub = {};
const coinStub = {
wallets: () => ({ get: sinon.stub().resolves(walletStub) }),
};
const stubBitgo = sinon.createStubInstance(BitGo as any, { coin: coinStub });
const req = mockRequestObject({
params: { id: 'testWalletId', coin },
body: inputParams,
bitgo: stubBitgo,
});
const result = await lightningRoutes.handleCreateLightningInvoice(req);
should(result).deepEqual(Invoice.encode(expectedResponse));
const decodedResult = Invoice.decode(result);
assert('right' in decodedResult);
should(decodedResult.right).deepEqual(expectedResponse);
should(createInvoiceSpy).be.calledOnce();
const [firstArg] = createInvoiceSpy.getCall(0).args;
should(firstArg).have.property('valueMsat', BigInt(10000));
should(firstArg).have.property('memo', 'test invoice');
should(firstArg).have.property('expiry', 3600);
});
it('should fail when valueMsat is missing from request', async () => {
const inputParams = {
memo: 'test invoice',
expiry: 3600,
};
const req = mockRequestObject({
params: { id: 'testWalletId', coin },
body: inputParams,
});
req.bitgo = bitgo;
await should(handleCreateLightningInvoice(req)).be.rejectedWith(
/^Invalid request body to create lightning invoice/
);
});
});
describe('Pay Lightning Invoice', () => {
it('should successfully pay a lightning invoice', async () => {
const inputParams = {
invoice: 'lntb100u1p3h2jk3pp5yndyvx4zmv...',
amountMsat: '10000',
passphrase: 'wallet-password-12345',
randomParamThatWontBreakDecoding: 'randomValue',
};
const expectedResponse: PayInvoiceResponse = {
paymentStatus: {
paymentHash: 'xyz789',
status: 'settled',
},
txRequestState: 'delivered',
txRequestId: '123',
};
const payInvoiceStub = sinon.stub().resolves(expectedResponse);
const mockLightningWallet = {
payInvoice: payInvoiceStub,
};
// Mock the module import
const proxyquire = require('proxyquire');
const lightningRoutes = proxyquire('../../../src/lightning/lightningInvoiceRoutes', {
'@bitgo/abstract-lightning': {
getLightningWallet: () => mockLightningWallet,
},
});
const walletStub = {};
const coinStub = {
wallets: () => ({ get: sinon.stub().resolves(walletStub) }),
};
const stubBitgo = sinon.createStubInstance(BitGo as any, { coin: coinStub });
const req = mockRequestObject({
params: { id: 'testWalletId', coin },
body: inputParams,
bitgo: stubBitgo,
});
const result = await lightningRoutes.handlePayLightningInvoice(req);
should(result).deepEqual(expectedResponse);
should(payInvoiceStub).be.calledOnce();
const [firstArg] = payInvoiceStub.getCall(0).args;
// we decode the amountMsat string to bigint, it should be in bigint format when passed to payInvoice
should(firstArg).have.property('amountMsat', BigInt(10000));
should(firstArg).have.property('invoice', inputParams.invoice);
should(firstArg).have.property('passphrase', 'wallet-password-12345');
});
it('should throw an error if the passphrase is missing in the request params', async () => {
const inputParams = {
invoice: 'lntb100u1p3h2jk3pp5yndyvx4zmv...',
amountMsat: '10000',
};
const req = mockRequestObject({
params: { id: 'testWalletId', coin },
body: inputParams,
});
req.bitgo = bitgo;
await should(handlePayLightningInvoice(req)).be.rejectedWith('Invalid request body to pay lightning invoice');
});
it('should throw an error if the invoice is missing in the request params', async () => {
const inputParams = {
amountMsat: '10000',
passphrase: 'wallet-password-12345',
};
const req = mockRequestObject({
params: { id: 'testWalletId', coin },
body: inputParams,
});
req.bitgo = bitgo;
await should(handlePayLightningInvoice(req)).be.rejectedWith(/^Invalid request body to pay lightning invoice/);
});
});
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!