Include 'linked' member for json-api collections

The options passed to the render are partitioned into adapter options
and serializer options. 'include' and 'root' are sent to the adapter,
not sure what options would go directly to serializer, but leaving this
in until I understand that better.
This commit is contained in:
Gary Gordon
2014-10-23 11:46:51 -04:00
parent 80ece39dd9
commit d5bae0c2f0
14 changed files with 250 additions and 56 deletions

View File

@@ -0,0 +1,104 @@
require 'test_helper'
module ActionController
module Serialization
class JsonApiLinkedTest < ActionController::TestCase
class MyController < ActionController::Base
def setup_post
@author = Author.new(id: 1, name: 'Steve K.')
@author.posts = []
@author2 = Author.new(id: 2, name: 'Anonymous')
@author2.posts = []
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
@post.comments = [@first_comment, @second_comment]
@post.author = @author
@first_comment.post = @post
@first_comment.author = @author2
@second_comment.post = @post
@second_comment.author = nil
end
def with_json_api_adapter
old_adapter = ActiveModel::Serializer.config.adapter
ActiveModel::Serializer.config.adapter = :json_api
yield
ensure
ActiveModel::Serializer.config.adapter = old_adapter
end
def render_resource_without_include
with_json_api_adapter do
setup_post
render json: @post
end
end
def render_resource_with_include
with_json_api_adapter do
setup_post
render json: @post, include: 'author'
end
end
def render_resource_with_nested_include
with_json_api_adapter do
setup_post
render json: @post, include: 'comments.author'
end
end
def render_collection_without_include
with_json_api_adapter do
setup_post
render json: [@post]
end
end
def render_collection_with_include
with_json_api_adapter do
setup_post
render json: [@post], include: 'author,comments'
end
end
end
tests MyController
def test_render_resource_without_include
get :render_resource_without_include
response = JSON.parse(@response.body)
refute response.key? 'linked'
end
def test_render_resource_with_include
get :render_resource_with_include
response = JSON.parse(@response.body)
assert response.key? 'linked'
assert_equal 1, response['linked']['authors'].size
assert_equal 'Steve K.', response['linked']['authors'].first['name']
end
def test_render_resource_with_nested_include
get :render_resource_with_nested_include
response = JSON.parse(@response.body)
assert response.key? 'linked'
assert_equal 1, response['linked']['authors'].size
assert_equal 'Anonymous', response['linked']['authors'].first['name']
end
def test_render_collection_without_include
get :render_collection_without_include
response = JSON.parse(@response.body)
refute response.key? 'linked'
end
def test_render_collection_with_include
get :render_collection_with_include
response = JSON.parse(@response.body)
assert response.key? 'linked'
end
end
end
end

View File

@@ -11,8 +11,9 @@ module ActiveModel
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
@post.comments = [@comment]
@anonymous_post.comments = []
@comment.post = @post
@post.author = @author
@comment.post = @post
@comment.author = nil
@anonymous_post.author = nil
@serializer = CommentSerializer.new(@comment)

View File

@@ -13,11 +13,13 @@ module ActiveModel
@post.comments = [@comment]
@anonymous_post.comments = []
@comment.post = @post
@comment.author = nil
@post.author = @author
@anonymous_post.author = nil
@blog = Blog.new(id: 1, name: "My Blog!!")
@blog.writer = @author
@blog.articles = [@post, @anonymous_post]
@author.posts = []
@serializer = CommentSerializer.new(@comment)
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
@@ -28,6 +30,7 @@ module ActiveModel
end
def test_includes_linked_post
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'post')
assert_equal([{id: "42", title: 'New Post', body: 'Body'}], @adapter.serializable_hash[:linked][:posts])
end

View File

