Hello there
Hope you guys doing well.
So, I’m having trouble with the third unit test in the ‘Exercise Tracker’ project of the APIs and Microservices course:
Blockquote You can
POST
to/api/users/:_id/exercises
with form datadescription
,duration
, and optionallydate
. If no date is supplied, the current date will be used. The response returned will be the user object with the exercise fields added.
Here is my code:
const express = require('express')
const app = express()
const cors = require('cors')
const bodyParser = require('body-parser')
const mongoose = require('mongoose');
const moment = require('moment');
require('dotenv').config()
app.use(cors())
app.use(express.static('public'))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/views/index.html')
});
//--- Database modelling
// creating docuemnt and model
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('Successfully connected to Mongo db')
});
let UserSchema = new mongoose.Schema({
username: String,
description: String,
duration: Number,
date: Date
});
let User = mongoose.model('User', UserSchema);
//---
//--- Other functions
function isValidDate(d) {
return d instanceof Date && !isNaN(d);
}
//---
//--- DB access methods
const createUser = (usernameSubmited, done) => {
User.findOne({'username': usernameSubmited}, (err, data) => {
if (!data) {
data = new User({username: usernameSubmited});
data.save(function(err) {
if (err) done(err);
done(null, data);
});
} else if (err) {
done(err);
} else {
done(null, 'Username already taken')
}
});
};
const findUserAndAddExercise = (submitedUID, exercise, done) => {
User.findById(submitedUID, function (err, data) {
console.log('FindById: below is the user data');
console.log(data);
if (!data) {
done(null, 'User Id is not found')
} else if (exercise.description == '') {
done(null, 'Exercise description is required')
} else if (exercise.duration == '') {
done(null, 'Exercise duration is required')
} else if (isNaN(exercise.duration)) {
done(null, 'Exercise duration should be a numerical value')
} else if (!isValidDate(exercise.date)) {
done(null, 'Entered date is not valid')
} else if (err) {
done(err);
} else {
console.log('New exercise was added to the DB\n');
data.description = exercise.description;
data.duration = exercise.duration;
data.date = exercise.date.toDateString();
data.save(function (err, data) {
if (err) return console.error(err);
done(null,data);
});
}
});
};
//---
//--- Routes
// body parser middleware
app.use('/', (req, res, next) => {
console.log(req.method + ' ' + req.path + ' - ' + req.ip);
next();
}, bodyParser.urlencoded({extended: false}) );
// get vector of all users
app.get('/api/users',function(req,res)
{
User.find(function (err, data) {
if (err) return console.error(err);
res.json(data);
});
});
// submit a new username
app.post('/api/users', (req, res) =>
{
createUser(req.body.username, (err, data) =>
{
if(err) {
console.log('Error occured: ' + err + '\n')
res.send(err);
} else if (data == 'Username already taken') {
console.log('Error occured: ' + data + '\n')
res.send(data);
} else {
console.log('\nNEWLY-CREATED USER ID: ' + data._id)
res.json({'username': data.username, '_id': data._id});
}
});
});
// submit new exercise data
app.post('/api/users/:_id/exercises', (req, res) =>
{
let dateToSet = new Date();
if (req.body.date != ''){
dateToSet = new Date(req.body.date);
}
// initialize data to save in DB
uid = req.body[':_id'];
exerciseToAdd = {
description: req.body.description,
duration: parseInt(req.body.duration),
date: dateToSet
}
// set Id route parameter
req.params._id = uid;
findUserAndAddExercise(uid, exerciseToAdd, (err, data) => {
if(err) {
console.log('Error occured: ' + err + '\n');
res.send(err);
} else if (data == 'User Id is not found'
|| data == 'Exercise description is required'
|| data == 'Exercise duration is required'
|| data == 'Exercise duration should be a numerical value'
|| data == 'Entered date is not valid') {
console.log('Error occured: ' + data + '\n');
res.send(data);
} else {
res.json({'_id': data._id, 'username': data.username, 'date': new Date(data.date).toDateString(), 'duration': data.duration, 'description': data.description});
}
});
});
//---
const listener = app.listen(process.env.PORT || 3000, () => {
console.log('Your app is listening on port ' + listener.address().port)
});
So, let’s created a new user and add a few exercise activities for this new user. I am doing it manually, and the console output is as follows:
NEWLY-CREATED USER ID: 60d794b4a93fa505205341b3
POST /api/users/60d794b4a93fa505205341b3/exercises - ::ffff:172.18.0.1
FindById: below is the user data
{ _id: 60d794b4a93fa505205341b3, username: 'Eliz', __v: 0 }
New exercise was added to the DB
POST /api/users/60d794b4a93fa505205341b3/exercises - ::ffff:172.18.0.1
FindById: below is the user data
{
_id: 60d794b4a93fa505205341b3,
username: 'Eliz',
__v: 0,
date: 2021-06-26T00:00:00.000Z,
description: 'Running',
duration: 15
}
New exercise was added to the DB
OK, that seems fine.
Now, when I fire the fcc unit tests, the console output is as follows:
NEWLY-CREATED USER ID: 60d79121a10ad00469ea8f4b
POST /api/users/60d79121a10ad00469ea8f4b/exercises - ::ffff:172.18.0.1
FindById: below is the user data
null
Error occured: User Id is not found
Here, we can see that the new user was created and should have been added to the DB. But then, when we try to find this user (using findById), there is no data (- null).
I’m kinda stuck for few days on this one. I think I have some sort of asynchronous bug in my code.
I’ll appreciate any advice you can give me on this issue or my code in general. Thank you!
I’m using replit (I’m unsure if you can access my project by this link): https://replit.com/@andreyxdd/boilerplate-project-exercisetracker#README.md
System details: Google Chrome Version 91.0.4472.114 (Official Build) (64-bit), Windows 10.