forked from EduCraft/curriculum-project-hub
126 lines
4.4 KiB
TypeScript
126 lines
4.4 KiB
TypeScript
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
|
import * as lark from "@larksuiteoapi/node-sdk";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
|
|
const openServers: ReturnType<typeof createServer>[] = [];
|
|
|
|
describe("real Lark SDK HTTP transport", () => {
|
|
afterEach(async () => {
|
|
await Promise.all(openServers.splice(0).map(async (server) => {
|
|
server.closeAllConnections();
|
|
await new Promise<void>((resolve, reject) => {
|
|
server.close((error) => error === undefined ? resolve() : reject(error));
|
|
});
|
|
}));
|
|
});
|
|
|
|
it("uses overridden Axios for token, authenticated success, and HTTP error paths", async () => {
|
|
const requests: Array<{
|
|
readonly method: string | undefined;
|
|
readonly url: string | undefined;
|
|
readonly authorization: string | undefined;
|
|
readonly body: string;
|
|
}> = [];
|
|
const server = createServer(async (request, response) => {
|
|
const body = await readBody(request);
|
|
requests.push({
|
|
method: request.method,
|
|
url: request.url,
|
|
authorization: request.headers.authorization,
|
|
body,
|
|
});
|
|
routeSmokeRequest(request, response, body);
|
|
});
|
|
openServers.push(server);
|
|
await new Promise<void>((resolve, reject) => {
|
|
server.once("error", reject);
|
|
server.listen(0, "127.0.0.1", resolve);
|
|
});
|
|
const address = server.address();
|
|
if (address === null || typeof address === "string") throw new Error("local HTTP server has no TCP address");
|
|
const domain = `http://127.0.0.1:${address.port}`;
|
|
const client = new lark.Client({
|
|
appId: "cli_transport_smoke",
|
|
appSecret: "transport-smoke-secret",
|
|
domain,
|
|
loggerLevel: lark.LoggerLevel.error,
|
|
});
|
|
|
|
await expect(client.request<{ readonly code: number; readonly data: { readonly ok: boolean } }>({
|
|
method: "GET",
|
|
url: "/open-apis/smoke/success",
|
|
params: { probe: "axios-override" },
|
|
})).resolves.toEqual({ code: 0, data: { ok: true } });
|
|
|
|
await expect(client.request({
|
|
method: "GET",
|
|
url: "/open-apis/smoke/failure",
|
|
})).rejects.toMatchObject({
|
|
response: {
|
|
status: 429,
|
|
data: { code: 999_429, msg: "forced smoke failure" },
|
|
},
|
|
});
|
|
|
|
expect(requests).toHaveLength(3);
|
|
expect(requests[0]).toMatchObject({
|
|
method: "POST",
|
|
url: "/open-apis/auth/v3/tenant_access_token/internal",
|
|
authorization: undefined,
|
|
});
|
|
expect(JSON.parse(requests[0]!.body)).toEqual({
|
|
app_id: "cli_transport_smoke",
|
|
app_secret: "transport-smoke-secret",
|
|
});
|
|
expect(requests[1]).toMatchObject({
|
|
method: "GET",
|
|
url: "/open-apis/smoke/success?probe=axios-override",
|
|
authorization: "Bearer tenant-transport-smoke",
|
|
});
|
|
expect(requests[2]).toMatchObject({
|
|
method: "GET",
|
|
url: "/open-apis/smoke/failure",
|
|
authorization: "Bearer tenant-transport-smoke",
|
|
});
|
|
});
|
|
});
|
|
|
|
async function readBody(request: IncomingMessage): Promise<string> {
|
|
const chunks: Buffer[] = [];
|
|
for await (const chunk of request) {
|
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
}
|
|
return Buffer.concat(chunks).toString("utf8");
|
|
}
|
|
|
|
function routeSmokeRequest(request: IncomingMessage, response: ServerResponse, body: string): void {
|
|
if (request.method === "POST" && request.url === "/open-apis/auth/v3/tenant_access_token/internal") {
|
|
const credential = JSON.parse(body) as { app_id?: unknown; app_secret?: unknown };
|
|
if (credential.app_id !== "cli_transport_smoke" || credential.app_secret !== "transport-smoke-secret") {
|
|
sendJson(response, 401, { code: 401, msg: "bad smoke credential" });
|
|
return;
|
|
}
|
|
sendJson(response, 200, {
|
|
code: 0,
|
|
msg: "ok",
|
|
tenant_access_token: "tenant-transport-smoke",
|
|
expire: 3_600,
|
|
});
|
|
return;
|
|
}
|
|
if (request.method === "GET" && request.url === "/open-apis/smoke/success?probe=axios-override") {
|
|
sendJson(response, 200, { code: 0, data: { ok: true } });
|
|
return;
|
|
}
|
|
if (request.method === "GET" && request.url === "/open-apis/smoke/failure") {
|
|
sendJson(response, 429, { code: 999_429, msg: "forced smoke failure" });
|
|
return;
|
|
}
|
|
sendJson(response, 404, { code: 404, msg: "unknown smoke route" });
|
|
}
|
|
|
|
function sendJson(response: ServerResponse, statusCode: number, body: unknown): void {
|
|
response.writeHead(statusCode, { "content-type": "application/json" });
|
|
response.end(JSON.stringify(body));
|
|
}
|