@@ -292,82 +292,166 @@ describe('updateAchievementById', () => {
292292 updatedAt : new Date ( ) ,
293293 createdBy : { id : 'admin_123' , name : 'Admin' } ,
294294 updatedBy : null ,
295- members : [
296- {
297- member : {
298- id : 'user_1' ,
299- name : 'User One' ,
300- email : 'user1@example.com' ,
301- profilePhoto : null ,
302- } ,
303- } ,
304- ] ,
305- } ;
306-
307- const updatedAchievement = {
308- ...baseAchievement ,
309- title : 'Updated Title' ,
310- updatedById : 'admin_456' ,
311- updatedBy : {
312- id : 'admin_456' ,
313- name : 'Admin Two' ,
314- email : 'admin2@example.com' ,
315- } ,
316- imageUrl : 'https://example.com/uploaded/updated.png' ,
317- members : [
318- {
319- member : {
320- id : 'user_2' ,
321- name : 'User Two' ,
322- email : 'user2@example.com' ,
323- profilePhoto : null ,
324- } ,
325- } ,
326- ] ,
327- } ;
328-
329- const mockReq : any = {
330- params : { achievementId : '1' } ,
331- file : {
332- originalname : 'updated.png' ,
333- buffer : Buffer . from ( 'test-image' ) ,
334- } ,
335- body : {
336- achievementData : JSON . stringify ( {
337- title : 'Updated Title' ,
338- updatedById : 'admin_456' ,
339- memberIds : [ 'user_2' ] ,
340- } ) ,
341- } ,
295+ members : [ ] ,
342296 } ;
343297
344298 const mockRes : any = {
345299 status : jest . fn ( ) . mockReturnThis ( ) ,
346300 json : jest . fn ( ) ,
347301 } ;
348302
349- it ( 'should return 200 and updated achievement' , async ( ) => {
350- mockedUploadImage . mockResolvedValue ( 'https://example.com/uploaded/updated.png' ) ;
303+ beforeEach ( ( ) => {
304+ jest . clearAllMocks ( ) ;
305+ } ) ;
306+
307+ it ( 'should update all fields successfully (200)' , async ( ) => {
308+ const updatedAchievement = { ...baseAchievement , title : 'Updated' , updatedById : 'admin_456' } ;
309+ const mockReq : any = {
310+ params : { achievementId : '1' } ,
311+ file : { originalname : 'img.png' , buffer : Buffer . from ( '123' ) } ,
312+ body : {
313+ achievementData : JSON . stringify ( {
314+ title : 'Updated' ,
315+ updatedById : 'admin_456' ,
316+ memberIds : [ 'user_2' ] ,
317+ } ) ,
318+ } ,
319+ } ;
320+
321+ mockedUploadImage . mockResolvedValue ( 'https://updated.com/img.png' ) ;
351322 jest . spyOn ( achievementService , 'getAchievementById' ) . mockResolvedValue ( baseAchievement ) ;
352323 jest . spyOn ( achievementService , 'updateAchievementById' ) . mockResolvedValue ( updatedAchievement ) ;
353324 jest . spyOn ( achievementService , 'addMembersToAchievement' ) . mockResolvedValue ( undefined ) ;
354325
355326 await updateAchievementById ( mockReq , mockRes ) ;
356327
357328 expect ( mockedUploadImage ) . toHaveBeenCalled ( ) ;
358- expect ( achievementService . getAchievementById ) . toHaveBeenCalledWith ( 1 ) ;
359- expect ( achievementService . updateAchievementById ) . toHaveBeenCalledWith ( 1 , expect . objectContaining ( {
360- title : 'Updated Title' ,
361- updatedById : 'admin_456' ,
362- imageUrl : 'https://example.com/uploaded/updated.png' ,
363- } ) ) ;
364- expect ( achievementService . addMembersToAchievement ) . toHaveBeenCalledWith ( 1 , [ 'user_2' ] ) ;
365329 expect ( mockRes . status ) . toHaveBeenCalledWith ( 200 ) ;
366330 expect ( mockRes . json ) . toHaveBeenCalledWith ( {
367331 success : true ,
368332 data : updatedAchievement ,
369333 } ) ;
370334 } ) ;
335+
336+ it ( 'should update only title' , async ( ) => {
337+ const mockReq : any = {
338+ params : { achievementId : '1' } ,
339+ body : {
340+ achievementData : JSON . stringify ( { title : 'New Title' , updatedById : 'admin_456' } ) ,
341+ } ,
342+ } ;
343+
344+ jest . spyOn ( achievementService , 'getAchievementById' ) . mockResolvedValue ( baseAchievement ) ;
345+ jest . spyOn ( achievementService , 'updateAchievementById' ) . mockResolvedValue ( {
346+ ...baseAchievement ,
347+ title : 'New Title' ,
348+ } ) ;
349+
350+ await updateAchievementById ( mockReq , mockRes ) ;
351+ expect ( achievementService . updateAchievementById ) . toHaveBeenCalledWith ( 1 , expect . objectContaining ( {
352+ title : 'New Title' ,
353+ updatedById : 'admin_456' ,
354+ } ) ) ;
355+ } ) ;
356+
357+ it ( 'should update only image' , async ( ) => {
358+ const mockReq : any = {
359+ params : { achievementId : '1' } ,
360+ file : { originalname : 'img.png' , buffer : Buffer . from ( 'abc' ) } ,
361+ body : {
362+ achievementData : JSON . stringify ( { updatedById : 'admin_456' } ) ,
363+ } ,
364+ } ;
365+
366+ mockedUploadImage . mockResolvedValue ( 'https://updated.com/img.png' ) ;
367+ jest . spyOn ( achievementService , 'getAchievementById' ) . mockResolvedValue ( baseAchievement ) ;
368+ jest . spyOn ( achievementService , 'updateAchievementById' ) . mockResolvedValue ( {
369+ ...baseAchievement ,
370+ imageUrl : 'https://updated.com/img.png' ,
371+ updatedById : 'admin_456' ,
372+ } ) ;
373+
374+ await updateAchievementById ( mockReq , mockRes ) ;
375+ expect ( mockedUploadImage ) . toHaveBeenCalled ( ) ;
376+ } ) ;
377+
378+ it ( 'should update only memberIds' , async ( ) => {
379+ const mockReq : any = {
380+ params : { achievementId : '1' } ,
381+ body : {
382+ achievementData : JSON . stringify ( { updatedById : 'admin_456' , memberIds : [ 'user_3' ] } ) ,
383+ } ,
384+ } ;
385+
386+ jest . spyOn ( achievementService , 'getAchievementById' ) . mockResolvedValue ( baseAchievement ) ;
387+ jest . spyOn ( achievementService , 'updateAchievementById' ) . mockResolvedValue ( {
388+ ...baseAchievement ,
389+ updatedById : 'admin_456' ,
390+ } ) ;
391+ jest . spyOn ( achievementService , 'addMembersToAchievement' ) . mockResolvedValue ( undefined ) ;
392+
393+ await updateAchievementById ( mockReq , mockRes ) ;
394+ expect ( achievementService . addMembersToAchievement ) . toHaveBeenCalledWith ( 1 , [ 'user_3' ] ) ;
395+ } ) ;
396+
397+ it ( 'should return 400 if updatedById is missing' , async ( ) => {
398+ const mockReq : any = {
399+ params : { achievementId : '1' } ,
400+ body : {
401+ achievementData : JSON . stringify ( { title : 'No Updater' } ) ,
402+ } ,
403+ } ;
404+
405+ await expect ( updateAchievementById ( mockReq , mockRes ) ) . rejects . toThrow ( ApiError ) ;
406+ } ) ;
407+
408+ it ( 'should return 400 if achievementId is invalid' , async ( ) => {
409+ const mockReq : any = {
410+ params : { achievementId : 'abc' } ,
411+ body : {
412+ achievementData : JSON . stringify ( { title : 'Updated' , updatedById : 'admin_456' } ) ,
413+ } ,
414+ } ;
415+
416+ await expect ( updateAchievementById ( mockReq , mockRes ) ) . rejects . toThrow ( ApiError ) ;
417+ } ) ;
418+
419+ it ( 'should return 404 if achievement not found' , async ( ) => {
420+ const mockReq : any = {
421+ params : { achievementId : '999' } ,
422+ body : {
423+ achievementData : JSON . stringify ( { title : 'Missing' , updatedById : 'admin_456' } ) ,
424+ } ,
425+ } ;
426+
427+ jest . spyOn ( achievementService , 'getAchievementById' ) . mockResolvedValue ( null ) ;
428+
429+ await expect ( updateAchievementById ( mockReq , mockRes ) ) . rejects . toThrow ( ApiError ) ;
430+ } ) ;
431+
432+ it ( 'should return 400 if no fields are provided for update' , async ( ) => {
433+ const mockReq : any = {
434+ params : { achievementId : '1' } ,
435+ body : {
436+ achievementData : JSON . stringify ( { updatedById : 'admin_456' } ) ,
437+ } ,
438+ } ;
439+
440+ jest . spyOn ( achievementService , 'getAchievementById' ) . mockResolvedValue ( baseAchievement ) ;
441+
442+ await expect ( updateAchievementById ( mockReq , mockRes ) ) . rejects . toThrow ( ApiError ) ;
443+ } ) ;
444+
445+ it ( 'should return 400 if achievementData is invalid JSON' , async ( ) => {
446+ const mockReq : any = {
447+ params : { achievementId : '1' } ,
448+ body : {
449+ achievementData : '{ invalid JSON }' ,
450+ } ,
451+ } ;
452+
453+ await expect ( updateAchievementById ( mockReq , mockRes ) ) . rejects . toThrow ( ApiError ) ;
454+ } ) ;
371455} ) ;
372456
373457const mockedDeleteImage = deleteImage as jest . Mock ;
0 commit comments