const assert = require('node:assert/strict'); const http = require('node:http'); const test = require('node:test'); const jwt = require('jsonwebtoken'); const app = require('../app'); const db = require('../src/config/db'); const agheeraPushClient = require('../src/services/agheeraPushClient'); const TEST_JWT_SECRET = 'test-jwt-secret'; let originalQuery; let originalJwtSecret; let originalAgheeraApiKey; const createToken = (payload = {}) => jwt.sign( { id: 1, dni: '58045340X', id_proveedor: 675, ...payload }, TEST_JWT_SECRET, { expiresIn: '1h' } ); const withServer = async (callback) => new Promise((resolve, reject) => { const server = app.listen(0, '127.0.0.1'); server.on('error', reject); server.on('listening', async () => { try { const result = await callback(server); server.close((closeError) => { if (closeError) { reject(closeError); return; } resolve(result); }); } catch (error) { server.close(() => reject(error)); } }); }); const postJson = async ({ port, path, authorization, body }) => new Promise((resolve, reject) => { const rawBody = JSON.stringify(body); const req = http.request( { hostname: '127.0.0.1', port, method: 'POST', path, headers: { authorization, 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(rawBody) } }, (res) => { let responseBody = ''; res.on('data', (chunk) => { responseBody += chunk; }); res.on('end', () => { resolve({ statusCode: res.statusCode, body: responseBody ? JSON.parse(responseBody) : null }); }); } ); req.on('error', reject); req.write(rawBody); req.end(); }); test.before(() => { originalQuery = db.query; originalJwtSecret = process.env.JWT_SECRET; originalAgheeraApiKey = process.env.AGHEERA_API_KEY; }); test.after(() => { db.query = originalQuery; process.env.JWT_SECRET = originalJwtSecret; process.env.AGHEERA_API_KEY = originalAgheeraApiKey; agheeraPushClient.__resetHttpClientForTests(); }); test.afterEach(() => { db.query = originalQuery; agheeraPushClient.__resetHttpClientForTests(); }); test('POST /api/locations envia posicion a Agheera para cliente 532', async () => { process.env.JWT_SECRET = TEST_JWT_SECRET; process.env.AGHEERA_API_KEY = 'test-api-key'; const agheeraCalls = []; agheeraPushClient.__setHttpClientForTests(async (url, options) => { agheeraCalls.push({ url, options }); return { ok: true, status: 200, text: async () => 'Messages received.' }; }); let step = 0; db.query = async (sql, params) => { step += 1; if (step === 1) { assert.match(sql, /INSERT INTO c_trazabilidad_transportista/); assert.equal(params[0].length, 1); assert.deepEqual(params[0][0].slice(0, 3), ['40.416775', '-3.70379', '58045340X']); assert.equal(params[0][0][4], 248230); return [{ affectedRows: 1 }]; } if (step === 2) { assert.match(sql, /FROM c_viajes/); assert.deepEqual(params, [248230]); return [[{ id_cliente: 532 }]]; } assert.match(sql, /FROM c_viajes_proveedor/); assert.deepEqual(params, [248230, '58045340X']); return [[{ matricula: '6599LCN' }]]; }; const response = await withServer(async (server) => postJson({ port: server.address().port, path: '/api/locations', authorization: `Bearer ${createToken()}`, body: { latitude: 40.416775, longitude: -3.70379, id_viaje: 248230, timestamp: '2026-06-01T13:20:00Z' } }) ); assert.equal(response.statusCode, 200); assert.deepEqual(response.body, { success: true, count: 1, message: 'Locations saved', agheera_push: { trip_id: 248230, attempted: true, success: true, http_status: 200, error: null } }); assert.equal(agheeraCalls.length, 1); const call = agheeraCalls[0]; assert.equal(call.url, 'https://push-dhl.agheera.com/Telematics/positions'); assert.equal(call.options.headers.apiKey, 'test-api-key'); const payload = JSON.parse(call.options.body); assert.deepEqual(payload, { Vehicles: [ { latitude: 40.416775, longitude: -3.70379, vehicleId: '6599LCN', licensePlate: '6599LCN', measurementTime: '2026-06-01T13:20:00Z' } ] }); }); test('POST /api/locations no envia a Agheera para clientes distintos de 532', async () => { process.env.JWT_SECRET = TEST_JWT_SECRET; process.env.AGHEERA_API_KEY = 'test-api-key'; const agheeraCalls = []; agheeraPushClient.__setHttpClientForTests(async (url, options) => { agheeraCalls.push({ url, options }); return { ok: true, status: 200, text: async () => 'Messages received.' }; }); let step = 0; db.query = async (sql, params) => { step += 1; if (step === 1) { assert.match(sql, /INSERT INTO c_trazabilidad_transportista/); return [{ affectedRows: 1 }]; } assert.match(sql, /FROM c_viajes/); assert.deepEqual(params, [248230]); return [[{ id_cliente: 700 }]]; }; const response = await withServer(async (server) => postJson({ port: server.address().port, path: '/api/locations', authorization: `Bearer ${createToken()}`, body: { latitude: 40.416775, longitude: -3.70379, id_viaje: 248230, timestamp: '2026-06-01T13:20:00Z' } }) ); assert.equal(response.statusCode, 200); assert.deepEqual(response.body, { success: true, count: 1, message: 'Locations saved' }); assert.equal(agheeraCalls.length, 0); }); test('POST /api/locations devuelve error de Agheera sin romper guardado local', async () => { process.env.JWT_SECRET = TEST_JWT_SECRET; process.env.AGHEERA_API_KEY = 'test-api-key'; agheeraPushClient.__setHttpClientForTests(async () => ({ ok: false, status: 401, text: async () => 'Unauthorized' })); let step = 0; db.query = async (sql, params) => { step += 1; if (step === 1) { assert.match(sql, /INSERT INTO c_trazabilidad_transportista/); return [{ affectedRows: 1 }]; } if (step === 2) { assert.match(sql, /FROM c_viajes/); assert.deepEqual(params, [248230]); return [[{ id_cliente: 532 }]]; } assert.match(sql, /FROM c_viajes_proveedor/); assert.deepEqual(params, [248230, '58045340X']); return [[{ matricula: '6599LCN' }]]; }; const response = await withServer(async (server) => postJson({ port: server.address().port, path: '/api/locations', authorization: `Bearer ${createToken()}`, body: { latitude: 40.416775, longitude: -3.70379, id_viaje: 248230, timestamp: '2026-06-01T13:20:00Z' } }) ); assert.equal(response.statusCode, 200); assert.deepEqual(response.body, { success: true, count: 1, message: 'Locations saved', agheera_push: { trip_id: 248230, attempted: true, success: false, http_status: 401, error: 'Agheera push failed' } }); });