Files
FlowPilot/tests/sms-bower-provider.test.js
T
2026-05-30 22:06:35 +08:00

132 lines
5.2 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const source = fs.readFileSync('phone-sms/providers/sms-bower.js', 'utf8');
const api = new Function('self', `${source}; return self.PhoneSmsBowerProvider;`)({});
function createTextResponse(payload, ok = true, status = ok ? 200 : 400, statusText = ok ? 'OK' : 'Bad Request') {
return {
ok,
status,
statusText,
text: async () => (typeof payload === 'string' ? payload : JSON.stringify(payload)),
};
}
test('SMS Bower provider defaults to Indonesia when no country is configured', async () => {
const requests = [];
const provider = api.createProvider({
fetchImpl: async (url, options = {}) => {
const parsed = new URL(url);
requests.push({ url: parsed, options });
if (parsed.searchParams.get('action') === 'getNumber') {
return createTextResponse('ACCESS_NUMBER:67890:6281234567890');
}
throw new Error(`unexpected ${parsed.toString()}`);
},
});
const activation = await provider.requestActivation({ smsBowerApiKey: 'demo-key' });
assert.equal(requests[0].url.searchParams.get('country'), '6');
assert.equal(activation.countryId, 6);
assert.equal(activation.countryLabel, 'Indonesia');
});
test('SMS Bower provider uses handler API key query for balance and price catalog', async () => {
const requests = [];
const provider = api.createProvider({
fetchImpl: async (url, options = {}) => {
const parsed = new URL(url);
requests.push({ url: parsed, options });
if (parsed.searchParams.get('action') === 'getBalance') {
return createTextResponse('ACCESS_BALANCE:12.34');
}
if (parsed.searchParams.get('action') === 'getPrices') {
return createTextResponse({ 52: { ot: { cost: 0.21, count: 7 } } });
}
throw new Error(`unexpected ${parsed.toString()}`);
},
});
const balance = await provider.fetchBalance({ smsBowerApiKey: 'demo-key' });
const prices = await provider.fetchPrices({ smsBowerApiKey: 'demo-key', smsBowerCountryId: 52 });
const entries = provider.collectPriceEntries(prices, []);
assert.equal(requests[0].url.origin + requests[0].url.pathname, 'https://smsbower.page/stubs/handler_api.php');
assert.equal(requests[0].url.searchParams.get('api_key'), 'demo-key');
assert.equal(requests[0].url.searchParams.get('action'), 'getBalance');
assert.equal(balance.balance, 12.34);
assert.equal(requests[1].url.searchParams.get('action'), 'getPrices');
assert.equal(requests[1].url.searchParams.get('service'), 'ot');
assert.equal(requests[1].url.searchParams.get('country'), '52');
assert.deepStrictEqual(entries, [{ cost: 0.21, count: 7, inStock: true }]);
});
test('SMS Bower provider acquires number, polls code, and updates activation statuses', async () => {
const requests = [];
const provider = api.createProvider({
fetchImpl: async (url, options = {}) => {
const parsed = new URL(url);
const action = parsed.searchParams.get('action');
requests.push({ url: parsed, options });
if (action === 'getNumber') {
return createTextResponse('ACCESS_NUMBER:12345:447700900123');
}
if (action === 'getStatus') {
return createTextResponse('STATUS_OK:Your OpenAI code is 654321');
}
if (action === 'setStatus') {
return createTextResponse(parsed.searchParams.get('status') === '6' ? 'ACCESS_ACTIVATION' : 'ACCESS_CANCEL');
}
throw new Error(`unexpected ${parsed.toString()}`);
},
sleepWithStop: async () => {},
throwIfStopped: () => {},
});
const state = {
smsBowerApiKey: 'demo-key',
smsBowerServiceCode: 'ot',
smsBowerCountryId: 16,
smsBowerCountryLabel: 'United Kingdom',
smsBowerMaxPrice: '0.3',
smsBowerMinPrice: '0.1',
smsBowerProviderIds: '3170,3180',
};
const activation = await provider.requestActivation(state);
const code = await provider.pollActivationCode(state, activation, { timeoutMs: 1000, intervalMs: 1, maxRounds: 1 });
await provider.finishActivation(state, activation);
await provider.cancelActivation(state, activation);
await provider.banActivation(state, activation);
const reused = await provider.reuseActivation(state, activation);
assert.equal(activation.provider, 'sms-bower');
assert.equal(activation.activationId, '12345');
assert.equal(activation.phoneNumber, '447700900123');
assert.equal(activation.countryId, 16);
assert.equal(code, '654321');
assert.equal(reused.activationId, '12345');
const acquireUrl = requests[0].url;
assert.equal(acquireUrl.searchParams.get('action'), 'getNumber');
assert.equal(acquireUrl.searchParams.get('service'), 'ot');
assert.equal(acquireUrl.searchParams.get('country'), '16');
assert.equal(acquireUrl.searchParams.get('maxPrice'), '0.3');
assert.equal(acquireUrl.searchParams.get('minPrice'), '0.1');
assert.equal(acquireUrl.searchParams.get('providerIds'), '3170,3180');
assert.deepStrictEqual(
requests.map((entry) => [entry.url.searchParams.get('action'), entry.url.searchParams.get('status')]),
[
['getNumber', null],
['getStatus', null],
['setStatus', '6'],
['setStatus', '8'],
['setStatus', '8'],
['setStatus', '3'],
]
);
});