test(`it can serialize a collection with a chain of belongs-to relationships`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    comment: JsonApiSerializer.extend({
      relationships: ['post']
    }),
    post: JsonApiSerializer.extend({
      relationships: ['author']
    })
  });

  let comments = this.schema.comment.all();
  let result = registry.serialize(comments);

  assert.deepEqual(result, {
    data: [
      {
        type: 'comments',
        id: 1,
        attributes: {
          text: 'pwned'
        },
        relationships: {
          post: {
            data: {type: 'posts', id: 1}
          }
        }
      }
    ],
    included: [
      {
        type: 'posts',
        id: 1,
        attributes: {
          title: 'Lorem'
        },
        relationships: {
          author: {
            data: {type: 'authors', id: 1}
          }
        }
      },
      {
        type: 'authors',
        id: 1,
        attributes: {
          'first-name': 'Link'
        }
      }
    ]
  });
});
test(`it can use different attr whitelists for different serializers`, function(assert) {
  this.registry = new SerializerRegistry(this.schema, {
    wordSmith: JsonApiSerializer.extend({
      attrs: ['id', 'firstName'],
      include: ['blogPosts']
    }),
    blogPost: JsonApiSerializer.extend({
      attrs: ['id', 'title']
    })
  });
  let { schema } = this;
  let link = schema.wordSmith.create({ id: 1, firstName: 'Link', age: 123 });
  link.createBlogPost({ title: 'A whole new world' });

  let collection = this.schema.wordSmith.all();
  let result = this.registry.serialize(collection);

  assert.deepEqual(result, {
    data: [{
      type: 'word-smiths',
      id: '1',
      attributes: {
        'first-name': 'Link'
      },
      relationships: {
        'blog-posts': {
          data: [
            { type: 'blog-posts', id: '1' }
          ]
        }
      }
    }],
    included: [
      {
        'attributes': {
          'title': 'A whole new world'
        },
        'id': '1',
        'relationships': {
          'fine-comments': {
            'data': []
          },
          'word-smith': {
            'data': { type: 'word-smiths', id: '1' }
          }
        },
        'type': 'blog-posts'
      }
    ]
  });
});
test(`it returns only the whitelisted attrs when serializing a model`, function(assert) {
  this.registry = new SerializerRegistry(this.schema, {
    wordSmith: JsonApiSerializer.extend({
      attrs: ['id', 'firstName']
    })
  });
  let user = this.schema.wordSmith.create({
    id: 1,
    firstName: 'Link',
    age: 123
  });

  let result = this.registry.serialize(user);
  assert.deepEqual(result, {
    data: {
      type: 'word-smiths',
      id: '1',
      attributes: {
        'first-name': 'Link'
      },
      relationships: {
        'blog-posts': {
          data: []
        }
      }
    }
  });
});
test(`it gracefully handles null belongs-to relationship`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    blogPost: JsonApiSerializer.extend({
      include: ['wordSmith']
    })
  });

  this.schema.blogPosts.create({ title: 'Lorem3' });
  let blogPost = this.schema.blogPosts.find(3);
  let result = registry.serialize(blogPost);

  assert.deepEqual(result, {
    data: {
      type: 'blog-posts',
      id: '3',
      attributes: {
        title: 'Lorem3'
      },
      relationships: {
        'fine-comments': {
          data: []
        }
      }
    }
  });
});
test(`it can embed a belongs-to relationship`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    blogPost: JsonApiSerializer.extend({
      include: ['wordSmith']
    })
  });

  let blogPost = this.schema.blogPosts.find(1);
  let result = registry.serialize(blogPost);

  assert.deepEqual(result, {
    data: {
      type: 'blog-posts',
      id: '1',
      attributes: {
        title: 'Lorem'
      },
      relationships: {
        'fine-comments': {
          data: [
            {
              id: '1',
              type: 'fine-comments'
            }
          ]
        },
        'word-smith': {
          data: {
            id: '1',
            type: 'word-smiths'
          }
        }
      }
    },
    'included': [
      {
        attributes: {
          'first-name': 'Link'
        },
        id: '1',
        type: 'word-smiths',
        relationships: {
          'blog-posts': {
            data: [
              {
                id: '1',
                type: 'blog-posts'
              },
              {
                id: '2',
                type: 'blog-posts'
              }
            ]
          }
        }
      }
    ]
  });
});
test(`keyForAttribute formats the attributes of a model`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer.extend({
      keyForAttribute: underscore
    })
  });
  let wordSmith = this.schema.wordSmiths.create({
    id: 1,
    firstName: 'Link',
    lastName: 'Jackson',
    age: 323
  });

  let result = registry.serialize(wordSmith);

  assert.deepEqual(result, {
    data: {
      type: 'word-smiths',
      id: '1',
      attributes: {
        age: 323,
        first_name: 'Link',
        last_name: 'Jackson'
      },
      relationships: {
        'blog-posts': {
          data: []
        }
      }
    }
  });
});
test(`it can serialize a collection with a has-many relationship`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    author: JsonApiSerializer.extend({
      relationships: ['posts'],
    })
  });

  let authors = this.schema.author.all();
  let result = registry.serialize(authors);

  assert.deepEqual(result, {
    data: [
      {
        type: 'authors',
        id: 1,
        attributes: {
          'first-name': 'Link',
        },
        relationships: {
          posts: {
            data: [
              {type: 'posts', id: 1},
              {type: 'posts', id: 2},
            ]
          }
        }
      },
      {
        type: 'authors',
        id: 2,
        attributes: {
          'first-name': 'Zelda'
        },
        relationships: {
          posts: {
            data: []
          }
        }
      }
    ],
    included: [
      {
        type: 'posts',
        id: 1,
        attributes: {
          title: 'Lorem'
        }
      },
      {
        type: 'posts',
        id: 2,
        attributes: {
          title: 'Ipsum'
        }
      }
    ]
  });
});
test(`keyForRelationship works`, function(assert) {
  let ApplicationSerializer = JsonApiSerializer.extend({
    keyForRelationship: underscore
  });
  let registry = new SerializerRegistry(this.schema, {
    application: ApplicationSerializer,
    wordSmith: ApplicationSerializer.extend({
      include: ['blogPosts']
    })
  });
  let wordSmith = this.schema.wordSmiths.create({
    id: 1,
    firstName: 'Link',
    lastName: 'Jackson',
    age: 323
  });
  wordSmith.createBlogPost({ title: 'Lorem ipsum' });

  let result = registry.serialize(wordSmith);

  assert.deepEqual(result, {
    data: {
      type: 'word-smiths',
      id: '1',
      attributes: {
        age: 323,
        'first-name': 'Link',
        'last-name': 'Jackson'
      },
      relationships: {
        'blog_posts': {
          data: [
            { id: '1', type: 'blog-posts' }
          ]
        }
      }
    },
    included: [
      {
        attributes: {
          title: 'Lorem ipsum'
        },
        id: '1',
        relationships: {
          fine_comments: {
            data: []
          },
          word_smith: {
            data: {
              type: 'word-smiths',
              id: '1'
            }
          }
        },
        type: 'blog-posts'
      }
    ]
  });
});
test('_getRelationshipNames should not choke on missing request', function(assert) {
  let serializer = new (JsonApiSerializer.extend({
    include: ['foo', 'bar']
  }))();
  let result = serializer._getRelationshipNames();

  assert.deepEqual(result, ['foo', 'bar']);
});
Example #10
0
 beforeEach: function() {
   this.schema = schemaHelper.setup();
   this.registry = new SerializerRegistry(this.schema, {
     author: JsonApiSerializer.extend({
       attrs: ['id', 'firstName']
     })
   });
 },
