Exercise Tracker Project - Oddly Unfulfilled User Story

Hello, everyone!
I’m currently working on APIs and Microservices Projects, more specifically on the Exercise Tracker project.

I’m having trouble with the specific user story below:

“I can add an exercise to any user by posting form data userId(_id), description, duration, and optionally date to /api/exercise/add. If no date supplied it will use current date. App will return the user object with the exercise fields added.”

If you go on my glitch project: https://cuddly-spotted-agustinia.glitch.me, you can see that the functionality is implemented, and it works!

I really appreciate any help you can provide.

Hello there,

A few users struggle with this project, because the instructions are not as specific as the tests. So, one useful thing you can do is have a look at the tests: https://github.com/freeCodeCamp/freeCodeCamp/blob/master/curriculum/challenges/english/05-apis-and-microservices/apis-and-microservices-projects/exercise-tracker.english.md

They are just written in JavaScript. So, have a look at what they are looking for.

Some things to look out for:

  • They are looking for duration to be a number
  • They are looking for _id to be specifically an IdObject (this was taught in the lessons)

Hope this helps

2 Likes

Thank you for the quick reply! I’ll take a look at the link you’ve shared :grin:

I’m sorry, but I looked at the link and I could not really understand much, to be honest.

I added some code to make sure that I am using ObjectId() from Schema.Types and Number() cast the duration. However, the test has failed again.

Is there a way I can run the test code so that I can have access to the log it creates?

If you develop freeCodeCamp locally, you can see the output: https://contribute.freecodecamp.org/#/how-to-setup-freecodecamp-locally

But, setting this up does take a lot of time and know-how. So, it would be easier to get to know the tests.

I can walk your though the tests, if you have anything specific you do not understand. Or, I can take a look at your code, tomorrow. So, if you are still stuck then, let me know.

What I’m really trying to find out is what are the expected values. I don’t see them being defined anywhere in this test, so that is preventing me from understanding what’s going on.

It would be great if you could take a look at my code then. I really appreciate you taking the time to help me out!

Well, let us look at the tests, as I think this would be most beneficial:

const res = await fetch(url + '/api/exercise/new-user', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: `username=fcc_test_${Date.now()}`.substr(0, 29)
      });

      if (res.ok) {
        const { _id, username } = await res.json(); // This is the response from your app
        // Now, using all the information provided, an expected object is created...
        const expected = {
          username,
          description: 'test',
          duration: 60,
          _id,
          date: 'Mon Jan 01 1990'
        };
  • A POST request is made to your app’s endpoint /api/exercise/new-user
  • In this POST, a username is passed: username=fcc_test_${Date.now()}.substr(0, 29)` (This is just a fancy way to ensure that every time a new user is posted, it has a different username, because the username is linked to the time of request)
  • An expected object gets created.
  • This has very little to do with the actual test, but is useful to use for testing
const addRes = await fetch(url + '/api/exercise/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `userId=${_id}&description=${expected.description}&duration=${expected.duration}&date=1990-01-01`
        });
  • A new POST request is made to the app endpoint: /api/exercise/add
  • The following arguments are passed in the request:
let body = {
  userId: _id,
  description: expected.description,
  duration: expected.duration,
  date: "1990-01-01"
}
  • The _id comes from this line above:
const { _id, username } = await res.json();

This is exactly the same as if you had made use of the UI to create a new-user:
image
Then, add an exercise:
image

Now:

if (addRes.ok) {
          const actual = await addRes.json();
          assert.deepEqual(actual, expected);
  • If the response returns an ok status, the actual user object is stored in the variable actual
  • actual is compared to the expected created earlier.

In summary:

  • New user created
  • expected values are based on this new user
  • An exercise is added to a user based on the _id
  • The returned (actual) user object is compared to the expected user object

Hope this helps

1 Like

Something that might be worth a try:

const {ObjectId} = require('mongodb');

I have no experience with const SchemaTypes = mongoose.Schema.Types;, but I know the above method to create an ObjectId works.

Just to help you debug, this is the expected user object in full:

const expected = {
  username: 'fcc_test_1596648410971', // Obviously the numbers change
  description: 'test',
  duration: 60,
  _id: 5f29cd9e782d5f13d127b456, // Must be of type 'ObjectId'
  date: 'Mon Jan 01 1990'
}
1 Like

Thank you sooo much!!! That was exactly it!

I somehow had missed this code excerpt, even after using ctrl+f:

const expected = {
          username,
          description: 'test',
          duration: 60,
          _id,
          date: 'Mon Jan 01 1990'
        };

And my const SchemaTypes = mongoose.Schema.Types; didn’t really work either .

Again, thank you so much for your time and help!! I truly appreciate it! :heart:

It helps, but in my situtaion,

const expected = {
  username: userData.username,
  description: exerciseData.description,
  duration: exerciseData.duration,
  _id: ObjectId(userData._id), // Must be of type 'ObjectId' - It helped here
  date:  moment(exerciseData.date).format("ddd MMM D YYYY") // 'Mon Jan 01 1990'
}

then I tried to change the moment().format() function to native Date().toDateString() function and it worked !

const expected = {
  username: userData.username,
  description: exerciseData.description,
  duration: exerciseData.duration,
  _id: ObjectId(userData._id),
  date:  new Date(exerciseData.date).toDateString() // 'Mon Jan 01 1990'
}

From the above, I came to know that FreeCodeCamp is dealing everything so simple with simple techniques :wink:
Hope it helps.