Skip to content

Commit 7d6512f

Browse files
committed
refactor: enhance SongController tests to cover new song retrieval features including recent, featured, categories, and random songs
1 parent dcf0f55 commit 7d6512f

File tree

1 file changed

+110
-8
lines changed

1 file changed

+110
-8
lines changed

apps/backend/src/song/song.controller.spec.ts

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import type { UserDocument } from '@nbw/database';
2-
import {
3-
PageQueryDTO,
4-
SongPreviewDto,
5-
SongViewDto,
6-
UploadSongDto,
7-
UploadSongResponseDto,
8-
} from '@nbw/database';
2+
import { PageQueryDTO, SongPreviewDto, SongViewDto, UploadSongDto, UploadSongResponseDto,} from '@nbw/database';
93
import { HttpStatus, UnauthorizedException } from '@nestjs/common';
104
import { AuthGuard } from '@nestjs/passport';
115
import { Test, TestingModule } from '@nestjs/testing';
126
import { Response } from 'express';
137

14-
import { FileService } from '@server/file/file.service';
8+
import { FileService } from '../file/file.service';
159

10+
import { SongBrowserService } from './song-browser/song-browser.service';
1611
import { SongController } from './song.controller';
1712
import { SongService } from './song.service';
1813

1914
const mockSongService = {
2015
getSongByPage: jest.fn(),
16+
searchSongs: jest.fn(),
2117
getSong: jest.fn(),
2218
getSongEdit: jest.fn(),
2319
patchSong: jest.fn(),
@@ -28,9 +24,17 @@ const mockSongService = {
2824

2925
const mockFileService = {};
3026

27+
const mockSongBrowserService = {
28+
getRecentSongs: jest.fn(),
29+
getCategories: jest.fn(),
30+
getSongsByCategory: jest.fn(),
31+
getRandomSongs: jest.fn(),
32+
};
33+
3134
describe('SongController', () => {
3235
let songController: SongController;
3336
let songService: SongService;
37+
let songBrowserService: SongBrowserService;
3438

3539
beforeEach(async () => {
3640
const module: TestingModule = await Test.createTestingModule({
@@ -44,6 +48,10 @@ describe('SongController', () => {
4448
provide: FileService,
4549
useValue: mockFileService,
4650
},
51+
{
52+
provide: SongBrowserService,
53+
useValue: mockSongBrowserService,
54+
},
4755
],
4856
})
4957
.overrideGuard(AuthGuard('jwt-refresh'))
@@ -52,6 +60,10 @@ describe('SongController', () => {
5260

5361
songController = module.get<SongController>(SongController);
5462
songService = module.get<SongService>(SongService);
63+
songBrowserService = module.get<SongBrowserService>(SongBrowserService);
64+
65+
// Clear all mocks
66+
jest.clearAllMocks();
5567
});
5668

5769
it('should be defined', () => {
@@ -71,6 +83,96 @@ describe('SongController', () => {
7183
expect(songService.getSongByPage).toHaveBeenCalledWith(query);
7284
});
7385

86+
it('should handle featured songs', async () => {
87+
const query: PageQueryDTO = { page: 1, limit: 10 };
88+
const songList: SongPreviewDto[] = [];
89+
90+
mockSongBrowserService.getRecentSongs.mockResolvedValueOnce(songList);
91+
92+
const result = await songController.getSongList(query, 'featured');
93+
94+
expect(result).toEqual(songList);
95+
expect(mockSongBrowserService.getRecentSongs).toHaveBeenCalledWith(query);
96+
});
97+
98+
it('should handle recent songs', async () => {
99+
const query: PageQueryDTO = { page: 1, limit: 10 };
100+
const songList: SongPreviewDto[] = [];
101+
102+
mockSongBrowserService.getRecentSongs.mockResolvedValueOnce(songList);
103+
104+
const result = await songController.getSongList(query, 'recent');
105+
106+
expect(result).toEqual(songList);
107+
expect(mockSongBrowserService.getRecentSongs).toHaveBeenCalledWith(query);
108+
});
109+
110+
it('should return categories when q=categories without id', async () => {
111+
const query: PageQueryDTO = { page: 1, limit: 10 };
112+
const categories = { pop: 42, rock: 38 };
113+
114+
mockSongBrowserService.getCategories.mockResolvedValueOnce(categories);
115+
116+
const result = await songController.getSongList(query, 'categories');
117+
118+
expect(result).toEqual(categories);
119+
expect(mockSongBrowserService.getCategories).toHaveBeenCalled();
120+
});
121+
122+
it('should return songs by category when q=categories with id', async () => {
123+
const query: PageQueryDTO = { page: 1, limit: 10 };
124+
const songList: SongPreviewDto[] = [];
125+
const categoryId = 'pop';
126+
127+
mockSongBrowserService.getSongsByCategory.mockResolvedValueOnce(songList);
128+
129+
const result = await songController.getSongList(query, 'categories', categoryId);
130+
131+
expect(result).toEqual(songList);
132+
expect(mockSongBrowserService.getSongsByCategory).toHaveBeenCalledWith(categoryId, query);
133+
});
134+
135+
it('should return random songs', async () => {
136+
const query: PageQueryDTO = { page: 1, limit: 5 };
137+
const songList: SongPreviewDto[] = [];
138+
const category = 'electronic';
139+
140+
mockSongBrowserService.getRandomSongs.mockResolvedValueOnce(songList);
141+
142+
const result = await songController.getSongList(query, 'random', undefined, category);
143+
144+
expect(result).toEqual(songList);
145+
expect(mockSongBrowserService.getRandomSongs).toHaveBeenCalledWith(5, category);
146+
});
147+
148+
it('should throw error for invalid random count', async () => {
149+
const query: PageQueryDTO = { page: 1, limit: 15 }; // Invalid limit > 10
150+
151+
await expect(
152+
songController.getSongList(query, 'random')
153+
).rejects.toThrow('Invalid query parameters');
154+
});
155+
156+
it('should handle zero limit for random (uses default)', async () => {
157+
const query: PageQueryDTO = { page: 1, limit: 0 }; // limit 0 is falsy, so uses default
158+
const songList: SongPreviewDto[] = [];
159+
160+
mockSongBrowserService.getRandomSongs.mockResolvedValueOnce(songList);
161+
162+
const result = await songController.getSongList(query, 'random');
163+
164+
expect(result).toEqual(songList);
165+
expect(mockSongBrowserService.getRandomSongs).toHaveBeenCalledWith(0, undefined); // Passes 0 (nullish coalescing doesn't apply to 0)
166+
});
167+
168+
it('should throw error for invalid query mode', async () => {
169+
const query: PageQueryDTO = { page: 1, limit: 10 };
170+
171+
await expect(
172+
songController.getSongList(query, 'invalid' as any)
173+
).rejects.toThrow('Invalid query parameters');
174+
});
175+
74176
it('should handle errors', async () => {
75177
const query: PageQueryDTO = { page: 1, limit: 10 };
76178

0 commit comments

Comments
 (0)