test(`model: it can include relationships specified by a combination of the include query param (hasMany) and serializer.relationships (belongsTo, ignored)`, function(assert) {
  const registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    blogPost: JsonApiSerializer.extend({
      include: ['wordSmith']
    })
  });

  const post = this.schema.blogPost.find(1);
  const request = {
    queryParams: {
      include: 'fine-comments'
    }
  };
  const result = registry.serialize(post, request);

  assert.propEqual(result, {
    data: {
      type: 'blog-posts',
      id: '1',
      attributes: {},
      relationships: {
        'word-smith': {
          data: { type: 'word-smiths', id: '1' }
        },
        'fine-comments': {
          data: [
            { type: 'fine-comments', id: '1' },
            { type: 'fine-comments', id: '2' }
          ]
        }
      }
    },
    included: [
      {
        type: 'fine-comments',
        id: '1',
        attributes: {},
        relationships: {
          'blog-post': {
            data: { type: 'blog-posts', id: '1' }
          }
        }
      },
      {
        type: 'fine-comments',
        id: '2',
        attributes: {},
        relationships: {
          'blog-post': {
            data: { type: 'blog-posts', id: '1' }
          }
        }
      }
    ]
  });
});
test('_getRelationshipNames should not choke on empty queryParams', function(assert) {
  let serializer = new (JsonApiSerializer.extend({
    include: ['foo', 'bar']
  }))();
  let request = { queryParams: {} };

  let result = serializer._getRelationshipNames(request);

  assert.deepEqual(result, ['foo', 'bar']);
});
Example #13
0
test(`it can link to relationships, omitting 'data'`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    blogPost: JsonApiSerializer.extend({
      links(model) {
        return {
          'wordSmith': {
            related: `/api/word_smiths/${model.id}`,
            self: `/api/blog_posts/${model.id}/relationships/word_smith`
          },
          'fineComments': {
            related: `/api/fine_comments?blog_post_id=${model.id}`,
            self: `/api/blog_posts/${model.id}/relationships/fine_comments`
          }
        };
      }
    })
  });

  let wordSmith = this.schema.wordSmith.find(1);
  let blogPost = this.schema.blogPost.find(1);
  let result = registry.serialize(blogPost);

  assert.deepEqual(result, {
    data: {
      type: 'blog-posts',
      id: blogPost.id,
      attributes: {
        'title': 'Lorem',
      },
      relationships: {
        'word-smith': {
          links: {
            related: {
              href: `/api/word_smiths/${wordSmith.id}`
            },
            self: {
              href: `/api/blog_posts/${blogPost.id}/relationships/word_smith`
            }
          }
        },
        'fine-comments': {
          links: {
            related: {
              href: `/api/fine_comments?blog_post_id=${blogPost.id}`,
            },
            self: {
              href: `/api/blog_posts/${blogPost.id}/relationships/fine_comments`
            }
          }
        }
      }
    }
  });
});
test('_getRelationshipNames should not choke on missing serializer.relationships', function(assert) {
  let serializer = new (JsonApiSerializer.extend())();
  let request = {
    queryParams: {
      include: 'baz,quux'
    }
  };

  let result = serializer._getRelationshipNames(request);

  assert.deepEqual(result, ['baz', 'quux']);
});
test('_getRelationshipNames should prefer relationships from request', function(assert) {
  let serializer = new (JsonApiSerializer.extend({
    include: ['foo', 'bar']
  }))();

  let request = {
    queryParams: {
      include: 'baz,quux'
    }
  };
  let result = serializer._getRelationshipNames(request);

  assert.deepEqual(result, ['baz', 'quux']);
});
Example #16
0
test(`it can serialize a collection of models that have both belongs-to and has-many relationships`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    post: JsonApiSerializer.extend({
      relationships: ['author', 'comments']
    })
  });

  let post = this.schema.post.find(1);
  let result = registry.serialize(post);

  assert.deepEqual(result, {
    data: {
      type: 'posts',
      id: 1,
      attributes: {
        title: 'Lorem'
      },
      relationships: {
        author: {
          data: {type: 'authors', id: 1}
        },
        comments: {
          data: [{type: 'comments', id: 1}]
        }
      }
    },
    included: [
      {
        type: 'authors',
        id: 1,
        attributes: {
          'first-name': 'Link'
        }
      },
      {
        type: 'comments',
        id: 1,
        attributes: {
          'text': 'pwned'
        }
      }
    ]
  });

});
test(`keyForAttribute also formats the models in a collections`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer.extend({
      keyForAttribute: underscore
    })
  });

  this.schema.wordSmiths.create({ id: 1, 'firstName': 'Link', 'lastName': 'Jackson' });
  this.schema.wordSmiths.create({ id: 2, 'firstName': 'Zelda', 'lastName': 'Brown' });
  let wordSmiths = this.schema.wordSmiths.all();

  let result = registry.serialize(wordSmiths);

  assert.deepEqual(result, {
    data: [{
      type: 'word-smiths',
      id: '1',
      attributes: {
        'first_name': 'Link',
        'last_name': 'Jackson'
      },
      relationships: {
        'blog-posts': {
          data: []
        }
      }
    }, {
      type: 'word-smiths',
      id: '2',
      attributes: {
        'first_name': 'Zelda',
        'last_name': 'Brown'
      },
      relationships: {
        'blog-posts': {
          data: []
        }
      }
    }]
  });
});
test(`it returns only the whitelisted attrs when serializing a collection`, function(assert) {
  this.registry = new SerializerRegistry(this.schema, {
    wordSmith: JsonApiSerializer.extend({
      attrs: ['id', 'firstName']
    })
  });
  let { schema } = this;
  schema.wordSmith.create({ id: 1, firstName: 'Link', age: 123 });
  schema.wordSmith.create({ id: 2, firstName: 'Zelda', age: 456 });

  let collection = this.schema.wordSmith.all();
  let result = this.registry.serialize(collection);

  assert.deepEqual(result, {
    data: [{
      type: 'word-smiths',
      id: '1',
      attributes: {
        'first-name': 'Link'
      },
      relationships: {
        'blog-posts': {
          data: []
        }
      }
    }, {
      type: 'word-smiths',
      id: '2',
      attributes: {
        'first-name': 'Zelda'
      },
      relationships: {
        'blog-posts': {
          data: []
        }
      }
    }]
  });
});
test('_getRelatedModelWithPath belongsTo', function(assert) {
  let serializer = new (JsonApiSerializer.extend())();
  let schema = schemaHelper.setup();

  let foo = schema.foo.create();
  let bar = foo.createBar();
  foo.save();
  let baz = bar.createBaz();
  bar.save();
  let quux1 = baz.createQuux();
  let quux2 = baz.createQuux();
  baz.save();
  let zomg1 = quux1.createZomg();
  let zomg2 = quux1.createZomg();
  quux1.save();
  let zomg3 = quux2.createZomg();
  let zomg4 = quux2.createZomg();
  quux2.save();
  let lol1 = zomg1.createLol();
  let lol2 = zomg2.createLol();
  let lol3 = zomg3.createLol();
  let lol4 = zomg4.createLol();
  zomg1.save();
  zomg2.save();
  zomg3.save();
  zomg4.save();

  let result = serializer._getRelatedWithPath(foo, 'bar.baz.quuxes.zomgs.lol');
  let ids = _map(result, 'id');

  assert.equal(result.length, 4);
  assert.ok(_includes(ids, lol1.id));
  assert.ok(_includes(ids, lol2.id));
  assert.ok(_includes(ids, lol3.id));
  assert.ok(_includes(ids, lol4.id));
});
test(`it ignores relationships that refer to serialized ancestor resources, multiple levels down`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    wordSmith: JsonApiSerializer.extend({
      include: ['blogPosts']
    }),
    blogPost: JsonApiSerializer.extend({
      include: ['wordSmith', 'fineComments']
    }),
    fineComment: JsonApiSerializer.extend({
      include: ['blogPost']
    })
  });

  let wordSmith = this.schema.wordSmiths.find(1);
  let result = registry.serialize(wordSmith);

  assert.deepEqual(result, {
    data: {
      attributes: {
        'first-name': 'Link'
      },
      id: '1',
      relationships: {
        'blog-posts': {
          data: [
            { type: 'blog-posts', id: '1' },
            { type: 'blog-posts', id: '2' }
          ]
        }
      },
      type: 'word-smiths'
    },
    included: [
      {
        type: 'blog-posts',
        id: '1',
        attributes: {
          title: 'Lorem'
        },
        relationships: {
          'word-smith': {
            data: { type: 'word-smiths', id: '1' }
          },
          'fine-comments': {
            data: [
              { type: 'fine-comments', id: '1' }
            ]
          }
        }
      },
      {
        type: 'fine-comments',
        id: '1',
        attributes: {
          text: 'pwned'
        },
        relationships: {
          'blog-post': {
            data: { type: 'blog-posts', id: '1' }
          }
        }
      },
      {
        type: 'blog-posts',
        id: '2',
        attributes: {
          title: 'Ipsum'
        },
        relationships: {
          'word-smith': {
            data: { type: 'word-smiths', id: '1' }
          },
          'fine-comments': {
            data: []
          }
        }
      }
    ]
  });
});
test(`it can include a chain of has-many relationships`, function(assert) {
  let registry = new SerializerRegistry(this.schema, {
    application: JsonApiSerializer,
    wordSmith: JsonApiSerializer.extend({
      include: ['blogPosts']
    }),
    blogPost: JsonApiSerializer.extend({
      include: ['fineComments']
    })
  });

  let link = this.schema.wordSmiths.find(1);
  let result = registry.serialize(link);

  assert.deepEqual(result, {
    data: {
      type: 'word-smiths',
      id: '1',
      attributes: {
        'first-name': 'Link'
      },
      relationships: {
        'blog-posts': {
          data: [
            { type: 'blog-posts', id: '1' },
            { type: 'blog-posts', id: '2' }
          ]
        }
      }
    },
    included: [
      {
        type: 'blog-posts',
        id: '1',
        attributes: {
          title: 'Lorem'
        },
        relationships: {
          'fine-comments': {
            data: [
              { type: 'fine-comments', id: '1' }
            ]
          },
          'word-smith': {
            data: {
              id: '1',
              type: 'word-smiths'
            }
          }
        }
      },
      {
        type: 'fine-comments',
        id: '1',
        attributes: {
          text: 'pwned'
        },
        relationships: {
          'blog-post': {
            data: {
              id: '1',
              type: 'blog-posts'
            }
          }
        }
      },
      {
        type: 'blog-posts',
        id: '2',
        attributes: {
          title: 'Ipsum'
        },
        relationships: {
          'fine-comments': {
            data: []
          },
          'word-smith': {
            data: {
              id: '1',
              type: 'word-smiths'
            }
          }
        }
      }
    ]
  });
});
import SerializerRegistry from 'ember-cli-mirage/serializer-registry';
import JsonApiSerializer from 'ember-cli-mirage/serializers/json-api-serializer';
import schemaHelper from '../schema-helper';
import { underscore } from 'ember-cli-mirage/utils/inflector';
import {module, test} from 'qunit';

module('Integration | Serializers | JSON API Serializer | Attribute Key Formatting', {
  beforeEach() {
    this.schema = schemaHelper.setup();
    this.registry = new SerializerRegistry(this.schema, {
      application: JsonApiSerializer.extend({
        keyForAttribute(key) {
          return underscore(key);
        }
      })
    });
  },
  afterEach() {
    this.schema.db.emptyData();
  }
});

test(`keyForAttribute formats the attributes of a model`, function(assert) {
  var author = this.schema.author.create({
    id: 1,
    firstName: 'Link',
    lastName: 'Jackson',
    age: 323,
  });

  let result = this.registry.serialize(author);