@@ -4,7 +4,7 @@ module ActiveModel
class Serializer
class Adapter
class JsonApi
class Collection < Minitest::Test
class CollectionTest < Minitest::Test
def setup
@author = Author.new(id: 1, name: 'Steve K.')
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
@@ -13,6 +13,7 @@ module ActiveModel
@second_post.comments = []
@first_post.author = @author
@second_post.author = @author
@author.posts = [@first_post, @second_post]
@serializer = ArraySerializer.new([@first_post, @second_post])
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
@@ -20,8 +21,8 @@ module ActiveModel
def test_include_multiple_posts
assert_equal([
{title: "Hello!!", body: "Hello, world!!", id: "1", links: {comments: [], author: "1"}},
{title: "New Post", body: "Body", id: "2", links: {comments: [], author: "1"}}
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: [], author: "1" } },
{ title: "New Post", body: "Body", id: "2", links: { comments: [], author: "1" } }
], @adapter.serializable_hash[:posts])
end
end

View File

@@ -12,6 +12,8 @@ module ActiveModel
@author.posts = [@first_post, @second_post]
@first_post.author = @author
@second_post.author = @author
@first_post.comments = []
@second_post.comments = []
@serializer = AuthorSerializer.new(@author)
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)

View File

@@ -7,10 +7,13 @@ module ActiveModel
class HasManyTest < Minitest::Test
def setup
@author = Author.new(id: 1, name: 'Steve K.')
@author.posts = []
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
@post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
@first_comment.author = nil
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
@second_comment.author = nil
@post.comments = [@first_comment, @second_comment]
@post_without_comments.comments = []
@first_comment.post = @post
@@ -30,6 +33,7 @@ module ActiveModel
end
def test_includes_linked_comments
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments')
assert_equal([
{id: "1", body: 'ZOMG A COMMENT'},
{id: "2", body: 'ZOMG ANOTHER COMMENT'}

View File

@@ -0,0 +1,40 @@
require 'test_helper'
module ActiveModel
class Serializer
class Adapter
class JsonApi
class LinkedTest < Minitest::Test
def setup
@author = Author.new(id: 1, name: 'Steve K.')
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
@first_post.comments = []
@second_post.comments = []
@first_post.author = @author
@second_post.author = @author
@author.posts = [@first_post, @second_post]
@serializer = ArraySerializer.new([@first_post, @second_post])
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'author,comments')
end
def test_include_multiple_posts_and_linked
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
@first_post.comments = [@first_comment, @second_comment]
@first_comment.post = @first_post
@first_comment.author = nil
@second_comment.post = @first_post
@second_comment.author = nil
assert_equal([
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: ['1', '2'], author: "1" } },
{ title: "New Post", body: "Body", id: "2", links: { comments: [], :author => "1" } }
], @adapter.serializable_hash[:posts])
assert_equal({ :comments => [{ :id => "1", :body => "ZOMG A COMMENT" }, { :id => "2", :body => "ZOMG ANOTHER COMMENT" }], :authors => [{ :id => "1", :name => "Steve K." }] }, @adapter.serializable_hash[:linked])
end
end
end
end
end
end

View File

@@ -52,6 +52,7 @@ CommentSerializer = Class.new(ActiveModel::Serializer) do
attributes :id, :body
belongs_to :post
belongs_to :author
end
AuthorSerializer = Class.new(ActiveModel::Serializer) do

View File

@@ -30,6 +30,7 @@ module ActiveModel
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
@post.comments = [@comment]
@comment.post = @post
@comment.author = nil
@post.author = @author
@author.posts = [@post]
@@ -47,11 +48,17 @@ module ActiveModel
end
def test_has_one
assert_equal({post: {type: :belongs_to, options: {}}}, @comment_serializer.class._associations)
assert_equal({post: {type: :belongs_to, options: {}}, :author=>{:type=>:belongs_to, :options=>{}}}, @comment_serializer.class._associations)
@comment_serializer.each_association do |name, serializer, options|
assert_equal(:post, name)
assert_equal({}, options)
assert_kind_of(PostSerializer, serializer)
if name == :post
assert_equal({}, options)
assert_kind_of(PostSerializer, serializer)
elsif name == :author
assert_equal({}, options)
assert_nil serializer
else
flunk "Unknown association: #{name}"
end
end
end
end