Hope you figured it out by now, but if not...
for(let i=0; i<item.ratings.length; i++){
if(userId !== item.ratings[i].userId){
alert = false
item.ratings.push(ratingObject)
return
}
}
It's adding the rating if the userId doesn't match, but if it does, it will simply return. The issue is that there's already a userId in the ratings array, before you get to "kris" (userId "fg12cy"). So, it will add it every time because it sees it exists every time. You need to change this loop to look for the user, and track if it's found or not, and only if it's not found after getting out of the loop should you add it to the ratings array.
By the way, "alert" is a javascript function, so I would avoid using that as a variable name, unless you intend to override the javascript function. Also, the "return" in the for loop will return from the fat arrow function. Not sure if that's what you intended, or if you just wanted to exit the for loop early but stay in the fat arrow function. To exit a for loop early, use "break".
Here's code with a couple of adjustments:
function rateProduct (description, userId, rate){
let correctDescription = true
let ratingObject = {}
ratingObject.userId = userId
ratingObject.rate = rate
let found = false
products.forEach((item) => {
if(description === item.description){
correctDescription = true;
for(let i=0; i<item.ratings.length; i++){
if(userId === item.ratings[i].userId){
found = true
break
}
}
if (!found) {
item.ratings.push(ratingObject)
}
} else{
correctDescription = false
}
})
if(!correctDescription){
return "No product is found to be rated"
} else if(found) {
return "You've already rated this product"
}
return products
}
Hope this helps.