feat: mail find reply and outlook message retrieval
这个提交包含在:
1 父节点
84d73f1b86
当前提交
e390b1b1eb
4 个文件已更改
+743
没有与搜索条件相匹配的文件
@@ -0,0 +1,67 @@
|
||||
import net from "node:net";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import type { CatalogComponent, FlowNode } from "../../shared/types";
|
||||
import type { RunContext } from "../engine/types";
|
||||
import { getHandler, hasCapability } from "../engine/registry";
|
||||
import "./message";
|
||||
|
||||
const context = {} as RunContext;
|
||||
const component = {} as CatalogComponent;
|
||||
const node = (id: string): FlowNode => ({ id, componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} });
|
||||
const ids = [
|
||||
"Mail_FindMail", "Mail_FindMail_v1", "Mail_FindMail_v2",
|
||||
"Mail_ReplyMail", "Mail_ReplyMail_v1", "Mail_ReplyMail_v2",
|
||||
"Mail_DoGetMailMessage", "Mail_DoGetMailMessage_v1", "Mail_DoGetMailMessage_v2"
|
||||
];
|
||||
|
||||
afterEach(async () => {});
|
||||
|
||||
describe("mail receive and reply", () => {
|
||||
it("registers find, reply and Outlook message capabilities", () => {
|
||||
for (const id of ids) expect(hasCapability(id), id).toBe(true);
|
||||
});
|
||||
|
||||
it("replies through SMTP with the selected mail sender", async () => {
|
||||
let received = "";
|
||||
const server = net.createServer((socket) => {
|
||||
socket.setEncoding("utf8");
|
||||
socket.write("220 localhost ESMTP\r\n");
|
||||
let buffer = "";
|
||||
let dataMode = false;
|
||||
socket.on("data", (chunk) => {
|
||||
buffer += chunk;
|
||||
const lines = buffer.split("\r\n");
|
||||
buffer = lines.pop() || "";
|
||||
for (const line of lines) {
|
||||
if (dataMode) {
|
||||
if (line === ".") {
|
||||
dataMode = false;
|
||||
socket.write("250 queued\r\n");
|
||||
} else received += line + "\n";
|
||||
} else if (/^EHLO/i.test(line)) socket.write("250-localhost\r\n250 OK\r\n");
|
||||
else if (/^MAIL FROM/i.test(line)) socket.write("250 ok\r\n");
|
||||
else if (/^RCPT TO/i.test(line)) socket.write("250 ok\r\n");
|
||||
else if (/^DATA/i.test(line)) { dataMode = true; socket.write("354 end with dot\r\n"); }
|
||||
else if (/^QUIT/i.test(line)) { socket.write("221 bye\r\n"); socket.end(); }
|
||||
else socket.write("250 OK\r\n");
|
||||
}
|
||||
});
|
||||
});
|
||||
await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||
const port = (server.address() as net.AddressInfo).port;
|
||||
try {
|
||||
const handler = getHandler("Mail_ReplyMail_v2");
|
||||
expect(handler).toBeTruthy();
|
||||
const result = await handler!(context, node("Mail_ReplyMail_v2"), {
|
||||
account_obj: { host: "127.0.0.1", port, account: "robot@example.com", secure: "False" },
|
||||
mail_obj: { from: "owner@example.com", subject: "status", messageId: "<abc@example.com>" },
|
||||
content: "reply delivered"
|
||||
}, component);
|
||||
expect(result).toMatchObject({ accepted: ["owner@example.com"] });
|
||||
expect(received).toContain("reply delivered");
|
||||
expect(received).toContain("Re: status");
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => server.close(() => resolve()));
|
||||
}
|
||||
}, 30000);
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户