fix: resolve Bun mock isolation contamination across test files
Some checks failed
CI / ci (push) Failing after 1m35s
CI / e2e (push) Has been skipped
CI / deploy (push) Has been skipped

- storage.service.ts: use dynamic import() inside each function so the
  current @aws-sdk mock is always picked up regardless of module load order
- images.test.ts + image.service.test.ts: replace module-level storage.service
  mock with @aws-sdk/client-s3 mock to avoid contaminating storage.service.test.ts
- routes/auth.test.ts: remove unnecessary oauth.service mock (no test uses
  verifyAccessToken) which was contaminating oauth.service.test.ts
- middleware/auth.test.ts: complete oauth.service mock shape with all exports

All 464 tests now pass in a single bun test run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 16:19:39 +02:00
parent 4ccbb2b070
commit 5f63e6f75d
5 changed files with 96 additions and 59 deletions

View File

@@ -1,22 +1,6 @@
import {
DeleteObjectCommand,
GetObjectCommand,
PutObjectCommand,
S3Client,
} from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
// S3 API abstraction — provider-agnostic (Garage, Cloudflare R2, AWS S3).
const s3 = new S3Client({
endpoint: process.env.S3_ENDPOINT,
region: process.env.S3_REGION ?? "us-east-1",
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY!,
secretAccessKey: process.env.S3_SECRET_KEY!,
},
forcePathStyle: true, // REQUIRED for Garage and most S3-compatible services
});
// Dynamic imports are used intentionally so that test mocks for @aws-sdk/*
// take effect even when this module is already cached from a prior import.
const bucket = process.env.S3_BUCKET ?? "gearbox-images";
const presignExpiry = Number.parseInt(
@@ -24,11 +8,26 @@ const presignExpiry = Number.parseInt(
10,
);
async function createS3Client() {
const { S3Client } = await import("@aws-sdk/client-s3");
return new S3Client({
endpoint: process.env.S3_ENDPOINT,
region: process.env.S3_REGION ?? "us-east-1",
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY!,
secretAccessKey: process.env.S3_SECRET_KEY!,
},
forcePathStyle: true, // REQUIRED for Garage and most S3-compatible services
});
}
export async function uploadImage(
buffer: Buffer | ArrayBuffer,
filename: string,
contentType: string,
): Promise<void> {
const { PutObjectCommand } = await import("@aws-sdk/client-s3");
const s3 = await createS3Client();
await s3.send(
new PutObjectCommand({
Bucket: bucket,
@@ -40,6 +39,8 @@ export async function uploadImage(
}
export async function deleteImage(filename: string): Promise<void> {
const { DeleteObjectCommand } = await import("@aws-sdk/client-s3");
const s3 = await createS3Client();
await s3.send(
new DeleteObjectCommand({
Bucket: bucket,
@@ -49,6 +50,9 @@ export async function deleteImage(filename: string): Promise<void> {
}
export async function getImageUrl(filename: string): Promise<string> {
const { GetObjectCommand } = await import("@aws-sdk/client-s3");
const { getSignedUrl } = await import("@aws-sdk/s3-request-presigner");
const s3 = await createS3Client();
const command = new GetObjectCommand({
Bucket: bucket,
Key: filename,