udacity / cd2073-intro-to-js-1-project-starter

Starter code for the Intro to JavaScript I Project created by Rachel Manning
Other
12 stars 233 forks source link

The last Jest test always fails! Learn how to fix it. #14

Open julianovmartins opened 1 year ago

julianovmartins commented 1 year ago

This is just a minor bug in this project's repository. In time, Udacity will fix it.

There is a slight problem with the last Jest test (paying less than total works), as the variable (totalPaid) that holds the received cash and supports the pay() function is being initialized with the value (100000000000000) from the previous test.

If you want all ten tests to succeed, add two new lines of code in the: https://github.com/udacity/cd2073-intro-to-js-1-project-starter/blob/main/starter/tests/script.test.js#L74

To fix this, reset the loaded module and require it again in the last jest test:

test('pay less than the total works', () => {

        // reset the module
        jest.resetModules();

        // require it again
        const cart = require('../src/assets/script.js');

        cart.addProductToCart(product1.productId);
        cart.addProductToCart(product2.productId);
        expect(cart.pay(1)).toBeLessThan(grandTotal());
    });

Now if all your functions are correct, all Jest tests will pass!

sharynneazhar commented 1 year ago

As noted, the last jest test is failing as a side effect of the previous test. However, it may or may not be a bug. It may be a lack of test coverage. 🤔

I would say this could be a lesson for students to test for possible edge cases as best practice. The real issue is actually with the unit test pay more than the total works. Although it passes, there is a side effect from the code being incomplete that causes the next test to fail. Here’s the scenario causing the failure.

Let’s say you owe a grand total of $20 in your cart.

Now for some reason (maybe you’re a hacker trying to rob me lol),

That’s fine, but then you try again. You pay another $20… now you get $70?

How do we fix this? After users have paid off their cart and have no more remaining balance, we need to

  1. If your code has a variable that is used to keep track of the running total paid by the user, reset the total paid back to 0
  2. Empty the contents of the cart
julianovmartins commented 1 year ago

Yes, resetting the total paid back to 0 is a good way.


// Track the total paid
let totalPaid = 0;

function pay(amount) {

    // Add the current payment amount to the total paid variable
    ...

    // Calculate the difference between the total paid and the cartTotal
    ...

    // Check if the remaining amount is greater than or equal to zero
    if (remaining >= 0) {
        // If so, reset the `totalPaid` to zero to prepare it for the next
        // payment, as the current payment, is enough to cover the `cartTotal`.
        totalPaid = 0;
    }

    // Return the remaining (negative if payment is less than the cartTotal)
    return remaining;
}