@@ -204,6 +204,11 @@ describe('ReviewService.createReview authorization checks', () => {
204
204
} as any ;
205
205
206
206
prismaMock . review . create . mockResolvedValue ( reviewCreateResult ) ;
207
+ prismaMock . review . update . mockResolvedValue ( {
208
+ ...reviewCreateResult ,
209
+ initialScore : 0 ,
210
+ finalScore : 0 ,
211
+ } ) ;
207
212
208
213
await expect (
209
214
service . createReview ( baseAuthUser , request ) ,
@@ -263,6 +268,11 @@ describe('ReviewService.createReview authorization checks', () => {
263
268
] ) ;
264
269
265
270
prismaMock . review . create . mockResolvedValue ( reviewCreateResult ) ;
271
+ prismaMock . review . update . mockResolvedValue ( {
272
+ ...reviewCreateResult ,
273
+ initialScore : 0 ,
274
+ finalScore : 0 ,
275
+ } ) ;
266
276
267
277
await expect (
268
278
service . createReview ( baseAuthUser , request ) ,
@@ -1223,3 +1233,121 @@ describe('ReviewService.deleteReview', () => {
1223
1233
} ) ;
1224
1234
} ) ;
1225
1235
} ) ;
1236
+
1237
+ describe ( 'ReviewService.deleteReviewItem authorization checks' , ( ) => {
1238
+ const prismaMock = {
1239
+ reviewItem : {
1240
+ findUnique : jest . fn ( ) ,
1241
+ delete : jest . fn ( ) ,
1242
+ } ,
1243
+ } as unknown as any ;
1244
+
1245
+ const prismaErrorServiceMock = {
1246
+ handleError : jest . fn ( ( error : any ) => ( {
1247
+ message : error . message ,
1248
+ code : error . response ?. code ?? 'UNKNOWN' ,
1249
+ details : error . response ?. details ,
1250
+ } ) ) ,
1251
+ } as unknown as any ;
1252
+
1253
+ const resourceApiServiceMock = {
1254
+ getMemberResourcesRoles : jest . fn ( ) ,
1255
+ } as unknown as any ;
1256
+
1257
+ const challengeApiServiceMock = { } as unknown as any ;
1258
+
1259
+ const service = new ReviewService (
1260
+ prismaMock ,
1261
+ prismaErrorServiceMock ,
1262
+ resourceApiServiceMock ,
1263
+ challengeApiServiceMock ,
1264
+ ) ;
1265
+
1266
+ const reviewerUser : JwtUser = {
1267
+ userId : 'member-100' ,
1268
+ roles : [ UserRole . Reviewer ] ,
1269
+ isMachine : false ,
1270
+ } ;
1271
+
1272
+ const baseReviewItem = {
1273
+ id : 'item-1' ,
1274
+ reviewId : 'review-1' ,
1275
+ review : {
1276
+ id : 'review-1' ,
1277
+ resourceId : 'resource-1' ,
1278
+ submission : {
1279
+ challengeId : 'challenge-1' ,
1280
+ } ,
1281
+ } ,
1282
+ } as any ;
1283
+
1284
+ beforeEach ( ( ) => {
1285
+ jest . resetAllMocks ( ) ;
1286
+
1287
+ prismaMock . reviewItem . findUnique . mockResolvedValue ( baseReviewItem ) ;
1288
+ prismaMock . reviewItem . delete . mockResolvedValue ( undefined ) ;
1289
+
1290
+ jest
1291
+ . spyOn ( service as any , 'recomputeAndUpdateReviewScores' )
1292
+ . mockResolvedValue ( undefined ) ;
1293
+ } ) ;
1294
+
1295
+ afterEach ( ( ) => {
1296
+ jest . restoreAllMocks ( ) ;
1297
+ } ) ;
1298
+
1299
+ it ( 'blocks reviewers from deleting review items they do not own' , async ( ) => {
1300
+ resourceApiServiceMock . getMemberResourcesRoles . mockResolvedValue ( [
1301
+ {
1302
+ id : 'resource-1' ,
1303
+ memberId : 'someone-else' ,
1304
+ challengeId : 'challenge-1' ,
1305
+ memberHandle : 'otherHandle' ,
1306
+ roleId : 'role-reviewer' ,
1307
+ createdBy : 'system' ,
1308
+ created : new Date ( ) . toISOString ( ) ,
1309
+ roleName : 'Reviewer' ,
1310
+ } ,
1311
+ ] ) ;
1312
+
1313
+ await expect (
1314
+ service . deleteReviewItem ( reviewerUser , 'item-1' ) ,
1315
+ ) . rejects . toMatchObject ( {
1316
+ status : 403 ,
1317
+ response : expect . objectContaining ( {
1318
+ code : 'REVIEW_ITEM_DELETE_FORBIDDEN_NOT_OWNER' ,
1319
+ } ) ,
1320
+ } ) ;
1321
+
1322
+ expect ( prismaMock . reviewItem . delete ) . not . toHaveBeenCalled ( ) ;
1323
+ expect ( resourceApiServiceMock . getMemberResourcesRoles ) . toHaveBeenCalledWith (
1324
+ 'challenge-1' ,
1325
+ 'member-100' ,
1326
+ ) ;
1327
+ } ) ;
1328
+
1329
+ it ( 'allows reviewers to delete review items associated with their own review' , async ( ) => {
1330
+ resourceApiServiceMock . getMemberResourcesRoles . mockResolvedValue ( [
1331
+ {
1332
+ id : 'resource-1' ,
1333
+ memberId : 'member-100' ,
1334
+ challengeId : 'challenge-1' ,
1335
+ memberHandle : 'reviewerHandle' ,
1336
+ roleId : 'role-reviewer' ,
1337
+ createdBy : 'system' ,
1338
+ created : new Date ( ) . toISOString ( ) ,
1339
+ roleName : 'Reviewer' ,
1340
+ } ,
1341
+ ] ) ;
1342
+
1343
+ await expect (
1344
+ service . deleteReviewItem ( reviewerUser , 'item-1' ) ,
1345
+ ) . resolves . toMatchObject ( {
1346
+ message : 'Review item item-1 deleted successfully.' ,
1347
+ } ) ;
1348
+
1349
+ expect ( prismaMock . reviewItem . delete ) . toHaveBeenCalledWith ( {
1350
+ where : { id : 'item-1' } ,
1351
+ } ) ;
1352
+ } ) ;
1353
+ } ) ;
0 commit comments