Define a route in Mirage config for 'queryRecord'

#1

I can’t figure out how to define a route in Mirage config.js file in the following situation:

  • I have address router defined as follows:
#router.js

Router.map(function() {
...
  this.route('address'); // it is not nested
...

In address.js route handler the model hook is defined as follows to hit /shops/:identifier/address end-point on the API backend side:

#routes/address.js

export default Route.extend(AuthenticatedRouteMixin, {
  currentShop: service(),

  model() {
    return this.store.queryRecord('address', { shop_identifier: this.get('currentShop.shop').get('identifier')});
  }

I tried to define address route in Mirage config/jsas follows:

this.get('/shops');
  this.get('/address', (schema, request) => {
    let shop = schema.shops.where(request.params.shop_identifier);
    return shop.address;
  });

but it fails when running the test. Whatever I try, when running acceptance/address-test.js, it fails with:

	
Mirage: Error: Your Ember app tried to GET '/shops/43544/address',
         but there was no route defined to handle this request.
         Define a route that matches this path in your
         mirage/config.js file. Did you forget to add your namespace?

Here is the test itself:

#tests/acceptance/address-test.js

import { module, test } from 'qunit';
import { visit, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { authenticateSession } from 'ember-simple-auth/test-support';
import setupMirageTest from 'ember-cli-mirage/test-support/setup-mirage';
import { setupWindowMock } from 'ember-window-mock';

module('Acceptance | Address', function(hooks) {
  setupWindowMock(hooks);
  setupApplicationTest(hooks);
  setupMirageTest(hooks);

  test('Authenticated users can visit /address', async function(assert) {
    let shop = server.create('shop');
    server.create('user', { shop });
    server.create('address', { shop });

    await authenticateSession({
      access_token: 'azerty',
      token_type: 'Bearer'
    });

    await visit('/address');
    assert.equal(currentURL(), '/address', 'user is on the Address page');
  });
});

What am I missing?

#2

I think you need to specify your Mirage route handler to be something like this:

this.get('/shops/:id/address', (schema, request) => {
    let shop = schema.shops.where(request.params.shop_identifier);
    return shop.address;
});
#3

@corrspt Thank you for your response. I applied the modification you suggested and got a different error:


Source: 	
Error: Ember Data Request GET /shops/92227/address returned a 500
Payload (application/json)
Mirage: Your GET handler for the url /shops/92227/address threw an error: 92227 is not a function

Why is 92227 not function ? It seems like there is something wrong with params names or values… The backend will extract the value shop_identifier from the request params to find a Shop by identifier. How Mirage should find a shop by identifier and not by ID in config.js?

#4

I figuredOut, here is the syntax that worked for me:

#mirage/config.js

this.get('/shops/:shop_identifier/address', (schema, request) => {
    let shop = schema.shops.findBy({ identifier: request.params.shop_identifier });
    return shop.address;
  });
```
I had to use `findBy` method to find the first `Shop`. Thank you!
#5

Hi @belgoros

The issue now is that your mirage handler is throwing an error. If you put a breakpoint (or drop a debuggerstatement inside the handler) you’ll probably be able to debug it.

I imagine it is due to schema.shops.where(request.params.shop_identifier) because the where of schema.schops expects an object with properties to filter by and you’re passing in the id of what you want to find. I think you’ll have to do: schema.shops.find(request.params.shop_identifier)

Mirage’s schema docs might help you here: https://www.ember-cli-mirage.com/docs/api/modules/ember-cli-mirage/orm/schema~Schema