Skip to content

Commit

Permalink
add editUsername; add rateRecipe; add registerUser functionality with…
Browse files Browse the repository at this point in the history
… corresponding test. WIP b00tc4mp#180
  • Loading branch information
Ancog committed Aug 17, 2024
1 parent a97d4ab commit 9878744
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 15 deletions.
17 changes: 8 additions & 9 deletions staff/angel-patino/project/api/logic/editUsername.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { User } from '../data/index.js'
import validate from '../../com/validate.js'
import { DuplicityError, NotFoundError, SystemError } from '../../com/errors.js'
import validate from 'com/validate.js'
import { DuplicityError, NotFoundError, SystemError } from 'com/errors.js'


const editUsername = (userId, username) => {
Expand All @@ -11,21 +11,20 @@ const editUsername = (userId, username) => {
.catch(error => { throw new SystemError(error.message) })
.then(user => {
if (!user) {
throw new NotFoundError(error.message)
throw new NotFoundError('User not found')
}

return User.findOne({ username }).lean()
.catch(error => { throw new SystemError(error.message) })
})
.then(existUsername => {
if (!existUsername) {
return User.findByIdAndUpdate(userId, { username: username }, { new: true })
.catch(error => { throw new SystemError(error.message) })
}
else {
throw new DuplicityError('username already exists')
if (existUsername) {
throw new DuplicityError('Username already exist')
}
return User.findByIdAndUpdate(userId, { username }, { new: true })
.catch(error => { throw new SystemError(error.message) })
})

}

export default editUsername
115 changes: 115 additions & 0 deletions staff/angel-patino/project/api/logic/editUsername.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import 'dotenv/config'
import mongoose, { Types } from 'mongoose'
import bcrypt from 'bcryptjs'
import { expect } from 'chai'

import { User } from '../data/index.js'
import editUsername from './editUsername.js'
import { ContentError, DuplicityError, NotFoundError } from 'com/errors.js'

const { MONGODB_URL_TEST } = process.env

const { ObjectId } = Types
describe('editUsername', () => {
before(() => mongoose.connect(MONGODB_URL_TEST).then(() => User.deleteMany()))

beforeEach(() => User.deleteMany())

it('succeeds in changing the username for an existing user', () => {
return bcrypt.hash('12345678', 8)
.then(hash => User.create({
name: 'Master',
surname: 'Chef',
email: '[email protected]',
username: 'masterchef',
password: hash
}))
.then(() => editUsername(user._id.toString(), 'newusername'))
.then(updateUser => {
expect(updateUser).to.exist
expect(updateUser.username).to.equal('newusername')
})

})

it('fails when the user does not exist', () => {
let errorThrown

return editUsername(new ObjectId().toString(), 'newusername')
.catch(error => errorThrown)
.finally(() => {
expect(errorThrown).to.be.an.instanceOf(NotFoundError)
expect(errorThrown.message).to.equal('User not found')
})
})

it('fails when the user already exists', () => {
let errorThrown

return bcrypt.hash('12345678', 8)
.then(hash => Promise.all([
User.create({
name: 'Master',
surname: 'Chef',
email: '[email protected]',
username: 'masterchef',
password: hash
}),
User.create({
name: 'Maestro',
surname: 'Rata',
email: '[email protected]',
username: 'maestrorata',
password: hash
})
]))
.then(([user, existingUser]) => {
return editUsername(user._id.toString(), existingUser.username)
.catch(error => errorThrown = error)
})
.finally(() => {
expect(errorThrown).to.be.an.instanceOf(DuplicityError)
expect(errorThrown.message).to.equal('Username already exists')
})
})

it('fails with an invalid userId', () => {
let errorThrown

try {
editUsername('invalidUserId', 'username')

} catch (error) {
errorThrown = error
} finally {
expect(errorThrown).to.be.an.instanceOf(ContentError)
expect(errorThrown).to.equal('userId is not valid')
}
})

it('fails with an invalid username', () => {
let errorThrown

return bcrypt.hash('12345678', 8)
.then(hash => User.create({
name: 'Master',
surname: 'Chef',
email: '[email protected]',
username: 'masterchef',
password: hash
}))
.then(user => {
try {
return editUsername(user._id.toString(), '')
} catch (error) {
errorThrown = error
} finally {
expect(errorThrown).to.be.an.instanceOf(ContentError)
expect(errorThrown.message).to.equal('username is not valid')

}
})
})

after(() => User.deleteMany().then(() => mongoose.disconnect()))
})
6 changes: 3 additions & 3 deletions staff/angel-patino/project/api/logic/rateRecipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ import { NotFoundError, SystemError } from 'com/errors.js'
function rateRecipe(userId, recipeId, rating) {
validate.id(userId, 'userId')
validate.id(recipeId, 'recipeId')
validate.number(rating, 'rating', { min: 1, max: 5 })
validate.rating(rating, 'rating')

return User.findById(userId).lean()
.catch(error => { throw new SystemError(error.message) })
.then(user => {
if (!user)
throw new NotFoundError('user not found')
throw new NotFoundError('User not found')

return Recipe.findById(recipeId)
.catch(error => { throw new SystemError(error.message) })
.then(recipe => {
if (!recipe)
throw new NotFoundError('user not found')
throw new NotFoundError('Recipe not found')

const userRating = recipe.rating.find(r => r.user.toString() === userId)

Expand Down
147 changes: 147 additions & 0 deletions staff/angel-patino/project/api/logic/rateRecipe.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import 'dotenv/config'
import mongoose, { Types } from 'mongoose'
import bcrypt from 'bcryptjs'
import { expect } from 'chai'

import { User, Recipe } from '../data/index.js'
import rateRecipe from './rateRecipe.js'
import { NotFoundError } from 'com/errors.js'

const { MONGODB_URL_TEST } = process.env

const { ObjectId } = Types



describe('rateRecipe', () => {
before(() => mongoose.connect(MONGODB_URL_TEST).then(() => Promise.all([User.deleteMany(), Recipe.deleteMany()])))

beforeEach(() => Promise.all([User.deleteMany(), Recipe.deleteMany()]))

it('succeeds in adding a new rating to a recipe', () => {
return bcrypt.hash('12345678', 8)
.then(hash => User.create({
name: 'mocha',
surname: 'chai',
email: '[email protected]',
username: 'mochachai',
password: hash
}))
.then(user => Recipe.create({
author: user.id,
title: 'Tortela',
thumbnail: 'https://upload.wikimedia.org/wikipedia/commons/5/5b/Tortilla-de-patatas.jpg',
cookTime: 55,
ingredients: [{ name: 'huevos', quantity: 2, unit: 'ml' }],
description: 'mix',
rating: []
}).then(recipe => ({ user, recipe })))
.then(({ user, recipe }) => rateRecipe(user._id.toString(), recipe._id.toString(), 4))
.then(() => Recipe.findById(recipe._id))
.then(updateRecipe => {
expect(updateRecipe.ratings).to.have.lengthOf(1)
expect(updateRecipe.ratings[0].value).to.equal(4)
expect(updateRecipe.ratings[0].user.toString()).to.equal(user._id.toString())
})
})

it('succeeds in updating an existing rating for a recipe', () => {
return bcrypt.hash('12345678', 8)
.then(hash => User.create({
name: 'mocha',
surname: 'chai',
email: '[email protected]',
username: 'mochachai',
password: hash
}))
.then(user => Recipe.create({
author: user.id,
title: 'Tortela',
thumbnail: 'https://upload.wikimedia.org/wikipedia/commons/5/5b/Tortilla-de-patatas.jpg',
cookTime: 55,
ingredients: [{ name: 'huevos', quantity: 2, unit: 'ml' }],
description: 'mix',
rating: [{ user: user._id, value: 3 }]
}).then(({ user, recipe }) => rateRecipe(user._id.toString(), recipe._id.toString(), 5))
.then(() => Recipe.findById(recipe._id))
.then(updateRecipe => {
expect(updateRecipe.ratings).to.have.lengthOf(1)
expect(updateRecipe.ratings[0].value).to.equal(5)
expect(updateRecipe.ratings[0].user.toString()).to.equal(user._id.toString())
})
)
})

it('fails whent the user does not exist', () => {
let errorThrown

return Recipe.create({
author: new ObjectId(),
title: 'Test',
thumbnail: 'https://upload.wikimedia.org/wikipedia/commons/5/5b/Tortilla-de-patatas.jpg',
cookTime: 30,
ingredients: [{ name: 'salt', quantity: 1, unit: 'tsp' }],
description: 'A test'
})
.then(recipe => rateRecipe(new ObjectId().toString(), recipe._id.toString(), 4))
.catch(error => errorThrown = error)
.finally(() => {
expect(errorThrown).to.be.an.instanceOf(NotFoundError)
expect(errorThrown.message).to.equal('User not found')
})
})

it('fails when the recipe does not exist', () => {
let errorThrown

return bcrypt.hash('12345678', 8)
.then(hash => User.create({
name: 'mocha',
surname: 'chai',
email: '[email protected]',
username: 'mochachai',
password: hash
}))
.then(user => rateRecipe(user._id.toString(), new ObjectId().toString(), 4))
.catch(error => errorThrown = error)
.finally(() => {
expect(errorThrown).to.be.an.instanceOf(NotFoundError)
expect(errorThrown).to.equal('Recipe nor found')
})
})

it('fails with an invalid rating', () => {
let errorThrown

return bcrypt.hash('12345678', 8)
.then(hash => User.create({
name: 'mocha',
surname: 'chai',
email: '[email protected]',
username: 'mochachai',
password: hash
}))
.then(user => Recipe.create({
author: user._id,
title: 'Test',
thumbnail: 'https://upload.wikimedia.org/wikipedia/commons/5/5b/Tortilla-de-patatas.jpg',
cookTime: 30,
ingredients: [{ name: 'salt', quantity: 1, unit: 'tsp' }],
description: 'A test'
}).then(recipe => ({ user, recipe })))
.then(({ user, recipe }) => {
try {
rateRecipe(user._id.toString(), recipe._id.toString(), 6)
} catch (error) {
errorThrown = error
} finally {
expect(errorThrown).to.be.an.instanceOf(ContentError)
expect(errorThrown.message).to.equal('rating is not valid. It must be a number between 1 and 5.')
}
})
})



after(() => Promise.all([User.deleteMany(), Recipe.deleteMany()]).then(() => mongoose.disconnect()))
})
4 changes: 2 additions & 2 deletions staff/angel-patino/project/api/logic/registerUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const registerUser = (name, surname, email, username, password, passwordRepeat)
.catch(error => { throw new SystemError(error.message) })
.then(user => {
if (user)
throw new DuplicityError('user already exists')
//introducimos usuario
throw new DuplicityError('User already exists')

return bcrypt.hash(password, 8)
.catch(error => { throw new SystemError(error.message) })
.then(hash => {
Expand Down
Loading

0 comments on commit 9878744

Please sign in to comment.