/** * Infrastructure Adapter: InMemoryMediaRepository * * In-memory implementation of MediaRepository for testing purposes. * Stores media entities in memory for fast, deterministic testing. */ import type { Media } from '@core/media/domain/entities/Media'; import type { MediaRepository } from '@core/media/domain/repositories/MediaRepository'; import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryMediaRepository implements MediaRepository { private media: Map = new Map(); private uploadedByMedia: Map = new Map(); constructor(private readonly logger: Logger) { this.logger.info('[InMemoryMediaRepository] Initialized.'); } async save(media: Media): Promise { this.logger.debug(`[InMemoryMediaRepository] Saving media: ${media.id} for uploader: ${media.uploadedBy}`); // Store by ID this.media.set(media.id, media); // Store by uploader if (!this.uploadedByMedia.has(media.uploadedBy)) { this.uploadedByMedia.set(media.uploadedBy, []); } const uploaderMedia = this.uploadedByMedia.get(media.uploadedBy)!; const existingIndex = uploaderMedia.findIndex(m => m.id === media.id); if (existingIndex > -1) { uploaderMedia[existingIndex] = media; } else { uploaderMedia.push(media); } this.logger.info(`Media ${media.id} for uploader ${media.uploadedBy} saved successfully.`); } async findById(id: string): Promise { this.logger.debug(`[InMemoryMediaRepository] Finding media by ID: ${id}`); const media = this.media.get(id) ?? null; if (media) { this.logger.info(`Found media by ID: ${id}`); } else { this.logger.warn(`Media with ID ${id} not found.`); } return media; } async findByUploadedBy(uploadedBy: string): Promise { this.logger.debug(`[InMemoryMediaRepository] Finding all media for uploader: ${uploadedBy}`); const uploaderMedia = this.uploadedByMedia.get(uploadedBy) ?? []; this.logger.info(`Found ${uploaderMedia.length} media files for uploader ${uploadedBy}.`); return uploaderMedia; } async delete(id: string): Promise { this.logger.debug(`[InMemoryMediaRepository] Deleting media with ID: ${id}`); const mediaToDelete = this.media.get(id); if (!mediaToDelete) { this.logger.warn(`Media with ID ${id} not found for deletion.`); return; } // Remove from media map this.media.delete(id); // Remove from uploader media const uploaderMedia = this.uploadedByMedia.get(mediaToDelete.uploadedBy); if (uploaderMedia) { const filtered = uploaderMedia.filter(media => media.id !== id); if (filtered.length > 0) { this.uploadedByMedia.set(mediaToDelete.uploadedBy, filtered); } else { this.uploadedByMedia.delete(mediaToDelete.uploadedBy); } } this.logger.info(`Media ${id} deleted successfully.`); } /** * Clear all media from the repository */ clear(): void { this.media.clear(); this.uploadedByMedia.clear(); this.logger.info('[InMemoryMediaRepository] All media cleared.'); } /** * Get the total number of media files stored */ get size(): number { return this.media.size; } }