Loopback-next: indexes wrong format in integration test

Created on 29 Apr 2019  路  6Comments  路  Source: strongloop/loopback-next

I've written an integration test for a function from a repository. I want to check if the model is created correctly but when i am calling "npm test" i am getting an error.
In the function i am accessing the index definition with "repository.modelClass.definition.settings.indexes.preisliste_bku".
When i start the app and debug to this point, the value of the index is an array of objects so that i can use the forEach loop.

The index definition in the "Preisliste"-model:
image

The array of objects:
image

But when i am calling the function from the test i am getting the error because "bku.keys" is not an array of objects but an object so the forEach loop does not work.

The format of bku.keys in the test:
image

I do not understand why the format is diffrent when i start the app and when i am running the test.

Hope the information are sufficient. Thank you guys for any response.

question

All 6 comments

What connector are you using? It's difficult to answer your question without an application we could use to reproduce the problem ourselves. Please create a small app per our bug reporting instructions.

I've created a little app (with postgres-connector in todo-example) for you to understand my problem:
https://github.com/nike171196/loopback-next/tree/wrong-index-format

Steps to reproduce:

  1. Open the API-explorer and call the action "/todos/index" from the todo.controller. The return value is in format array of objects. This is what i except from the test too.
  1. Run "npm test". In the test i wrote, the same function (getModelIndex()) is called like in the controller but the return value is not the same.

I hope this helps you to understand what i am talking about.

I am afraid I am not able to run your application because I automigration does not work and thus I don't have any way how to create necessary database schemas :(

However, I see a problem in your test:

https://github.com/nike171196/loopback-next/blob/e95d46c2728b125eae887a646a24156346a5cac7/examples/todo/src/__tests__/integration/repositories/todo.repository.integration.ts#L11-L13

    const index = repository.getModelIndex();
    console.log(index);
    expect(index).to.be.type('object[]', 'Should be type array of objects.');

type assertion (docs) is accepting one of string values that typeof operator returns (see their list e.g. here). object[] is not a valid typeof value.

In JavaScript, Arrays are considered as objects.

expect(index).to.be.type('object');

You can use instanceof operator to verify that the value is an instance of Array:

expect(index).to.be.instanceof(Array);

Another problematic part I noticed: your application is loading & binding BaseRepository as if it was a repository bound to a model. That's why the migration script fails with the following error:

Cannot resolve injected arguments for BaseRepository.[0]: The arguments[0] is not decorated for dependency injection, but a value is not supplied

The solution I recommended in the past is to move generic repository classes to a different location where @loopback/boot is not going to pick them up. For example, src/base-repositories/base.repository.ts You will need to run npm run clean to remove the base repository from dist too.


With that change in place, I managed to automigrate the database and run the test suite. AFAICT, this is the value returned by getModelIndex method:

{
  todo_bku: { keys: { title: 1, desc: 1 }, options: { unique: true } }
}

The value look reasonable to me it's a key-value map where the key is the index name and the value is an object describing (defining) the index. What makes you expect an array value instead?

I was relatively recently looking into foreign keys and (unique) indexes in https://github.com/strongloop/loopback-next/pull/2712, I described the currently available syntax in this document. For the future, I proposed a slightly improved syntax, see https://github.com/strongloop/loopback-next/issues/2766.

Open the API-explorer and call the action "/todos/index" from the todo.controller. The return value is in format array of objects. This is what i except from the test too.

I see an object, not an array.

Screen Shot 2019-06-04 at 15 11 10

Another problematic part I noticed: your application is loading & binding BaseRepository as if it was a repository bound to a model. That's why the migration script fails with the following error:

Cannot resolve injected arguments for BaseRepository.[0]: The arguments[0] is not decorated for dependency injection, but a value is not supplied

The solution I recommended in the past is to move generic repository classes to a different location where @loopback/boot is not going to pick them up. For example, src/base-repositories/base.repository.ts You will need to run npm run clean to remove the base repository from dist too.

I believe the above must be documented somewhere in repositories docs. I was struggling with migration for the past 3 days and finally stumbled upon this message. Priceless!

Thank you so much @bajtos

Was this page helpful?
0 / 5 - 0 ratings

Related issues

teambitcodeGIT picture teambitcodeGIT  路  3Comments

kesavkolla picture kesavkolla  路  3Comments

half-blood-programmer picture half-blood-programmer  路  3Comments

dericgw picture dericgw  路  3Comments

shadyanwar picture shadyanwar  路  3Comments