@@ -31,6 +31,7 @@ const mockSongService = {
3131 getSongEdit : jest . fn ( ) ,
3232 patchSong : jest . fn ( ) ,
3333 getSongDownloadUrl : jest . fn ( ) ,
34+ getSongFileBuffer : jest . fn ( ) ,
3435 deleteSong : jest . fn ( ) ,
3536 uploadSong : jest . fn ( ) ,
3637 getRandomSongs : jest . fn ( ) ,
@@ -46,6 +47,9 @@ describe('SongController', () => {
4647 let songService : SongService ;
4748
4849 beforeEach ( async ( ) => {
50+ // Clear all mocks before each test
51+ jest . clearAllMocks ( ) ;
52+
4953 const module : TestingModule = await Test . createTestingModule ( {
5054 controllers : [ SongController ] ,
5155 providers : [
@@ -66,8 +70,8 @@ describe('SongController', () => {
6670 songController = module . get < SongController > ( SongController ) ;
6771 songService = module . get < SongService > ( SongService ) ;
6872
69- // Clear all mocks
70- jest . clearAllMocks ( ) ;
73+ // Verify the service is injected
74+ expect ( songController . songService ) . toBeDefined ( ) ;
7175 } ) ;
7276
7377 it ( 'should be defined' , ( ) => {
@@ -79,7 +83,12 @@ describe('SongController', () => {
7983 const query : SongListQueryDTO = { page : 1 , limit : 10 } ;
8084 const songList : SongPreviewDto [ ] = [ ] ;
8185
82- mockSongService . getSongByPage . mockResolvedValueOnce ( songList ) ;
86+ mockSongService . querySongs . mockResolvedValueOnce ( {
87+ content : songList ,
88+ page : 1 ,
89+ limit : 10 ,
90+ total : 0 ,
91+ } ) ;
8392
8493 const result = await songController . getSongList ( query ) ;
8594
@@ -88,7 +97,7 @@ describe('SongController', () => {
8897 expect ( result . page ) . toBe ( 1 ) ;
8998 expect ( result . limit ) . toBe ( 10 ) ;
9099 expect ( result . total ) . toBe ( 0 ) ;
91- expect ( songService . getSongByPage ) . toHaveBeenCalled ( ) ;
100+ expect ( songService . querySongs ) . toHaveBeenCalled ( ) ;
92101 } ) ;
93102
94103 it ( 'should handle search query' , async ( ) => {
@@ -357,7 +366,7 @@ describe('SongController', () => {
357366 it ( 'should handle errors' , async ( ) => {
358367 const query : SongListQueryDTO = { page : 1 , limit : 10 } ;
359368
360- mockSongService . getSongByPage . mockRejectedValueOnce ( new Error ( 'Error' ) ) ;
369+ mockSongService . querySongs . mockRejectedValueOnce ( new Error ( 'Error' ) ) ;
361370
362371 await expect ( songController . getSongList ( query ) ) . rejects . toThrow ( 'Error' ) ;
363372 } ) ;
@@ -437,7 +446,7 @@ describe('SongController', () => {
437446 expect ( result . total ) . toBe ( 5 ) ;
438447 expect ( result . page ) . toBe ( 1 ) ;
439448 expect ( result . limit ) . toBe ( 10 ) ;
440- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q , undefined ) ;
449+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q ?? '' ) ;
441450 } ) ;
442451
443452 it ( 'should handle search with empty query string' , async ( ) => {
@@ -457,7 +466,7 @@ describe('SongController', () => {
457466 expect ( result ) . toBeInstanceOf ( PageDto ) ;
458467 expect ( result . content ) . toEqual ( songList ) ;
459468 expect ( result . total ) . toBe ( 0 ) ;
460- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , '' , undefined ) ;
469+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , '' ) ;
461470 } ) ;
462471
463472 it ( 'should handle search with null query string' , async ( ) => {
@@ -476,7 +485,7 @@ describe('SongController', () => {
476485
477486 expect ( result ) . toBeInstanceOf ( PageDto ) ;
478487 expect ( result . content ) . toEqual ( songList ) ;
479- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , '' , undefined ) ;
488+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , '' ) ;
480489 } ) ;
481490
482491 it ( 'should handle search with multiple pages' , async ( ) => {
@@ -499,7 +508,7 @@ describe('SongController', () => {
499508 expect ( result . content ) . toHaveLength ( 10 ) ;
500509 expect ( result . total ) . toBe ( 25 ) ;
501510 expect ( result . page ) . toBe ( 2 ) ;
502- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q , undefined ) ;
511+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q ?? '' ) ;
503512 } ) ;
504513
505514 it ( 'should handle search with large result set' , async ( ) => {
@@ -521,7 +530,7 @@ describe('SongController', () => {
521530 expect ( result ) . toBeInstanceOf ( PageDto ) ;
522531 expect ( result . content ) . toHaveLength ( 50 ) ;
523532 expect ( result . total ) . toBe ( 500 ) ;
524- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q , undefined ) ;
533+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q ?? '' ) ;
525534 } ) ;
526535
527536 it ( 'should handle search on last page with partial results' , async ( ) => {
@@ -561,7 +570,7 @@ describe('SongController', () => {
561570 const result = await songController . searchSongs ( query , q ) ;
562571
563572 expect ( result ) . toBeInstanceOf ( PageDto ) ;
564- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q , undefined ) ;
573+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q ?? '' ) ;
565574 } ) ;
566575
567576 it ( 'should handle search with very long query string' , async ( ) => {
@@ -579,7 +588,7 @@ describe('SongController', () => {
579588 const result = await songController . searchSongs ( query , q ) ;
580589
581590 expect ( result ) . toBeInstanceOf ( PageDto ) ;
582- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q , undefined ) ;
591+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q ?? '' ) ;
583592 } ) ;
584593
585594 it ( 'should handle search with custom limit' , async ( ) => {
@@ -627,7 +636,7 @@ describe('SongController', () => {
627636
628637 expect ( result ) . toBeInstanceOf ( PageDto ) ;
629638 expect ( result . content ) . toHaveLength ( 10 ) ;
630- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q , undefined ) ;
639+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q ?? '' ) ;
631640 } ) ;
632641
633642 it ( 'should return correct pagination info with search results' , async ( ) => {
@@ -699,7 +708,7 @@ describe('SongController', () => {
699708 const result = await songController . searchSongs ( query , q ) ;
700709
701710 expect ( result ) . toBeInstanceOf ( PageDto ) ;
702- expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q , undefined ) ;
711+ expect ( songService . querySongs ) . toHaveBeenCalledWith ( query , q ?? '' ) ;
703712 } ) ;
704713 } ) ;
705714
@@ -803,23 +812,31 @@ describe('SongController', () => {
803812
804813 const res = {
805814 set : jest . fn ( ) ,
806- redirect : jest . fn ( ) ,
815+ send : jest . fn ( ) ,
807816 } as unknown as Response ;
808817
809- const url = 'test-url' ;
818+ const buffer = Buffer . from ( 'test-song-data' ) ;
819+ const filename = 'test-song.nbs' ;
810820
811- mockSongService . getSongDownloadUrl . mockResolvedValueOnce ( url ) ;
821+ mockSongService . getSongFileBuffer . mockResolvedValueOnce ( {
822+ buffer,
823+ filename,
824+ } ) ;
812825
813826 await songController . getSongFile ( id , src , user , res ) ;
814827
815828 expect ( res . set ) . toHaveBeenCalledWith ( {
816- 'Content-Disposition' : 'attachment; filename="song.nbs"' ,
829+ 'Content-Type' : 'application/octet-stream' ,
830+ 'Content-Disposition' : `attachment; filename="${ filename . replace (
831+ / [ / " ] / g,
832+ '_' ,
833+ ) } "`,
817834 'Access-Control-Expose-Headers' : 'Content-Disposition' ,
818835 } ) ;
819836
820- expect ( res . redirect ) . toHaveBeenCalledWith ( HttpStatus . FOUND , url ) ;
837+ expect ( res . send ) . toHaveBeenCalledWith ( Buffer . from ( buffer ) ) ;
821838
822- expect ( songService . getSongDownloadUrl ) . toHaveBeenCalledWith (
839+ expect ( songService . getSongFileBuffer ) . toHaveBeenCalledWith (
823840 id ,
824841 user ,
825842 src ,
@@ -836,16 +853,16 @@ describe('SongController', () => {
836853
837854 const res = {
838855 set : jest . fn ( ) ,
839- redirect : jest . fn ( ) ,
856+ send : jest . fn ( ) ,
840857 } as unknown as Response ;
841858
842- mockSongService . getSongDownloadUrl . mockRejectedValueOnce (
859+ mockSongService . getSongFileBuffer . mockRejectedValueOnce (
843860 new Error ( 'Error' ) ,
844861 ) ;
845862
846863 await expect (
847864 songController . getSongFile ( id , src , user , res ) ,
848- ) . rejects . toThrow ( 'Error ' ) ;
865+ ) . rejects . toThrow ( 'An error occurred while retrieving the song file ' ) ;
849866 } ) ;
850867 } ) ;
851868
0 commit comments