import { MusicWorldController } from './music-world.controller'; import { MusicWorldService } from './music-world.service'; describe('MusicWorldController', () => { const createController = ( feedService = { getExplore: jest.fn() }, searchService = { searchPosts: jest.fn() }, ) => new MusicWorldController(new MusicWorldService(feedService as any, searchService as any)); it('returns Flutter-ready Arabic music discovery cards', () => { const controller = createController(); const result = controller.getMusicWorld(); expect(result.title).toBe('عالم الموسيقى'); expect(result.searchPlaceholder).toBe('شو حابب تلاقي اليوم؟'); expect(result.cards).toHaveLength(6); expect(result.cards[0]).toEqual({ key: 'oud', title: 'عود', subtitle: 'اكتشف عزف العود والمقامات الشرقية', imageUrl: '/uploads/music-world/oud.jpg', type: 'search', endpoint: '/api/v1/search/posts', query: 'عود', }); expect(result.cards.some((card) => card.type === 'navigation')).toBe(true); expect(result.sections.map((section) => section.key)).toEqual([ 'trending', 'explore', 'artists', ]); }); it('maps feed explore posts into Flutter grid items', async () => { const feedService = { getExplore: jest.fn().mockResolvedValue({ items: [ { id: 'post-1', feedItemType: 'post', postType: 'video', content: 'عود حجاز', thumbnailUrl: '/uploads/thumb.jpg', media: { mediaType: 'video', displayUrl: '/uploads/thumb-medium.jpg', thumbnailUrl: '/uploads/thumb.jpg', }, authorId: { _id: 'user-1', name: 'Artist', username: 'artist', avatar: '/avatar.jpg', isVerified: true, }, engagement: { likesCount: 3, commentsCount: 2, viewCount: 10, playCount: 7, }, likedByMe: true, savedByMe: false, createdAt: '2026-06-09T00:00:00.000Z', }, { id: 'card-1', feedItemType: 'featured_marketplace', }, ], page: 1, limit: 20, total: 1, totalPages: 1, nextCursor: null, pagination: { hasNextPage: false, nextCursor: null, page: 1, limit: 20 }, }), }; const controller = createController(feedService); const result = await controller.getExplore({ sub: 'viewer-1' } as any, { page: 1, limit: 20, }); expect(feedService.getExplore).toHaveBeenCalledWith('viewer-1', { page: 1, limit: 20 }); expect(result.items).toHaveLength(1); expect(result.items[0]).toMatchObject({ id: 'post-1', postType: 'video', content: 'عود حجاز', thumbnailUrl: '/uploads/thumb.jpg', displayUrl: '/uploads/thumb-medium.jpg', author: { id: 'user-1', username: 'artist', isVerified: true, }, engagement: { likesCount: 3, commentsCount: 2, viewCount: 10, playCount: 7, }, isLiked: true, isSaved: false, }); expect(result.pagination).toMatchObject({ hasNextPage: false }); }); it('maps music-world search results into the same grid item shape', async () => { const searchService = { searchPosts: jest.fn().mockResolvedValue({ items: [ { _id: 'post-2', postType: 'image', content: 'ناي', imageUrls: ['/uploads/ney.jpg'], authorId: { _id: 'user-2', name: 'Ney Artist', username: 'ney_artist', avatar: '', isVerified: false, }, likesCount: 4, commentsCount: 1, isLiked: false, isSaved: true, createdAt: '2026-06-09T00:00:00.000Z', }, ], page: 1, limit: 20, total: 1, totalPages: 1, nextCursor: null, pagination: { hasNextPage: false }, }), }; const controller = createController(undefined, searchService); const result = await controller.search({ sub: 'viewer-1' } as any, { q: 'ناي', page: 1, limit: 20, }); expect(searchService.searchPosts).toHaveBeenCalledWith('viewer-1', { q: 'ناي', page: 1, limit: 20, type: 'posts', }); expect(result.items[0]).toMatchObject({ id: 'post-2', postType: 'image', displayUrl: '/uploads/ney.jpg', thumbnailUrl: '/uploads/ney.jpg', author: { id: 'user-2', username: 'ney_artist', }, engagement: { likesCount: 4, commentsCount: 1, }, isLiked: false, isSaved: true, }); }); });