import { describe, it, expect, vi, Mocked } from 'vitest'; import { MediaService } from './MediaService'; import { MediaApiClient } from '../../api/media/MediaApiClient'; import { MediaViewModel } from '../../view-models/MediaViewModel'; import { UploadMediaViewModel } from '../../view-models/UploadMediaViewModel'; import { DeleteMediaViewModel } from '../../view-models/DeleteMediaViewModel'; describe('MediaService', () => { let mockApiClient: Mocked; let service: MediaService; beforeEach(() => { mockApiClient = { uploadMedia: vi.fn(), getMedia: vi.fn(), deleteMedia: vi.fn(), } as Mocked; service = new MediaService(mockApiClient); }); describe('uploadMedia', () => { it('should call apiClient.uploadMedia with correct input and return view model', async () => { const input = { file: new File(['test'], 'test.jpg', { type: 'image/jpeg' }), type: 'image', category: 'avatar' as const, }; const expectedOutput = { success: true, mediaId: 'media-123', url: 'https://example.com/media.jpg' }; mockApiClient.uploadMedia.mockResolvedValue(expectedOutput); const result = await service.uploadMedia(input); expect(mockApiClient.uploadMedia).toHaveBeenCalledWith(input); expect(result).toBeInstanceOf(UploadMediaViewModel); expect(result.success).toBe(true); expect(result.mediaId).toBe('media-123'); expect(result.url).toBe('https://example.com/media.jpg'); expect(result.isSuccessful).toBe(true); expect(result.hasError).toBe(false); }); it('should handle error response', async () => { const input = { file: new File(['test'], 'test.jpg', { type: 'image/jpeg' }), type: 'image', }; const expectedOutput = { success: false, error: 'Upload failed' }; mockApiClient.uploadMedia.mockResolvedValue(expectedOutput); const result = await service.uploadMedia(input); expect(result).toBeInstanceOf(UploadMediaViewModel); expect(result.success).toBe(false); expect(result.error).toBe('Upload failed'); expect(result.isSuccessful).toBe(false); expect(result.hasError).toBe(true); }); it('should handle upload without category', async () => { const input = { file: new File(['test'], 'test.jpg', { type: 'image/jpeg' }), type: 'image', }; const expectedOutput = { success: true, mediaId: 'media-456', url: 'https://example.com/media2.jpg' }; mockApiClient.uploadMedia.mockResolvedValue(expectedOutput); const result = await service.uploadMedia(input); expect(mockApiClient.uploadMedia).toHaveBeenCalledWith(input); expect(result).toBeInstanceOf(UploadMediaViewModel); expect(result.success).toBe(true); }); }); describe('getMedia', () => { it('should call apiClient.getMedia with mediaId and return view model', async () => { const mediaId = 'media-123'; const expectedOutput = { id: 'media-123', url: 'https://example.com/image.jpg', type: 'image' as const, category: 'avatar' as const, uploadedAt: new Date('2023-01-15'), size: 2048000, }; mockApiClient.getMedia.mockResolvedValue(expectedOutput); const result = await service.getMedia(mediaId); expect(mockApiClient.getMedia).toHaveBeenCalledWith(mediaId); expect(result).toBeInstanceOf(MediaViewModel); expect(result.id).toBe('media-123'); expect(result.url).toBe('https://example.com/image.jpg'); expect(result.type).toBe('image'); expect(result.category).toBe('avatar'); expect(result.uploadedAt).toEqual(new Date('2023-01-15')); expect(result.size).toBe(2048000); expect(result.formattedSize).toBe('2000.00 KB'); }); it('should handle media without category and size', async () => { const mediaId = 'media-456'; const expectedOutput = { id: 'media-456', url: 'https://example.com/video.mp4', type: 'video' as const, uploadedAt: new Date('2023-02-20'), }; mockApiClient.getMedia.mockResolvedValue(expectedOutput); const result = await service.getMedia(mediaId); expect(result).toBeInstanceOf(MediaViewModel); expect(result.id).toBe('media-456'); expect(result.type).toBe('video'); expect(result.category).toBeUndefined(); expect(result.size).toBeUndefined(); expect(result.formattedSize).toBe('Unknown'); }); }); describe('deleteMedia', () => { it('should call apiClient.deleteMedia with mediaId and return view model', async () => { const mediaId = 'media-123'; const expectedOutput = { success: true }; mockApiClient.deleteMedia.mockResolvedValue(expectedOutput); const result = await service.deleteMedia(mediaId); expect(mockApiClient.deleteMedia).toHaveBeenCalledWith(mediaId); expect(result).toBeInstanceOf(DeleteMediaViewModel); expect(result.success).toBe(true); expect(result.isSuccessful).toBe(true); expect(result.hasError).toBe(false); }); it('should handle error response', async () => { const mediaId = 'media-456'; const expectedOutput = { success: false, error: 'Deletion failed' }; mockApiClient.deleteMedia.mockResolvedValue(expectedOutput); const result = await service.deleteMedia(mediaId); expect(result).toBeInstanceOf(DeleteMediaViewModel); expect(result.success).toBe(false); expect(result.error).toBe('Deletion failed'); expect(result.isSuccessful).toBe(false); expect(result.hasError).toBe(true); }); }); });