fix: align SMS Bower provider with documented API

This commit is contained in:
chick
2026-05-31 00:20:16 +08:00
parent b69490e632
commit 39af4f9ca4
2 changed files with 49 additions and 27 deletions
+26 -14
View File
@@ -14,13 +14,13 @@ function createTextResponse(payload, ok = true, status = ok ? 200 : 400, statusT
};
}
test('SMS Bower provider defaults to Indonesia when no country is configured', async () => {
test('SMS Bower provider defaults to Indonesia and documented OpenAI service code', 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') {
if (parsed.searchParams.get('action') === 'getNumberV2') {
return createTextResponse('ACCESS_NUMBER:67890:6281234567890');
}
throw new Error(`unexpected ${parsed.toString()}`);
@@ -30,11 +30,12 @@ test('SMS Bower provider defaults to Indonesia when no country is configured', a
const activation = await provider.requestActivation({ smsBowerApiKey: 'demo-key' });
assert.equal(requests[0].url.searchParams.get('country'), '6');
assert.equal(requests[0].url.searchParams.get('service'), 'dr');
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 () => {
test('SMS Bower provider uses documented handler API methods for balance and price catalog', async () => {
const requests = [];
const provider = api.createProvider({
fetchImpl: async (url, options = {}) => {
@@ -43,8 +44,8 @@ test('SMS Bower provider uses handler API key query for balance and price catalo
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 } } });
if (parsed.searchParams.get('action') === 'getPricesV3') {
return createTextResponse({ 52: { dr: { 3170: { price: 0.21, count: 7 } } } });
}
throw new Error(`unexpected ${parsed.toString()}`);
},
@@ -58,21 +59,32 @@ test('SMS Bower provider uses handler API key query for balance and price catalo
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('action'), 'getPricesV3');
assert.equal(requests[1].url.searchParams.get('service'), 'dr');
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 () => {
test('SMS Bower provider treats JSON status 0 responses as API errors even when HTTP is ok', async () => {
const provider = api.createProvider({
fetchImpl: async () => createTextResponse({ status: 0, message: 'No access', data: [] }, true, 200),
});
await assert.rejects(
() => provider.fetchBalance({ smsBowerApiKey: 'bad-key' }),
/SMS Bower 查询余额失败:No access/
);
});
test('SMS Bower provider acquires number with getNumberV2, 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 === 'getNumberV2') {
return createTextResponse({ activationId: '12345', phoneNumber: '447700900123', activationCost: 0.3, countryCode: 16 });
}
if (action === 'getStatus') {
return createTextResponse('STATUS_OK:Your OpenAI code is 654321');
@@ -88,7 +100,7 @@ test('SMS Bower provider acquires number, polls code, and updates activation sta
const state = {
smsBowerApiKey: 'demo-key',
smsBowerServiceCode: 'ot',
smsBowerServiceCode: 'dr',
smsBowerCountryId: 16,
smsBowerCountryLabel: 'United Kingdom',
smsBowerMinPrice: '0.1',
@@ -110,8 +122,8 @@ test('SMS Bower provider acquires number, polls code, and updates activation sta
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('action'), 'getNumberV2');
assert.equal(acquireUrl.searchParams.get('service'), 'dr');
assert.equal(acquireUrl.searchParams.get('country'), '16');
assert.equal(acquireUrl.searchParams.get('maxPrice'), '0.3');
assert.equal(acquireUrl.searchParams.get('minPrice'), '0.1');
@@ -121,7 +133,7 @@ test('SMS Bower provider acquires number, polls code, and updates activation sta
assert.deepStrictEqual(
requests.map((entry) => [entry.url.searchParams.get('action'), entry.url.searchParams.get('status')]),
[
['getNumber', null],
['getNumberV2', null],
['getStatus', null],
['setStatus', '6'],
['setStatus', '8'],