openclaw/extensions/sms/test-integration.ts
Narayan Vyas 15b41de880 refactor(channels): rename plivo extension to sms with provider pattern
Restructure the SMS channel extension to follow the voice-call pattern:
- Rename from "plivo" to "sms" (technology-based naming)
- Add provider abstraction (SMSProvider interface)
- Implement PlivoProvider and MockProvider
- Support for future providers (Twilio, etc.)

This makes the extension more extensible and consistent with
the voice-call extension architecture.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 20:36:22 -08:00

183 lines
5.2 KiB
TypeScript

/**
* SMS Extension Integration Test
* Run with: npx tsx test-integration.ts
*/
import { smsPlugin } from "./src/channel.js";
import { PlivoProvider } from "./src/providers/index.js";
import { startWebhookServer } from "./src/webhook.js";
import type { SMSResolvedAccount } from "./src/types.js";
// Test configuration
// Set these environment variables before running:
// PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN, SMS_PHONE_NUMBER, TEST_PHONE_NUMBER
const TEST_CONFIG = {
channels: {
sms: {
provider: "plivo",
phoneNumber: process.env.SMS_PHONE_NUMBER || "+15550001234",
plivo: {
authId: process.env.PLIVO_AUTH_ID,
authToken: process.env.PLIVO_AUTH_TOKEN,
},
webhookPath: "/sms",
enableQuickCommands: true,
},
},
};
async function testConfigAdapter() {
console.log("\n=== Testing Config Adapter ===");
const accountIds = smsPlugin.config.listAccountIds(TEST_CONFIG);
console.log("Account IDs:", accountIds);
const account = smsPlugin.config.resolveAccount(TEST_CONFIG, "default");
console.log("Resolved account:", {
provider: account?.provider,
phoneNumber: account?.phoneNumber,
dmPolicy: account?.dmPolicy,
enableQuickCommands: account?.enableQuickCommands,
});
const isConfigured = smsPlugin.config.isConfigured(TEST_CONFIG, "default");
console.log("Is configured:", isConfigured);
const description = smsPlugin.config.describeAccount(TEST_CONFIG, "default");
console.log("Account description:", description);
return account;
}
async function testPlivoProvider(account: SMSResolvedAccount) {
console.log("\n=== Testing Plivo Provider ===");
const providerConfig = account.providerConfig as { authId: string; authToken: string };
const provider = new PlivoProvider(providerConfig);
try {
await provider.initialize();
console.log("Provider initialized successfully");
} catch (error) {
console.error("Provider initialization failed:", error);
throw error;
}
return provider;
}
async function testOutboundAdapter(_account: SMSResolvedAccount) {
console.log("\n=== Testing Outbound Adapter ===");
// Test resolveTarget with fake 555 numbers
const target1 = smsPlugin.outbound.resolveTarget("+15550001234");
console.log("Resolve target (+15550001234):", target1);
const target2 = smsPlugin.outbound.resolveTarget("5550001234");
console.log("Resolve target (5550001234):", target2);
const target3 = smsPlugin.outbound.resolveTarget("invalid");
console.log("Resolve target (invalid):", target3);
}
async function testWebhookServer(provider: PlivoProvider, account: SMSResolvedAccount) {
console.log("\n=== Testing Webhook Server ===");
const { server, stop } = await startWebhookServer({
provider,
account,
accountId: "default",
path: "/sms",
port: 3456,
onMessage: async (message) => {
console.log("Received message:", message);
return `Echo: ${message.text}`;
},
log: (msg, data) => console.log(`[Webhook] ${msg}`, data || ""),
});
console.log("Webhook server running on http://localhost:3456/sms");
return { server, stop };
}
async function testSendSMS(provider: PlivoProvider, fromNumber: string) {
console.log("\n=== Testing SMS Send ===");
const testNumber = process.env.TEST_PHONE_NUMBER;
if (!testNumber) {
console.log("Skipping send test: TEST_PHONE_NUMBER not set");
return { ok: false, error: "TEST_PHONE_NUMBER not set" };
}
console.log(`Sending test SMS to ${testNumber}...`);
const result = await provider.sendText({
from: fromNumber,
to: testNumber,
text: "Hello from SMS extension test! Provider: Plivo",
});
console.log("Send result:", result);
return result;
}
async function testCapabilities() {
console.log("\n=== Testing Capabilities ===");
console.log("Channel ID:", smsPlugin.id);
console.log("Meta:", smsPlugin.meta);
console.log("Capabilities:", smsPlugin.capabilities);
}
async function main() {
console.log("🚀 Starting SMS extension integration test...\n");
try {
// Test config
const account = await testConfigAdapter();
if (!account) {
throw new Error("Failed to resolve account");
}
// Test capabilities
await testCapabilities();
// Test Plivo provider
const provider = await testPlivoProvider(account);
// Test outbound adapter
await testOutboundAdapter(account);
// Ask if user wants to test sending
const args = process.argv.slice(2);
if (args.includes("--send")) {
await testSendSMS(provider, account.phoneNumber);
} else {
console.log("\n(Skipping SMS send test. Use --send flag to test actual sending)");
}
// Test webhook server
if (args.includes("--webhook")) {
const { stop } = await testWebhookServer(provider, account);
console.log("\nWebhook server started. Press Ctrl+C to stop.");
console.log("Waiting for incoming messages...\n");
process.on("SIGINT", async () => {
console.log("\nShutting down...");
await stop();
process.exit(0);
});
// Keep running
await new Promise(() => {});
}
console.log("\n✅ All tests passed!");
} catch (error) {
console.error("\n❌ Test failed:", error);
process.exit(1);
}
}
main();