const assert = require('node:assert/strict'); const http = require('node:http'); const test = require('node:test'); const { createApp } = require('../src/app'); const { closeDbPool, getDb } = require('../src/config/db'); const createdUserIds = []; const createdServiceIds = []; let providerMock; function unique(prefix) { return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2)}`; } function startFailingProviderMock() { const server = http.createServer(async (_req, res) => { res.setHeader('content-type', 'application/json'); res.end(JSON.stringify({ error: 'forced provider failure' })); }); return new Promise((resolve) => { server.listen(0, '127.0.0.1', () => { resolve({ url: `http://127.0.0.1:${server.address().port}`, close: () => new Promise((done) => server.close(done)) }); }); }); } function listen(app) { return new Promise((resolve) => { const server = app.listen(0, '127.0.0.1', () => { resolve({ baseUrl: `http://127.0.0.1:${server.address().port}`, close: () => new Promise((done) => server.close(done)) }); }); }); } async function request(baseUrl, path, options = {}) { const response = await fetch(`${baseUrl}${path}`, { ...options, headers: { 'content-type': 'application/json', ...(options.headers || {}) } }); const body = await response.json().catch(() => ({})); return { response, body }; } async function register(baseUrl, prefix) { const account = { username: unique(prefix), email: `${unique(prefix)}@example.com`, password: 'StrongPass123' }; const result = await request(baseUrl, '/auth/register', { method: 'POST', body: JSON.stringify(account) }); assert.equal(result.response.status, 201); createdUserIds.push(result.body.user.id); return { ...account, id: result.body.user.id }; } async function login(baseUrl, account) { const result = await request(baseUrl, '/auth/login', { method: 'POST', body: JSON.stringify({ email: account.email, password: account.password }) }); assert.equal(result.response.status, 200); return result.body.accessToken; } test.before(async () => { providerMock = await startFailingProviderMock(); process.env.PROVIDER_API_URL = providerMock.url; process.env.PROVIDER_API_KEY = 'mock-key'; }); test.after(async () => { const db = getDb(); if (createdUserIds.length > 0) { await db('orders').whereIn('user_id', createdUserIds).del(); await db('deposits').whereIn('user_id', createdUserIds).orWhereIn('reviewed_by', createdUserIds).del(); await db('transactions').whereIn('user_id', createdUserIds).del(); await db('refresh_tokens').whereIn('user_id', createdUserIds).del(); await db('password_reset_tokens').whereIn('user_id', createdUserIds).del(); await db('users').whereIn('id', createdUserIds).del(); } if (createdServiceIds.length > 0) { await db('services').whereIn('id', createdServiceIds).del(); } await closeDbPool(); await providerMock.close(); }); test('full flow refunds wallet when provider order fails', async () => { process.env.JWT_SECRET = process.env.JWT_SECRET || 'test_secret'; const api = await listen(createApp()); try { const db = getDb(); const user = await register(api.baseUrl, 'e2e_user'); const admin = await register(api.baseUrl, 'e2e_admin'); await db('users').where({ id: admin.id }).update({ role: 'admin' }); const userToken = await login(api.baseUrl, user); const adminToken = await login(api.baseUrl, admin); const userAuth = { authorization: `Bearer ${userToken}` }; const adminAuth = { authorization: `Bearer ${adminToken}` }; const deposit = await request(api.baseUrl, '/deposits', { method: 'POST', headers: userAuth, body: JSON.stringify({ amount: '10.0000', method: 'paypal', tx_ref: unique('e2e_tx') }) }); assert.equal(deposit.response.status, 201); const approved = await request(api.baseUrl, `/admin/deposits/${deposit.body.deposit.id}`, { method: 'PATCH', headers: adminAuth, body: JSON.stringify({ action: 'approve' }) }); assert.equal(approved.response.status, 200); const [serviceId] = await db('services').insert({ provider_service_id: unique('e2e_provider_service'), name: 'E2E Failure Service', category: 'E2E', provider_price: '2.0000', markup_percent: '25.0000', sell_price: '2.5000', min: 100, max: 10000, is_active: true }); createdServiceIds.push(serviceId); const failedOrder = await request(api.baseUrl, '/orders', { method: 'POST', headers: userAuth, body: JSON.stringify({ service_id: serviceId, link: 'https://example.com/e2e-failure', quantity: 1000 }) }); assert.equal(failedOrder.response.status, 502); const me = await request(api.baseUrl, '/me', { headers: userAuth }); const orders = await request(api.baseUrl, '/orders', { headers: userAuth }); const transactions = await request(api.baseUrl, '/transactions', { headers: userAuth }); assert.equal(me.body.user.balance, '10.0000'); assert.equal(orders.body.orders.some((order) => order.status === 'failed' && order.charge === '2.5000'), true); assert.equal(transactions.body.transactions.some((transaction) => transaction.type === 'refund' && transaction.amount === '2.5000'), true); } finally { await api.close(); } });