
All checks were successful
build-and-push-ext / build_push (push) Successful in 35s
- Dockerfile optimisé: seulement docker-cli pour bitcoin-cli - README.md complet avec tous les endpoints et configuration - CHANGELOG.md mis à jour avec v1.1.1 - Tests unitaires pour les routes funds - Tests d'intégration pour le signer - Configuration Jest avec coverage - Scripts de test dans package.json - Fichier .env.test pour les tests
137 lines
4.6 KiB
TypeScript
137 lines
4.6 KiB
TypeScript
import request from 'supertest';
|
|
import express from 'express';
|
|
import fundsRoutes from '../../src/routes/funds.routes';
|
|
import { exec } from 'child_process';
|
|
|
|
// Mock de child_process
|
|
jest.mock('child_process');
|
|
const mockExec = exec as jest.MockedFunction<typeof exec>;
|
|
|
|
describe('Funds Routes', () => {
|
|
let app: express.Application;
|
|
|
|
beforeEach(() => {
|
|
app = express();
|
|
app.use(express.json());
|
|
app.use('/api/v1/funds', fundsRoutes);
|
|
|
|
// Reset des mocks
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('POST /api/v1/funds/transfer', () => {
|
|
it('devrait transférer des fonds avec succès', async () => {
|
|
// Mock des commandes bitcoin-cli
|
|
mockExec.mockImplementation((command, callback) => {
|
|
if (command.includes('getblockchaininfo')) {
|
|
callback(null, { stdout: '{"chain":"signet","blocks":1000}', stderr: '' });
|
|
} else if (command.includes('loadwallet')) {
|
|
callback(null, { stdout: '{"name":"default","warning":""}', stderr: '' });
|
|
} else if (command.includes('getbalance')) {
|
|
callback(null, { stdout: '1.5', stderr: '' });
|
|
} else if (command.includes('getnewaddress')) {
|
|
callback(null, { stdout: 'bc1qtest123', stderr: '' });
|
|
} else if (command.includes('sendtoaddress')) {
|
|
callback(null, { stdout: 'txid123456789', stderr: '' });
|
|
} else if (command.includes('generatetoaddress')) {
|
|
callback(null, { stdout: '["blockhash123"]', stderr: '' });
|
|
} else if (command.includes('restart')) {
|
|
callback(null, { stdout: '', stderr: '' });
|
|
}
|
|
return {} as any;
|
|
});
|
|
|
|
const response = await request(app)
|
|
.post('/api/v1/funds/transfer')
|
|
.send({
|
|
amount: 0.01,
|
|
source: 'mining_mnemonic',
|
|
target: 'default'
|
|
});
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.success).toBe(true);
|
|
expect(response.body.message).toContain('Transfert de 0.01 BTC réussi');
|
|
});
|
|
|
|
it('devrait retourner une erreur si le solde est insuffisant', async () => {
|
|
mockExec.mockImplementation((command, callback) => {
|
|
if (command.includes('getbalance')) {
|
|
callback(null, { stdout: '0.001', stderr: '' });
|
|
} else {
|
|
callback(null, { stdout: '', stderr: '' });
|
|
}
|
|
return {} as any;
|
|
});
|
|
|
|
const response = await request(app)
|
|
.post('/api/v1/funds/transfer')
|
|
.send({
|
|
amount: 0.01,
|
|
source: 'mining_mnemonic',
|
|
target: 'default'
|
|
});
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(response.body.success).toBe(false);
|
|
expect(response.body.error).toContain('Solde insuffisant');
|
|
});
|
|
|
|
it('devrait gérer les erreurs de commande bitcoin-cli', async () => {
|
|
mockExec.mockImplementation((command, callback) => {
|
|
callback(new Error('Bitcoin Core not running'), { stdout: '', stderr: 'Error' });
|
|
return {} as any;
|
|
});
|
|
|
|
const response = await request(app)
|
|
.post('/api/v1/funds/transfer')
|
|
.send({
|
|
amount: 0.01,
|
|
source: 'mining_mnemonic',
|
|
target: 'default'
|
|
});
|
|
|
|
expect(response.status).toBe(500);
|
|
expect(response.body.success).toBe(false);
|
|
expect(response.body.error).toContain('Erreur lors du transfert');
|
|
});
|
|
});
|
|
|
|
describe('GET /api/v1/funds/check', () => {
|
|
it('devrait vérifier les fonds avec succès', async () => {
|
|
mockExec.mockImplementation((command, callback) => {
|
|
if (command.includes('cat /home/bitcoin/.4nk/default')) {
|
|
callback(null, { stdout: '{"outputs":[{"value":1000000}]}', stderr: '' });
|
|
} else if (command.includes('getbalance')) {
|
|
callback(null, { stdout: '0.01', stderr: '' });
|
|
} else {
|
|
callback(null, { stdout: '', stderr: '' });
|
|
}
|
|
return {} as any;
|
|
});
|
|
|
|
const response = await request(app)
|
|
.get('/api/v1/funds/check');
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.success).toBe(true);
|
|
expect(response.body.relay.outputsCount).toBe(1);
|
|
expect(response.body.relay.balance).toBe(0.01);
|
|
});
|
|
|
|
it('devrait gérer les erreurs de vérification', async () => {
|
|
mockExec.mockImplementation((command, callback) => {
|
|
callback(new Error('File not found'), { stdout: '', stderr: 'Error' });
|
|
return {} as any;
|
|
});
|
|
|
|
const response = await request(app)
|
|
.get('/api/v1/funds/check');
|
|
|
|
expect(response.status).toBe(500);
|
|
expect(response.body.success).toBe(false);
|
|
expect(response.body.error).toContain('Erreur lors de la vérification');
|
|
});
|
|
});
|
|
});
|