From 9d40f7cebce891027d12c1bc8e5e75fd78c0f323 Mon Sep 17 00:00:00 2001 From: Debi312 Date: Tue, 20 Aug 2024 08:19:34 +0200 Subject: [PATCH] add getPosts, getResults ans getRandomWorkout spec test in logic; fix validate errors #178 --- .../project/api/logic/createPost.js | 3 +- .../project/api/logic/createPost.spec.js | 4 +- .../project/api/logic/getPosts.js | 8 +- .../project/api/logic/getPosts.spec.js | 115 +++++++++++++ .../project/api/logic/getRandomWorkout.js | 2 +- .../api/logic/getRandomWorkout.spec.js | 152 ++++++++++++++++++ .../project/api/logic/getResults.js | 2 +- .../project/api/logic/getResults.spec.js | 106 ++++++++++++ staff/debora-garcia/project/api/package.json | 7 +- .../project/app/src/logic/createPost.js | 3 + staff/debora-garcia/project/com/validate.js | 7 +- 11 files changed, 393 insertions(+), 16 deletions(-) create mode 100644 staff/debora-garcia/project/api/logic/getPosts.spec.js create mode 100644 staff/debora-garcia/project/api/logic/getRandomWorkout.spec.js create mode 100644 staff/debora-garcia/project/api/logic/getResults.spec.js diff --git a/staff/debora-garcia/project/api/logic/createPost.js b/staff/debora-garcia/project/api/logic/createPost.js index 7cef32f95..388e537cb 100644 --- a/staff/debora-garcia/project/api/logic/createPost.js +++ b/staff/debora-garcia/project/api/logic/createPost.js @@ -6,7 +6,8 @@ import { NotFoundError, SystemError } from "com/errors.js" const createPost = (userId, workoutId, image, description, time, repetitions, weight) => { validate.id(userId, "userId") validate.id(workoutId, "workoutId") - validate.url(image, "image") + + validate.url(image, "image") validate.text(description, "description", 150) validate.number(time, "time") validate.number(repetitions, "repetitions") diff --git a/staff/debora-garcia/project/api/logic/createPost.spec.js b/staff/debora-garcia/project/api/logic/createPost.spec.js index a1aa16756..c15743590 100644 --- a/staff/debora-garcia/project/api/logic/createPost.spec.js +++ b/staff/debora-garcia/project/api/logic/createPost.spec.js @@ -12,9 +12,7 @@ const { MONGODB_URL_TEST } = process.env const { ObjectId } = Types describe("createPost", () => { - before(() => mongoose.connect(MONGODB_URL_TEST).then(() => { - return Promise.all([User.deleteMany(), Post.deleteMany(), Result.deleteMany()]) - })) + before(() => mongoose.connect(MONGODB_URL_TEST).then(() => Promise.all([User.deleteMany(), Post.deleteMany(), Result.deleteMany()]))) beforeEach(() => Promise.all([User.deleteMany(), Post.deleteMany(), Result.deleteMany()])) diff --git a/staff/debora-garcia/project/api/logic/getPosts.js b/staff/debora-garcia/project/api/logic/getPosts.js index b206ad415..c23a17319 100644 --- a/staff/debora-garcia/project/api/logic/getPosts.js +++ b/staff/debora-garcia/project/api/logic/getPosts.js @@ -3,9 +3,6 @@ import { SystemError, NotFoundError } from "com/errors.js" import validate from "com/validate.js" const getPosts = (userId) => { validate.id(userId, "userId") - // validate.number(time, "time") - // validate.number(repetitions, "repetitions") - // validate.number(weight, "weight") return User.findById(userId).lean() .catch(error => { throw new SystemError(error.message) }) @@ -24,6 +21,7 @@ const getPosts = (userId) => { .lean() .catch(error => { throw new SystemError(error.message) }) .then(posts => { + if (posts.length === 0) throw new NotFoundError("there are no posts yet") posts.forEach(post => { post.id = post._id.toString() @@ -48,8 +46,8 @@ const getPosts = (userId) => { } post.likes.map(userObjectId => userObjectId.toString()) - post.coments.map(userObjectId => userObjectId.toString()) - + //post.comments.map(userObjectId => userObjectId.toString()) + //TODO COMMENTS }) return (posts) diff --git a/staff/debora-garcia/project/api/logic/getPosts.spec.js b/staff/debora-garcia/project/api/logic/getPosts.spec.js new file mode 100644 index 000000000..b298f4ecc --- /dev/null +++ b/staff/debora-garcia/project/api/logic/getPosts.spec.js @@ -0,0 +1,115 @@ +import "dotenv/config" +import mongoose, { Types } from "mongoose" +import bcrypt from "bcryptjs" + +import getPosts from "./getPosts.js" +import { Post, Result, User, Workout } from "../data/index.js" +import { expect } from "chai" +import { ContentError, NotFoundError } from "com/errors.js" + +const { MONGODB_URL_TEST } = process.env +const { ObjectId } = Types + + +describe("getPosts", () => { + before(() => mongoose.connect(MONGODB_URL_TEST).then(() => Promise.all([User.deleteMany(), Post.deleteMany(), Result.deleteMany()]))) + + beforeEach(() => Promise.all([User.deleteMany(), Post.deleteMany(), Result.deleteMany()])) + + it("suceeds on getting all posts", () => + bcrypt.hash("1234", 8) + .then(hash => User.create({ + name: "nameTest", + surname: "surnameTest", + email: "test@gmail.com", + username: "usernameTest", + password: hash + })) + .then((user) => Workout.create({ + workoutType: "benchmark", + title: "Fran", + rounds: 10, + movements: [], + duration: 10, + description: "descriptionTest" + }) + .then((workout) => Result.create({ + workout: workout.id, + athlete: user.id, + time: 10, + repetitions: 10, + weight: 10 + }) + .then((result) => Post.create({ + author: user.id, + workout: workout.id, + result: result.id, + image: "http://test.com", + description: "descriptionTest", + time: 10, + repetitions: 10, + weight: 10, + likes: [], + comments: [] + }))) + .then(() => user) + ) + .then((user) => getPosts(user.id)) + .then(posts => { + expect(posts).to.be.an.instanceOf(Array) + expect(posts).to.have.lengthOf(1) + + expect(posts[0].author).to.be.an.instanceOf(Object) + expect(posts[0].image).to.equal("http://test.com") + expect(posts[0].workout).to.be.an.instanceOf(Object) + expect(posts[0].result).to.be.an.instanceOf(Object) + expect(posts[0].description).to.equal("descriptionTest") + + expect(posts[0].likes).to.be.an.instanceOf(Array) + expect(posts[0].comments).to.be.an.instanceOf(Array) + }) + ) + + it("fails on non-existing user", () => { + let errorThrown + + return getPosts(new ObjectId().toString()) + .catch(error => errorThrown = error) + .finally(() => { + expect(errorThrown).to.be.an.instanceOf(NotFoundError) + expect(errorThrown.message).to.be.equal("user not found") + }) + }) + + it("fails on non-existing post", () => { + let errorThrown + + return bcrypt.hash("1234", 8) + .then(hash => User.create({ + name: "nameTest", + surname: "surnameTest", + email: "test@gmail.com", + username: "usernameTest", + password: hash + })) + .then(user => getPosts(user.id)) + .catch(error => errorThrown = error) + .finally(() => { + expect(errorThrown).to.be.an.instanceOf(NotFoundError) + expect(errorThrown.message).to.be.equal("there are no posts yet") + }) + }) + + it("fails on invalid user id", () => { + let errorThrown + try { + getPosts(1234) + } catch (error) { + errorThrown = error + } finally { + expect(errorThrown).to.be.an.instanceof(ContentError) + expect(errorThrown.message).to.equal("userId is not valid") + } + }) + after(() => Promise.all([User.deleteMany(), Post.deleteMany()]).then(() => mongoose.disconnect())) +}) diff --git a/staff/debora-garcia/project/api/logic/getRandomWorkout.js b/staff/debora-garcia/project/api/logic/getRandomWorkout.js index ebfbb45df..f34aee15a 100644 --- a/staff/debora-garcia/project/api/logic/getRandomWorkout.js +++ b/staff/debora-garcia/project/api/logic/getRandomWorkout.js @@ -14,7 +14,7 @@ const getRandomWorkout = (userId, workoutType) => { return Workout.find({ workoutType }).select("-__v").populate("movements").lean() .catch(error => { throw new SystemError(error.message) }) .then(workouts => { - if (!workouts) throw new NotFoundError("workouts not found") + if (!workouts || workouts.length === 0) throw new NotFoundError("workouts not found") const randomNumber = Math.floor(Math.random() * workouts.length) diff --git a/staff/debora-garcia/project/api/logic/getRandomWorkout.spec.js b/staff/debora-garcia/project/api/logic/getRandomWorkout.spec.js new file mode 100644 index 000000000..869d38591 --- /dev/null +++ b/staff/debora-garcia/project/api/logic/getRandomWorkout.spec.js @@ -0,0 +1,152 @@ +import "dotenv/config" +import mongoose, { Types } from "mongoose" +import bcrypt from "bcryptjs" + +import getRandomWorkout from "./getRandomWorkout.js" +import { Post, Result, User, Workout } from "../data/index.js" +import { expect } from "chai" +import { ContentError, NotFoundError } from "com/errors.js" + +const { MONGODB_URL_TEST } = process.env +const { ObjectId } = Types + +describe("getRandomWorkout", () => { + before(() => mongoose.connect(MONGODB_URL_TEST).then(() => Promise.all([User.deleteMany(), Workout.deleteMany(), Result.deleteMany()]))) + + beforeEach(() => Promise.all([User.deleteMany(), Workout.deleteMany(), Result.deleteMany()])) + + it("succeeds on getting a random workout", () => { + let workoutType = "benchmark" + + return bcrypt.hash("1234", 8) + .then(hash => User.create({ + name: "nameTest", + surname: "surnameTest", + email: "test@gmail.com", + username: "usernameTest", + password: hash + })) + .then((user) => { + return Promise.all([Workout.create({ + workoutType: workoutType, + title: "Fran", + rounds: 10, + movements: [], + duration: 10, + description: "descriptionTest1" + }), + Workout.create({ + workoutType: workoutType, + title: "Murph", + rounds: 1, + movements: [], + duration: 60, + description: "descriptionTest2" + })]) + + .then(() => user) + }) + .then((user) => getRandomWorkout(user.id, workoutType)) + .then(workout => { + expect(workout.workoutType).to.be.equal(workoutType) + expect(workout.movements).to.be.an.instanceOf(Array) + expect(workout.description).to.be.an.string + if (workout.title === "Fran") { + expect(workout.rounds).to.be.equal(10) + expect(workout.duration).to.be.equal(10) + expect(workout.description).to.be.equal("descriptionTest1") + } else if (workout.title === "Murph") { + expect(workout.rounds).to.be.equal(1) + expect(workout.duration).to.be.equal(60) + expect(workout.description).to.be.equal("descriptionTest2") + } + }) + }) + + it("fails on non-existing user", () => { + let errorThrown + + return getRandomWorkout(new ObjectId().toString(), "benchmark") + .catch(error => errorThrown = error) + .finally(() => { + expect(errorThrown).to.be.an.instanceOf(NotFoundError) + expect(errorThrown.message).to.be.equal("user not found") + }) + }) + + it("fails on no workouts found for given workoutType", () => { + let errorThrown + + return bcrypt.hash("1234", 8) + .then(hash => User.create({ + name: "nameTest", + surname: "surnameTest", + email: "test@gmail.com", + username: "usernameTest", + password: hash + })) + .then((user) => getRandomWorkout(user.id, "for-time")) + .catch(error => errorThrown = error) + .finally(() => { + expect(errorThrown).to.be.an.instanceOf(NotFoundError) + expect(errorThrown.message).to.be.equal("workouts not found") + }) + + }) + + it("fails on generating random workout", () => { + let errorThrown + + return bcrypt.hash("1234", 8) + .then(hash => User.create({ + name: "nameTest", + surname: "surnameTest", + email: "test@gmail.com", + username: "usernameTest", + password: hash + })) + .then(user => Workout.create({ + workoutType: "benchmark", + title: "Fran", + rounds: 10, + movements: [], + duration: 10, + description: "descriptionTest" + }) + .then(() => Workout.deleteMany({ workoutType: "benchmark" })) + .then(() => getRandomWorkout(user.id, "benchmark")) + ) + .catch(error => errorThrown = error) + .finally(() => { + expect(errorThrown).to.be.an.instanceOf(NotFoundError) + expect(errorThrown.message).to.be.equal("workout not found") + }) + + }) + it("fails on invalid user id", () => { + let errorThrown + try { + getRandomWorkout(1234, "benchmark") + } catch (error) { + errorThrown = error + } finally { + expect(errorThrown).to.be.an.instanceof(ContentError) + expect(errorThrown.message).to.equal("userId is not valid") + } + }) + + it("fails on invalid workoutType", () => { + let errorThrown + try { + getRandomWorkout(new ObjectId().toString(), 1234) + } catch (error) { + errorThrown = error + } finally { + expect(errorThrown).to.be.an.instanceof(ContentError) + expect(errorThrown.message).to.equal("workoutType is not valid") + } + }) + + after(() => Promise.all([User.deleteMany(), Workout.deleteMany()]).then(() => mongoose.disconnect())) + +}) \ No newline at end of file diff --git a/staff/debora-garcia/project/api/logic/getResults.js b/staff/debora-garcia/project/api/logic/getResults.js index 30b131e03..c2be94bc4 100644 --- a/staff/debora-garcia/project/api/logic/getResults.js +++ b/staff/debora-garcia/project/api/logic/getResults.js @@ -17,7 +17,7 @@ const getResults = (userId) => { .lean() .catch(error => { throw new SystemError(error.message) }) .then(results => { - if (!results) throw new NotFoundError("you did't submit any result") + if (results.length === 0) throw new NotFoundError("you did't submit any result") results.forEach(result => { result.id = result._id.toString() delete result._id diff --git a/staff/debora-garcia/project/api/logic/getResults.spec.js b/staff/debora-garcia/project/api/logic/getResults.spec.js new file mode 100644 index 000000000..6e3d3a061 --- /dev/null +++ b/staff/debora-garcia/project/api/logic/getResults.spec.js @@ -0,0 +1,106 @@ +import "dotenv/config" +import mongoose, { Types } from "mongoose" +import bcrypt from "bcryptjs" + +import getResults from "./getResults.js" +import { Post, Result, User, Workout } from "../data/index.js" +import { expect } from "chai" +import { ContentError, NotFoundError } from "com/errors.js" + +const { MONGODB_URL_TEST } = process.env +const { ObjectId } = Types + +describe("getResults", () => { + before(() => mongoose.connect(MONGODB_URL_TEST).then(() => Promise.all([User.deleteMany(), Post.deleteMany(), Result.deleteMany()]))) + + beforeEach(() => Promise.all([User.deleteMany(), Post.deleteMany(), Result.deleteMany()])) + + it("succeds on getting all results", () => + bcrypt.hash("1234", 8) + .then(hash => User.create({ + name: "nameTest", + surname: "surnameTest", + email: "test@gmail.com", + username: "usernameTest", + password: hash + })) + .then(user => Workout.create({ + workoutType: "benchmark", + title: "Fran", + rounds: 10, + movements: [], + duration: 10, + description: "descriptionTest", + userId: user.id + }) + .then(workout => + Result.create({ + workout: workout.id, + athlete: user.id, + time: 10, + repetitions: 10, + weight: 10, + date: Date.now() + })) + .then(() => user) + ) + + .then(user => getResults(user.id)) + .then(results => { + expect(results).to.be.an.instanceOf(Array) + expect(results).to.have.lengthOf(1) + + expect(results[0].workout).to.be.an.instanceOf(Object) + expect(results[0].athlete).to.be.an.instanceOf(Object) + expect(results[0].time).to.be.equal(10) + expect(results[0].repetitions).to.be.equal(10) + expect(results[0].weight).to.be.equal(10) + expect(results[0].date).to.be.instanceOf(Date) + }) + ) + it("fails on non-existing user", () => { + let errorThrown + + return getResults(new ObjectId().toString()) + .catch(error => errorThrown = error) + .finally(() => { + expect(errorThrown).to.be.an.instanceOf(NotFoundError) + expect(errorThrown.message).to.equal("user not found") + }) + + }) + + it("fails on non-existing results", () => { + let errorThrown + + return bcrypt.hash("1234", 8) + .then(hash => User.create({ + name: "nameTest", + surname: "surnameTest", + email: "test@gmail.com", + username: "usernameTest", + password: hash + })) + .then(user => getResults(user.id)) + .catch(error => errorThrown = error) + .finally(() => { + expect(errorThrown).to.be.an.instanceOf(NotFoundError) + expect(errorThrown.message).to.equal("you did't submit any result") + }) + }) + + it("fails on invalid user id", () => { + let errorThrown + try { + getResults(1234) + } catch (error) { + errorThrown = error + } finally { + expect(errorThrown).to.be.an.instanceof(ContentError) + expect(errorThrown.message).to.equal("userId is not valid") + } + }) + + after(() => Post.deleteMany().then(() => User.deleteMany().then(() => Result.deleteMany().then(() => mongoose.disconnect())))) + +}) \ No newline at end of file diff --git a/staff/debora-garcia/project/api/package.json b/staff/debora-garcia/project/api/package.json index facae1c70..efcaebf6c 100644 --- a/staff/debora-garcia/project/api/package.json +++ b/staff/debora-garcia/project/api/package.json @@ -5,9 +5,12 @@ "type": "module", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", "start": "node --watch .", - "inspect": "node --inspect-brk ." + "inspect": "node --inspect-brk .", + "debug": "node --inspect-brk .", + "test": "mocha logic/*.spec.js", + "test-inspect": "mocha --inspect-brk logic/*.spec.js" + }, "keywords": [], "author": "", diff --git a/staff/debora-garcia/project/app/src/logic/createPost.js b/staff/debora-garcia/project/app/src/logic/createPost.js index edf53cd45..e6c274c11 100644 --- a/staff/debora-garcia/project/app/src/logic/createPost.js +++ b/staff/debora-garcia/project/app/src/logic/createPost.js @@ -4,6 +4,9 @@ import validate from "com/validate" const createPost = (workoutId, image, description, time, repetitions, weight) => { validate.url(image, "image") validate.text(description, "description", 150) + validate.number(time, "time") + validate.number(repetitions, "repetitions") + validate.number(weight, "weight") return fetch(`${import.meta.env.VITE_API_URL}/posts`, { method: "POST", diff --git a/staff/debora-garcia/project/com/validate.js b/staff/debora-garcia/project/com/validate.js index 33d0f06c8..b784a4e03 100644 --- a/staff/debora-garcia/project/com/validate.js +++ b/staff/debora-garcia/project/com/validate.js @@ -45,8 +45,9 @@ function validateText(text, explain = "text", maxLength = Infinity) { //en la validacion de imagen usamos uno generico de url function validateUrl(url, explain = "url") { - if (url && typeof url !== "string" || !url.startsWith("http")) - throw new ContentError(`${explain} is not valid`) + if (url && (typeof url !== "string" || !url.startsWith("http"))) { + throw new ContentError(`${explain} is not valid`); + } } function validateId(id, explain = "id") { @@ -59,7 +60,7 @@ function validateType(type, explain = "type") { } function validateNumber(number, explain = "number") { - if (number && typeof number !== "number") + if (number && (typeof number !== "number")) throw new ContentError(`${explain} is not valid`) }