/** * 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 = new Map(); private metadata: Map = new Map(); constructor(private readonly logger: Logger) { this.logger.info('[InMemoryMediaStorageAdapter] Initialized.'); } async uploadMedia(buffer: Buffer, options: UploadOptions): Promise { 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 { 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 { 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); } }