Improve AI music and add music world explore
هذا الالتزام موجود في:
174
src/modules/music-world/music-world.controller.spec.ts
Normal file
174
src/modules/music-world/music-world.controller.spec.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
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,
|
||||
});
|
||||
});
|
||||
});
|
||||
المرجع في مشكلة جديدة
حظر مستخدم