server.get('api/employee's, function(schema, request) {
employee = schema.employee.find(1);
this.serializerOrRegistry.serialize(employee, request);
return foo;
});
As I was getting started with mirage, this was super helpful for debugging, but also, at this point I’m not sure how to include meta-data in the response, and one of our endpoints returns pagination in the meta key. What I did was generate the payload and then add meta manually.
this.get('api/employees', function(schema, request) {
let employees = schema.employee.all();
let response = this.serializerOrRegistry.serialize(employees, request);
response.meta = {
total: employees.length,
totalPages: 1
};
return new Mirage.Response(200, {}, response);
});
As I was moving away from a mix of Factory Guy and Pretender, we had a bunch of request where we were matching that it was “done” and then returning a new model.
// import the following from mirage
import BaseShorthandRouteHandler from 'ember-cli-mirage/route-handlers/shorthands/base';
server.post('/api/employees', function(schema, request) {
assert.ok(true, 'did post');
let handler = new BaseShorthandRouteHandler(schema, this.serializerOrRegistry);
return schema.employee.create(handler._getAttrsForRequest(request, 'employee'));
})
Let’s say you have the models “car” and “motorcycle” which inherit from “vehicle” and you want to return all available “vehicles” through the end-point `/api/vehicles`. The following can help you.
this.get('/api/vehicles', function(schema, request) {
// fetch all the cars, it returns a mirage collection
let collection = schema.car.all();
// push all the motorcycles into the mirage collection
collection.push(...schema.motorcycle.all());
// Make sure there is a serializer for vehicle `ember g mirage-serializer vehicle`
// since we are using JSONAPI, it will use the model.type to create the
// final response.
//
// This will probably work only with JSONAPI :P
collection.modelName = 'vehicle';
return collection;
});
server.delete('/api/employees/:id', function() {
return new Mirage.Response(204);
});
Sam recommends to let mirage shortcut do their job and then match against mirage’s DB. Let’s see an example.
andThen(function(){
server.patch('/api/employee/1', function(schema, request) {
var data = JSON.parse(request.requestBody).data;
assert.equal(data.attributes.name, 'Sam', 'name is Sam');
return new Mirage.Response(204);
});
});
click('thing that fires post');
The snippet above is removed letting mirage takes care of the patch via shortcuts.
andThen(function(){
assert.equal(
server.schema.employee.find(1).name,
'tom',
'Name is Tom'
);
});
click('thing that fires put');
andThen(function(){
assert.equal(
server.schema.employee.find(1).name,
'Sam',
'Name was updated to Sam'
);
});
Now we check against mirage’s db that it was updated.
There are scenarios where we might still need to intercept the request and do something inside of it, but for most of the cases we can let mirage do its magic.
Let’s say we still want to have assertions inside requests. It is common to see tests that depend on the API format, this can be really problematic if we decide to change the format of our API. suppose we are using AMS and have something like the following:
server.post('/api/employees', function(schema, request){
var employee = JSON.parse(request.requestBody).employee;
assert.equal(employee.name, 'Sam Selikoff', 'foo woot buu');
assert.equal(employee.phone_number, '+14159353143', 'number is persisted');
// ...
});
And then decide to move to JSON API.
server.post('/api/employees', function(schema, request){
var employee = JSON.parse(request.requestBody).data;
assert.equal(employee.attributes.name, 'Sam Selikoff', 'foo woot buu');
assert.equal(employee.attributes['phone-number'], '+14159353143', 'number is persisted');
// ...
});
But then realized everyone have been wrong and SOAP was actually what we needed. If you have only 1 tests then this is not a problem but if you have a lot of tests updating this is not a fun task.
Since mirage works with serializers, we can use that instead and then stop worrying about the format of the payload. The following can be used to achieve the same as the previous test, but this time is transparent to us if we are using JSON API, AMS or SOAP.
import BaseShorthandRouteHandler from 'ember-cli-mirage/route-handlers/shorthands/base';
server.post('/api/employees', function(schema, request){
let handler = new BaseShorthandRouteHandler(schema, this.serializerOrRegistry);
let employee = handler._getAttrsForRequest(request, 'employee');
// employee has been normalized to mirage's DB format.
assert.equal(employee.name, 'Sam Selikoff', 'foo woot buu');
assert.equal(employee.phoneNumber, '+14159353143', 'number is persisted');
// ...
});