Files
boss/tests/aliyun-oss-storage.test.ts

102 lines
3.6 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
createAliyunOssStorageProvider,
getAliyunOssSignedDownloadUrl,
readAliyunOssObjectBuffer,
validateAliyunOssConfig,
} from "../src/lib/boss-storage-aliyun-oss.ts";
import { encryptStorageSecret } from "../src/lib/boss-storage-secrets.ts";
async function createConfig() {
process.env.BOSS_STORAGE_SECRET_KEY = "aliyun-oss-storage-test-key";
return {
enabled: true,
accessKeyId: "test-access-key",
accessKeySecretEncrypted: await encryptStorageSecret("test-secret"),
bucket: "boss-bucket",
endpoint: "oss-cn-hangzhou.aliyuncs.com",
region: "oss-cn-hangzhou",
prefix: "uploads",
};
}
test("aliyun oss storage uploads attachments through signed REST requests", async () => {
const config = await createConfig();
const originalFetch = globalThis.fetch;
const calls: Array<{ input: string; init?: RequestInit }> = [];
globalThis.fetch = (async (input, init) => {
calls.push({ input: String(input), init });
return new Response("", { status: 200 });
}) as typeof fetch;
try {
const provider = createAliyunOssStorageProvider(config);
const record = await provider.storeAttachment({
account: "kris@example.com",
messageId: "msg-1",
fileName: "report.txt",
mimeType: "text/plain",
buffer: Buffer.from("hello"),
});
assert.equal(record.storageBackend, "aliyun_oss");
assert.match(record.storagePath, /^uploads\/acct-[a-f0-9]{16}\/\d{4}\/\d{2}\/msg-1-report\.txt$/);
assert.equal(calls.length, 1);
assert.match(calls[0].input, /^https:\/\/boss-bucket\.oss-cn-hangzhou\.aliyuncs\.com\/uploads\/acct-/);
assert.equal(calls[0].init?.method, "PUT");
const headers = calls[0].init?.headers as Record<string, string>;
assert.equal(headers["content-type"], "text/plain");
assert.match(headers.authorization, /^OSS test-access-key:/);
assert.ok(headers["x-oss-date"]);
} finally {
globalThis.fetch = originalFetch;
}
});
test("aliyun oss signed download url is generated without network access", async () => {
const config = await createConfig();
const signedUrl = await getAliyunOssSignedDownloadUrl(config, "uploads/demo file.txt", 600);
const url = new URL(signedUrl);
assert.equal(url.hostname, "boss-bucket.oss-cn-hangzhou.aliyuncs.com");
assert.equal(url.pathname, "/uploads/demo%20file.txt");
assert.equal(url.searchParams.get("OSSAccessKeyId"), "test-access-key");
assert.ok(url.searchParams.get("Expires"));
assert.ok(url.searchParams.get("Signature"));
});
test("aliyun oss storage reads objects and validates bucket config", async () => {
const config = await createConfig();
const originalFetch = globalThis.fetch;
const calls: Array<{ input: string; init?: RequestInit }> = [];
globalThis.fetch = (async (input, init) => {
calls.push({ input: String(input), init });
if (String(input).endsWith("?bucketInfo")) {
return new Response("<BucketInfo><Bucket><Name>boss-bucket</Name></Bucket></BucketInfo>", {
status: 200,
});
}
return new Response("object-content", { status: 200 });
}) as typeof fetch;
try {
const buffer = await readAliyunOssObjectBuffer(config, "uploads/a.txt");
assert.equal(buffer.toString("utf8"), "object-content");
const validation = await validateAliyunOssConfig(config);
assert.deepEqual(validation, {
provider: "aliyun_oss",
bucket: "boss-bucket",
endpoint: "oss-cn-hangzhou.aliyuncs.com",
region: "oss-cn-hangzhou",
});
assert.equal(calls.length, 2);
assert.match(calls[1].input, /\/\?bucketInfo$/);
} finally {
globalThis.fetch = originalFetch;
}
});