import 'dart:convert'; import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:mail_hub/core/models/address.dart'; import 'package:mail_hub/core/protocol/mime/mime_builder.dart'; import 'package:mail_hub/core/protocol/smtp/smtp_client.dart'; import 'package:mail_hub/core/protocol/smtp/smtp_exception.dart'; /// SMTP 客户端集成测试:连接本地 Mock 服务器,验证完整发信流程 void main() { Process? server; int port = 0; final outFile = '${Directory.systemTemp.path}/mock_smtp_${DateTime.now().millisecondsSinceEpoch}.eml'; setUpAll(() async { final probe = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0); port = probe.port; await probe.close(); server = await Process.start('python3', [ 'test/mock_smtp_server.py', '$port', '--auth-user', 'test@example.com', '--auth-pass', 'secret', '--out', outFile, ]); await server!.stdout.transform(utf8.decoder).first; }); tearDownAll(() async { server?.kill(); final f = File(outFile); if (await f.exists()) await f.delete(); }); test('完整流程:连接→EHLO→AUTH→发送→QUIT', () async { final client = SmtpClient(); await client.connect('127.0.0.1', port, ssl: false); expect(client.isConnected, true); expect(client.hasCapability('AUTH'), true); await client.auth('test@example.com', 'secret'); final raw = MimeBuilder.build( from: const MailAddress('张三', 'zhangsan@example.com'), to: const [MailAddress('李四', 'lisi@example.com')], cc: const [MailAddress('王五', 'wangwu@example.com')], subject: 'SMTP 集成测试', textBody: '这是正文', htmlBody: '这是正文', ); await client.sendMail('zhangsan@example.com', [ 'lisi@example.com', 'wangwu@example.com', 'secret-bcc@example.com', ], raw); client.quit(); client.disconnect(); expect(client.isConnected, false); // 校验 mock 收到的邮件内容 final eml = await File(outFile).readAsString(); expect(eml, contains('From: =?UTF-8?B?5byg5LiJ?= ')); expect(eml, contains('To: =?UTF-8?B?5p2O5Zub?= ')); expect(eml, contains('Cc: =?UTF-8?B?546L5LqU?= ')); expect(eml, contains('Subject: =?UTF-8?B?U01UUCDpm4bmiJDmtYvor5U=?=')); expect(eml, contains('multipart/alternative')); // 无附件时不包裹 mixed expect(eml, isNot(contains('multipart/mixed'))); expect(eml, contains('MOCK_MSG_END')); }); test('认证失败抛出 SmtpException', () async { final client = SmtpClient(); await client.connect('127.0.0.1', port, ssl: false); await expectLater( client.auth('test@example.com', 'wrong'), throwsA(isA()), ); client.disconnect(); }); test('连接被拒抛出 SmtpException', () async { final client = SmtpClient(); await expectLater( client.connect('127.0.0.1', 1, ssl: false), throwsA(isA()), ); }); }