integration tests
This commit is contained in:
109
adapters/media/ports/InMemoryMediaStorageAdapter.ts
Normal file
109
adapters/media/ports/InMemoryMediaStorageAdapter.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Infrastructure Adapter: InMemoryMediaStorageAdapter
|
||||
*
|
||||
* In-memory implementation of MediaStoragePort for testing purposes.
|
||||
* Simulates file storage without actual filesystem operations.
|
||||
*/
|
||||
|
||||
import type { MediaStoragePort, UploadOptions, UploadResult } from '@core/media/application/ports/MediaStoragePort';
|
||||
import type { Logger } from '@core/shared/domain/Logger';
|
||||
|
||||
export class InMemoryMediaStorageAdapter implements MediaStoragePort {
|
||||
private storage: Map<string, Buffer> = new Map();
|
||||
private metadata: Map<string, { size: number; contentType: string }> = new Map();
|
||||
|
||||
constructor(private readonly logger: Logger) {
|
||||
this.logger.info('[InMemoryMediaStorageAdapter] Initialized.');
|
||||
}
|
||||
|
||||
async uploadMedia(buffer: Buffer, options: UploadOptions): Promise<UploadResult> {
|
||||
this.logger.debug(`[InMemoryMediaStorageAdapter] Uploading media: ${options.filename}`);
|
||||
|
||||
// Validate content type
|
||||
const allowedTypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'image/gif'];
|
||||
if (!allowedTypes.includes(options.mimeType)) {
|
||||
return {
|
||||
success: false,
|
||||
errorMessage: `Content type ${options.mimeType} is not allowed`,
|
||||
};
|
||||
}
|
||||
|
||||
// Generate storage key
|
||||
const storageKey = `uploaded/${Date.now()}-${options.filename.replace(/[^a-zA-Z0-9.-]/g, '_')}`;
|
||||
|
||||
// Store buffer and metadata
|
||||
this.storage.set(storageKey, buffer);
|
||||
this.metadata.set(storageKey, {
|
||||
size: buffer.length,
|
||||
contentType: options.mimeType,
|
||||
});
|
||||
|
||||
this.logger.info(`Media uploaded successfully: ${storageKey}`);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
filename: options.filename,
|
||||
url: storageKey,
|
||||
};
|
||||
}
|
||||
|
||||
async deleteMedia(storageKey: string): Promise<void> {
|
||||
this.logger.debug(`[InMemoryMediaStorageAdapter] Deleting media: ${storageKey}`);
|
||||
|
||||
this.storage.delete(storageKey);
|
||||
this.metadata.delete(storageKey);
|
||||
|
||||
this.logger.info(`Media deleted successfully: ${storageKey}`);
|
||||
}
|
||||
|
||||
async getBytes(storageKey: string): Promise<Buffer | null> {
|
||||
this.logger.debug(`[InMemoryMediaStorageAdapter] Getting bytes for: ${storageKey}`);
|
||||
|
||||
const buffer = this.storage.get(storageKey) ?? null;
|
||||
|
||||
if (buffer) {
|
||||
this.logger.info(`Retrieved bytes for: ${storageKey}`);
|
||||
} else {
|
||||
this.logger.warn(`No bytes found for: ${storageKey}`);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
async getMetadata(storageKey: string): Promise<{ size: number; contentType: string } | null> {
|
||||
this.logger.debug(`[InMemoryMediaStorageAdapter] Getting metadata for: ${storageKey}`);
|
||||
|
||||
const meta = this.metadata.get(storageKey) ?? null;
|
||||
|
||||
if (meta) {
|
||||
this.logger.info(`Retrieved metadata for: ${storageKey}`);
|
||||
} else {
|
||||
this.logger.warn(`No metadata found for: ${storageKey}`);
|
||||
}
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all stored media
|
||||
*/
|
||||
clear(): void {
|
||||
this.storage.clear();
|
||||
this.metadata.clear();
|
||||
this.logger.info('[InMemoryMediaStorageAdapter] All media cleared.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of stored media files
|
||||
*/
|
||||
get size(): number {
|
||||
return this.storage.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a storage key exists
|
||||
*/
|
||||
has(storageKey: string): boolean {
|
||||
return this.storage.has(storageKey);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user