0

Hey everyone I am trying to solve a problem statement using Javascript which has a simple button to add movie to favourites in its onclick. The function should throw a Promise.reject() if the movie has already been added once in the favourites.

So there are some test cases for this addFavourite() and some of the test cases are failing. Can you let me know why ? I can't change the test files so what should I change in my code to resolve the error ?

This is my addFavourite() function. (Note: allMovies is a list of all movie objects):

function addFavourite(searchId) {
  var favMovie = [];
  allMovies.forEach((iterator) => {
    if (iterator.id == searchId) {
      favMovie = iterator;
    }
  });
  var movieRepeated = false;
  allFavourites.forEach((iterator) => {
    if (iterator.id == favMovie.id) {
      movieRepeated = true;
    }
  });
  if (movieRepeated) {
    return Promise.reject(new Error("Movie repeated!")).then(
      resolved,
      rejected
    );
  } else {
    fetch("http://localhost:3000/favourites", {
      method: "POST",
      headers: {
        "content-type": "application/json",
      },
      body: JSON.stringify(favMovie),
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
      })
      .then((addedMovie) => {
        allFavourites.push(addedMovie);
        displayFavs(allFavourites);
        return allFavourites;
      });
  }
}


These are the testcases that are failing:

1.

it('adding of same movie as favourite twice shall be restricted', (done) => {
        fetchMock.get('http://localhost:3000/movies', moviesTestData);
        fetchMock.get('http://localhost:3000/favourites', favouritesTestData);
        fetchMock.post('http://localhost:3000/favourites', moviesTestData[0]);

        script.getMovies()
        .then(() => {
            return script.getFavourites();
        })
        .then(() => {
            return script.addFavourite(476307);
        })
        .catch((err) => {
            expect(err).to.not.equal(null, err);
            expect(err.message).to.equal('Movie is already added to favourites');
            done();
        });
    });

it(`addFavourites() shall hit the correct api with correct data and 
        return correct response`, (done) => {
            fetchMock.get('http://localhost:3000/movies', moviesTestData);
            fetchMock.get('http://localhost:3000/favourites', favouritesTestData);
            fetchMock.post('http://localhost:3000/favourites', moviesTestData[0]);

            script.getMovies()
            .then(() => {
                return script.getFavourites();
            })
            .then(() => {
                return script.addFavourite(476307);
            })
            .then((res) => {
                const lastCallArgs = fetchMock.lastCall();
                expect(lastCallArgs[0]).to.equal('http://localhost:3000/favourites');
                expect(lastCallArgs[1].method).to.equal('POST');
                expect(lastCallArgs[1].body).to.equal(JSON.stringify(moviesTestData[0]));
                favouritesTestData.push(moviesTestData[0]);
                expect(res).to.deep.equal(favouritesTestData);
                expect(document.getElementById('favouritesList').innerHTML)
                .to.include('The Unique Lama');
                done();
            })
            .catch((err) => {
                expect(err).to.equal(null, err);
                done();
            });
    });

Here is the error that I get:

addFavourites() shall hit the correct api with correct data and return correct response:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. 
      at listOnTimeout (internal/timers.js:554:17)
      at processTimers (internal/timers.js:497:7)
bijoy26
  • 133
  • 9
  • You are testing `== favMovie.id`, but `favMovie` is an array and has no `.id` property?! – Bergi Aug 01 '21 at 12:35
  • "*`.then(resolved, rejected)`*" - this smells like the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! And notice it returns a promise a that always fulfills, since `rejected` *handles* the error. – Bergi Aug 01 '21 at 12:36
  • You are missing a `return` in front of the `fetch(…).then(…);` promise chain. – Bergi Aug 01 '21 at 12:37
  • I initialised favMovie as an array [] by mistake! It's an obiect and is supposed to be {}. Once I traverse throught all the movies and finds the object with the same id, it stores the value of that object. – Divya Gahlot Aug 01 '21 at 13:33
  • 1
    Also, I think I need to understand first how promises work, and then I will be able to understand what is going on here! Thanks a lot though. – Divya Gahlot Aug 01 '21 at 13:35

1 Answers1

1

You probably need to call done() inside then bodies as well, because you are not returning a promise to the test runner.

starikcetin
  • 1,391
  • 1
  • 16
  • 24