Search code examples
ember.jsjson-apiember-cli-mirage

Ember-CLI-Mirage enforcing JSON:API?


Stumped on a couple failures and want to know if I'm understanding Mirage correctly:

1.In ember-cli-mirage, am I correct that the server response I define should reflect what my actual server is returning? For example:

this.get('/athletes', function(db, request) {
  let athletes = db.athletes || [];
  return {
    athletes: athletes,
    meta: { count: athletes.length }
  }
});

I am using custom serializers and the above matches the format of my server response for a get request on this route, however, on two tests I'm getting two failures with this error: normalizeResponse must return a valid JSON API document: meta must be an object

2.Is mirage enforcing the json:api format, and is it doing so because of the way I'm setting up the tests?

For example, I have several tests that visit the above /athletes route, yet my failures occur when I use an async call like below. I would love to know the appropriate way to correctly overwrite the server response behavior, as well as why the normalizeResponse error appears in the console for 2 tests but only causes the one below to fail.

test('contact params not sent with request after clicking .showglobal', function(assert) {
  assert.expect(2);
  let done = assert.async();
  server.createList('athlete', 10);

  //perform a search, which shows all 10 athletes
  visit('/athletes');
  fillIn('.search-inner input', "c");

  andThen(() => {
    server.get('/athletes', (db, request) => {
      assert.notOk(params.hasOwnProperty("contacts"));
      done();
    });

    //get global athletes, which I thought would now be intercepted by the server.get call defined within the andThen block
    click('button.showglobal');
  });
});

Result:

✘ Error: Assertion Failed: normalizeResponse must return a valid JSON API document:
    * meta must be an object
         expected true

I tried changing my server response to a json:api format as suggested in the last example here but this looks nothing like my actual server response and causes my tests to fail since my app doesn't parse a payload with this structure. Any tips or advice must appreciated.


Solution

    1. You are correct. Are the failures happening for the mock you've shown above? It looks to me like that would always return meta as an object, so verify the response is what you think it should be by looking in the console after the request is made.

      If you'd like to see responses during a test, enter server.logging = true in your test:

      test('I can view the photos', function() {
        server.logging = true;
        server.createList('photo', 10);
      
        visit('/');
      
        andThen(function() {
          equal( find('img').length, 10 );
        });
      });
      
    2. No, Mirage is agnostic about your particular backend, though it does come with some defaults. Again I would try enabling server.logging here to debug your tests.

      Also, when writing asserts against the mock server, define the route handlers at the beginning of the test, as shown in the example from the docs.