Files
SS/tests/services.test.js

143 lines
4.1 KiB
JavaScript

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);
});