claude-code-remote-remake/test-email-reply.js

231 lines
7.5 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* TaskPing 邮件回复测试工具
* 用于测试邮件命令提取和 PTY 注入功能
*/
const path = require('path');
const fs = require('fs');
// 加载 relay-pty 模块
const {
extractTokenFromSubject,
stripReply,
handleMailMessage
} = require('./src/relay/relay-pty');
// 测试用例
const testCases = [
{
name: '基本命令',
email: {
subject: 'Re: [TaskPing #TEST123] 任务等待您的指示',
from: { text: 'user@example.com', value: [{ address: 'user@example.com' }] },
text: '继续执行\n\n> 原始邮件内容...'
},
expectedToken: 'TEST123',
expectedCommand: '继续执行'
},
{
name: 'CMD前缀',
email: {
subject: 'Re: TaskPing: ABC789',
from: { text: 'user@example.com', value: [{ address: 'user@example.com' }] },
text: 'CMD: npm run build\n\n发自我的iPhone'
},
expectedToken: 'ABC789',
expectedCommand: 'npm run build'
},
{
name: '代码块',
email: {
subject: 'Re: [TaskPing #XYZ456]',
from: { text: 'user@example.com', value: [{ address: 'user@example.com' }] },
text: '这是我的命令:\n\n```\ngit add .\ngit commit -m "Update"\n```\n\n谢谢'
},
expectedToken: 'XYZ456',
expectedCommand: 'git add .\ngit commit -m "Update"'
},
{
name: '复杂邮件引用',
email: {
subject: 'Re: [TaskPing #TASK999] 请输入下一步操作',
from: { text: 'boss@company.com', value: [{ address: 'boss@company.com' }] },
text: `yes, please continue
--
Best regards,
Boss
On 2024-01-01, TaskPing wrote:
> 任务已完成第一步
> 会话ID: 12345-67890
> 请回复您的下一步指示`
},
expectedToken: 'TASK999',
expectedCommand: 'yes, please continue'
},
{
name: 'HTML邮件转纯文本',
email: {
subject: 'Re: [TaskPing #HTML123]',
from: { text: 'user@example.com', value: [{ address: 'user@example.com' }] },
html: '<div>运行测试套件</div><br><blockquote>原始邮件...</blockquote>',
text: '运行测试套件\n\n> 原始邮件...'
},
expectedToken: 'HTML123',
expectedCommand: '运行测试套件'
}
];
// 运行测试
function runTests() {
console.log('🧪 TaskPing 邮件解析测试\n');
let passed = 0;
let failed = 0;
testCases.forEach((testCase, index) => {
console.log(`测试 ${index + 1}: ${testCase.name}`);
try {
// 测试 Token 提取
const token = extractTokenFromSubject(testCase.email.subject);
if (token === testCase.expectedToken) {
console.log(` ✅ Token提取正确: ${token}`);
} else {
console.log(` ❌ Token提取错误: 期望 "${testCase.expectedToken}", 实际 "${token}"`);
failed++;
console.log('');
return;
}
// 测试命令提取
const command = stripReply(testCase.email.text || testCase.email.html);
if (command === testCase.expectedCommand) {
console.log(` ✅ 命令提取正确: "${command}"`);
passed++;
} else {
console.log(` ❌ 命令提取错误:`);
console.log(` 期望: "${testCase.expectedCommand}"`);
console.log(` 实际: "${command}"`);
failed++;
}
} catch (error) {
console.log(` ❌ 测试出错: ${error.message}`);
failed++;
}
console.log('');
});
// 显示结果
console.log('━'.repeat(50));
console.log(`测试完成: ${passed} 通过, ${failed} 失败`);
if (failed === 0) {
console.log('\n✅ 所有测试通过!');
} else {
console.log('\n❌ 部分测试失败,请检查实现');
}
}
// 测试实际邮件处理
async function testEmailProcessing() {
console.log('\n\n📧 测试邮件处理流程\n');
// 设置测试环境变量
process.env.ALLOWED_SENDERS = 'user@example.com,boss@company.com';
process.env.SESSION_MAP_PATH = path.join(__dirname, 'test-session-map.json');
// 创建测试会话
const testSessions = {
'TEST123': {
type: 'pty',
createdAt: Math.floor(Date.now() / 1000),
expiresAt: Math.floor((Date.now() + 3600000) / 1000),
cwd: process.cwd()
}
};
fs.writeFileSync(process.env.SESSION_MAP_PATH, JSON.stringify(testSessions, null, 2));
console.log('✅ 创建测试会话文件');
// 模拟邮件消息
const { simpleParser } = require('mailparser');
const testEmail = `From: user@example.com
To: taskping@example.com
Subject: Re: [TaskPing #TEST123] 测试
Content-Type: text/plain; charset=utf-8
这是测试命令
> 原始邮件内容...`;
try {
console.log('🔄 处理模拟邮件...');
// 注意:实际的 handleMailMessage 会尝试创建 PTY
// 在测试环境中可能会失败,这是预期的
await handleMailMessage(Buffer.from(testEmail), 'test-uid-123');
console.log('✅ 邮件处理流程完成注意PTY创建可能失败这在测试中是正常的');
} catch (error) {
console.log(`⚠️ 邮件处理出错(预期的): ${error.message}`);
}
// 清理测试文件
if (fs.existsSync(process.env.SESSION_MAP_PATH)) {
fs.unlinkSync(process.env.SESSION_MAP_PATH);
console.log('🧹 清理测试文件');
}
}
// 显示集成说明
function showIntegrationGuide() {
console.log('\n\n📚 集成指南\n');
console.log('1. 配置邮件服务器信息:');
console.log(' 编辑 .env 文件,填入 IMAP 配置');
console.log('');
console.log('2. 设置白名单发件人:');
console.log(' ALLOWED_SENDERS=your-email@gmail.com');
console.log('');
console.log('3. 创建会话映射:');
console.log(' 当发送提醒邮件时,在 session-map.json 中添加:');
console.log(' {');
console.log(' "YOUR_TOKEN": {');
console.log(' "type": "pty",');
console.log(' "createdAt": 1234567890,');
console.log(' "expiresAt": 1234567890,');
console.log(' "cwd": "/path/to/project"');
console.log(' }');
console.log(' }');
console.log('');
console.log('4. 启动服务:');
console.log(' ./start-relay-pty.js');
console.log('');
console.log('5. 发送测试邮件:');
console.log(' 主题包含 [TaskPing #YOUR_TOKEN]');
console.log(' 正文为要执行的命令');
}
// 主函数
async function main() {
console.log('╔══════════════════════════════════════════════════════════╗');
console.log('║ TaskPing Email Reply Test Suite ║');
console.log('╚══════════════════════════════════════════════════════════╝\n');
// 运行单元测试
runTests();
// 测试邮件处理
await testEmailProcessing();
// 显示集成指南
showIntegrationGuide();
}
// 运行测试
main().catch(console.error);