Exercise Tracker test 5,6

The exercise tracker test 5 and 6 keep failing
even though output matches what is expected when I test it.

test 5 expects a GET request to /api/users/:_id/logs will return a JSON object
that contains a ‘log’ property which is an array of objects that contain a date (date.toDateString format), a description (String), and a duration (Number).

Test 6 expects that that same route ( GET request to /api/users/:_id/logs ) return object will include a count (Number) property which correlates with the length of the log property.

When I test the route on my project it does meet the requirements of the tests. But when I submit the solution link to the challenge, it keeps failing test 5 and 6.

If someone can steer me in the right direction, I would appreciate it.

server.js

const express = require('express');
const app = express();
require('dotenv').config({ path: 'sample.env'})
const cors = require('cors')
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unique: true
  }
})

const User = mongoose.model('User', UserSchema);
const ExerciseSchema = new mongoose.Schema({
  user: {
    type: mongoose.ObjectId,
    ref: 'User',
    required: true
  },
  description: {
    type: String,
    required: true
  },
  duration: {
    type:Number,
    required:true
  },
  date: {
    type: Date,
    default: Date.now
  }
})

const Exercise = mongoose.model('Exercise', ExerciseSchema);

const rgx = {
  duration: /^\d+$/,
  date: /^\d{4}-\d{1,2}-\d{1,2}$/
}

app.use(cors())
app.use(express.urlencoded({ extended: true }))
app.use(express.static('public'))
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/views/index.html')
});

app.post('/api/users/:_id/exercises', async (req, res) => {
  let {description, duration, date } = req.body;
  const {_id} = req.params;
  try {
    if(!description){
      return res.send("Path 'description' is required.")
    } else if(!duration){
      return res.send("Path 'duration' is required.")
    } else if(!rgx.duration.test(duration)){
      return res.send("Path 'duration' is numbers only.")
    }
    let user = await User.findOne({ _id });
    if(!user){
      return res.send('User not found');
    }
    let obj = {
      user: _id,
      duration: duration,
      description
    }

    if(date != ''){
      obj.date = new Date(date);
    } 
    const exercise = await new Exercise(obj);
    await exercise.save();
    console.log(user.username + ' added a new exercise: ' + exercise.description)
    return res.json({
      _id,
      username: user.username,
      date: new Date(exercise.date).toDateString(),
      duration: exercise.duration,
      description: exercise.description
    })
  } catch (e) {
    return res.send(e);
  }
  return res.redirect('/')

})
app.post('/api/users', async (req, res) => {
  const { username } = req.body;
  if(!username){
    return res.send("Path 'username' is required.");
  }

  try{
    let user = await User.findOne({ username });
    if(user){
      return res.send('Username already taken.');
    }

    user = await new User({ username });
    await user.save();
    return res.json({ username, _id: user._id })

  } catch (e) {
    return res.send('Something went wrong');
  }
  return res.redirect('/');
})



app.get('/api/users/:_id/logs',async (req, res) => {
    const { to, limit, from } = req.query;
  try {
    User.findById(req.params._id, (async(err, user) => {
      if(!user) return res.json({
        count: 0,
        log:[]
      })
      if(err){
        return res.json({ error: err})
      }

      let log = await Exercise.find({ user: user._id }).select(['date', 'description', 'duration']);
      log = log.map(({
        description,
        duration,
        date
      }) => {
        return ({
          description,
          duration,
          date: new Date(date).toDateString()
        })
      })
      
      if(rgx.date.test(to)){
        log = log.filter(ex => {
          return Date.parse(ex.date) <= Date.parse(to)
        })
      }

      if(rgx.date.test(req.query.from)){
        log = log.filter(ex => {
          return Date.parse(ex.date) >= Date.parse(req.query.from)
        })
      }

      log = log.slice(0, parseInt(limit) || log.length)
      
      const response = {
            _id: user._id,
            username: user.username,
            count:log.length,
            log,
      }
          // console.log(response)
      return res.json(response)
      
    }))
  } catch(e) {
    console.log('assertion error',e)
  }
})

app.get('/api/users', async(req,res) => {
  const users = await User.find().select('_id username')
  return res.json(users)
})

const listener = app.listen(process.env.PORT || 3000, () => {
  console.log('Your app is listening on port ' + listener.address().port)
  mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true }).then(() => {
    console.log('database connected')
  })
})

Your project link(s)

solution: https://replit.com/@sammyl720/boilerplate-project-exercisetracker

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36

Challenge: Exercise Tracker

Link to the challenge:

I was waiting to see if someone would reply your post, because I couldn’t see anything wrong with your code. Your code looks okay to me. Not much of a suggestion, but one possible reason for test failure is somehow the size of the returned log is different from what they’re testing against. You’re pulling out the log and filtering inside your code. One thing you can try is to let mongodb do the filtering. This is a better approach anyway, especially when the difference between the log size and the size of result after filtering is huge, so you might want to give a try.

1 Like

Welcome there,

The tests seem to be misleading. This is what I notice:

  1. Your app always returns count: 0, and logs: [], from the tests

  2. Your app does not handle dates for the user/:id/exercise route correctly

if(date != ''){ // What else can date be?
  obj.date = new Date(date);
} 

Hope this helps

1 Like

Thanks, it finally passed after removing the following code

if(date != ''){ 
  obj.date = new Date(date);
} 
   

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.