const assert = require('node:assert/strict'); const http = require('node:http'); const test = require('node:test'); const { closeDbPool, getDb } = require('../src/config/db'); const { calculateSellPrice, listActiveServices, listAdminServices, syncServicesFromProvider, updateService } = require('../src/services/services.service'); const providerIds = []; function startProviderMock() { const server = http.createServer(async (req, res) => { const chunks = []; for await (const chunk of req) { chunks.push(chunk); } const body = new URLSearchParams(Buffer.concat(chunks).toString()); const action = body.get('action'); res.setHeader('content-type', 'application/json'); if (action === 'services') { res.end(JSON.stringify([ { service: 'svc-test-1', name: 'Instagram Followers', category: 'Instagram', rate: '4.0000', min: 100, max: 10000 }, { service: 'svc-test-2', name: 'TikTok Views', category: 'TikTok', rate: '1.2000', min: 1000, max: 500000 } ])); return; } res.statusCode = 400; res.end(JSON.stringify({ error: 'unknown action' })); }); return new Promise((resolve) => { server.listen(0, '127.0.0.1', () => { const address = server.address(); resolve({ url: `http://127.0.0.1:${address.port}`, close: () => new Promise((done) => server.close(done)) }); }); }); } test.after(async () => { if (providerIds.length > 0) { await getDb()('services').whereIn('provider_service_id', providerIds).del(); } await closeDbPool(); }); test('calculateSellPrice applies markup and keeps four decimals', () => { assert.equal(calculateSellPrice('4.0000', '25'), '5.0000'); assert.equal(calculateSellPrice('1.2000', '12.5'), '1.3500'); }); test('syncServicesFromProvider stores services and public listing hides provider price', async () => { const mock = await startProviderMock(); const oldUrl = process.env.PROVIDER_API_URL; const oldKey = process.env.PROVIDER_API_KEY; process.env.PROVIDER_API_URL = mock.url; process.env.PROVIDER_API_KEY = 'mock-key'; try { const result = await syncServicesFromProvider('25'); assert.equal(result.synced, 2); providerIds.push('svc-test-1', 'svc-test-2'); const adminServices = await listAdminServices(); const firstAdmin = adminServices.find((service) => service.provider_service_id === 'svc-test-1'); assert.equal(firstAdmin.provider_price, '4.0000'); assert.equal(firstAdmin.markup_percent, '25.0000'); assert.equal(firstAdmin.sell_price, '5.0000'); const publicServices = await listActiveServices(); const firstPublic = publicServices.find((service) => service.provider_service_id === 'svc-test-1'); assert.equal(firstPublic.sell_price, '5.0000'); assert.equal(Object.hasOwn(firstPublic, 'provider_price'), false); assert.equal(Object.hasOwn(firstPublic, 'markup_percent'), false); } finally { process.env.PROVIDER_API_URL = oldUrl; process.env.PROVIDER_API_KEY = oldKey; await mock.close(); } }); test('updateService can adjust markup, sell price, and activation', async () => { let service = await getDb()('services').where({ provider_service_id: 'svc-test-2' }).first(); if (!service) { const [id] = await getDb()('services').insert({ provider_service_id: 'svc-test-2', name: 'TikTok Views', category: 'TikTok', provider_price: '1.2000', markup_percent: '25.0000', sell_price: '1.5000', min: 1000, max: 500000, is_active: true }); providerIds.push('svc-test-2'); service = await getDb()('services').where({ id }).first(); } const updated = await updateService( service.id, { markup_percent: '50', is_active: false } ); assert.equal(updated.sell_price, '1.8000'); assert.equal(Boolean(updated.is_active), false); const publicServices = await listActiveServices(); assert.equal(publicServices.some((service) => service.provider_service_id === 'svc-test-2'), false); });