Ticket:Projection

i modified the moviesDAO.js and write the query but getting error but in mongo shell i am getting the desired output with same query.

● Projection › Can perform a country search for three countries
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

  12 |   })
  13 | 
> 14 |   test("Can perform a country search for three countries", async () => {
     |   ^
  15 |     const countriesList = ["Russia", "Japan", "Mexico"]
  16 |     const movies = await MoviesDAO.getMoviesByCountry(countriesList)
  17 |     expect(movies.length).toEqual(2788)

  at Spec (node_modules/jest-jasmine2/build/jasmine/Spec.js:85:20)
  at test (test/projection.test.js:14:3)
  at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
  at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
  at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)

Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 0 total
Time: 9.196s
OpenHandles` to troubleshoot this issue.
(node:10452) UnhandledPromiseRejectionWarning: TypeError: Cannot read property ‘addExpectationResult’ of undefined
(node:10452) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:10452) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
npm ERR! Test failed. See above for more details.

Hi @Adish_39279!

Can you show us how your method is implemented?

You mean the query that i have written?

Yeap! Your getMoviesByCountry’s implementation.

static async getMoviesByCountry(countries) {
/**
Ticket: Projection

Write a query that matches movies with the countries in the "countries"
list, but only returns the title and _id of each movie.

Remember that in MongoDB, the $in operator can be used with a list to
match one or more values of a specific field.
*/

let cursor
try {
  // TODO Ticket: Projection
  // Find movies matching the "countries" list, but only return the title
  // and _id. Do not put a limit in your own implementation, the limit
  // here is only included to avoid sending 46000 documents down the
  // wire.
  cursor = await movies.find(
    {
      "countries": {
        $in: countries,
      },
    },
    { title: 1 },
  )
} catch (e) {
  console.error(`Unable to issue find command, ${e}`)
  return []
}

return cursor.toArray()

}

Any idea what is the problem ?

Try increse the timeout like this:

beforeEach(() => {
    jest.setTimeout(10000);
  });

At the beginning of describe intruction. Before the tests.

you forget projection: before title

4 Likes

from where to increase timeout?

That’s not the problem

In the test spec file.

thanks for the help zuno and imareo

Did you fix the issue?

Yes the problem is solved

1 Like

Just to note that if encountering a message with jest.setTimeout errors, then rather than editing every test file in the beforeEach ( as has been suggested ) it would be far better practice to include a jest.setup.js file within the root level of the project and the:

jest.setTimeout(30000)

Or appropriate number as required.

Additionally make sure the general configuration is reading this by changing jest.config.js to:

module.exports = {
  globalSetup: "./test/config/setup.js",
  globalTeardown: "./test/config/teardown.js",
  testEnvironment: "./test/config/mongoEnvironment",
  setupTestFrameworkScriptFile: './jest.setup.js'        // additional line
}

Less typing or need to alter for every test, plus you really should not be editing the actual test files anyway. All that should be required here is the appropriate dao section changes.

More important Note

The more likely issue actually underlying long timeout issues would actually be that the returned resultset has more data than expected. This is actually part of the exercise.

So correcting with the actual API method you are meant to be implementing ( yes there is something different in the API docs as compared to the lesson material ) should actually correct such issues.

Therefore the need for actual timeout settings to be adjusted in tests may vary depending on region and available connection speed and latency. But it’s probably mostly related to the coding implementation you are meant to fix.

5 Likes

Hint : use projection

Instead of =>

cursor = await movies.find({ "countries": { $in: countries}}, { title: 1 } )

Try using the project keyword:

cursor = await movies.find({ countries: { $in: countries } }).project({ title: 1 })

5 Likes

There is an issue for the ticket. Test expects 2789 records but in DB I have only 2788. To pass test I had to edit expected value

You never never change a test case. They are there to ensure your code does the right thing. If you fail a test it is because your code is wrong. You have to fix your code. You do not edit the test to fit your code. If your code is wrong you won’t get the validation code for the ticket anyway. May be it is possible to bypass that too.

Any idea my code failed?
static async getMoviesByCountry(countries) {

/**
Ticket: Projection

Write a query that matches movies with the countries in the "countries"
list, but only returns the title and _id of each movie.

Remember that in MongoDB, the $in operator can be used with a list to
match one or more values of a specific field.
*/

let cursor
try {
  // TODO Ticket: Projection
  // Find movies matching the "countries" list, but only return the title
  // and _id. Do not put a limit in your own implementation, the limit
  // here is only included to avoid sending 46000 documents down the
  // wire.
  // cursor = await movies.find({country{$in:countries}},{title:1}).limit(1)
  cursor = await movies.find(
			{countries:{$in:[countries]}},
				{projection:{_id:1,title:1}}
			)
  expect(cursor).not.toBeNull()
  expect(Object.keys(cursor).length).toBe(2)
} catch (e) {
  console.error(`Unable to issue find command, ${e}`)
  return []
}

return cursor.toArray()

}