mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
400 lines
12 KiB
Ruby
400 lines
12 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'test_helper'
|
|
|
|
module ActiveModelSerializers
|
|
module Adapter
|
|
class JsonApi
|
|
class RelationshipTest < ActiveSupport::TestCase
|
|
def test_relationship_with_data
|
|
expected = {
|
|
data: {
|
|
id: '1',
|
|
type: 'blogs'
|
|
}
|
|
}
|
|
|
|
model_attributes = { blog: Blog.new(id: 1) }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_with_nil_model
|
|
expected = { data: nil }
|
|
|
|
model_attributes = { blog: nil }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_with_data_array
|
|
expected = {
|
|
data: [
|
|
{
|
|
id: '1',
|
|
type: 'posts'
|
|
},
|
|
{
|
|
id: '2',
|
|
type: 'posts'
|
|
}
|
|
]
|
|
}
|
|
|
|
model_attributes = { posts: [Post.new(id: 1), Post.new(id: 2)] }
|
|
relationship_name = :posts
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_many :posts
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_data_not_included
|
|
expected = { meta: {} }
|
|
|
|
model_attributes = { blog: :does_not_matter }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog do
|
|
include_data false
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_many_links
|
|
expected = {
|
|
links: {
|
|
self: 'a link',
|
|
related: 'another link'
|
|
}
|
|
}
|
|
|
|
model_attributes = { blog: :does_not_matter }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog do
|
|
include_data false
|
|
link :self, 'a link'
|
|
link :related, 'another link'
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_block_link_with_meta
|
|
expected = {
|
|
links: {
|
|
self: {
|
|
href: '1',
|
|
meta: { id: 1 }
|
|
}
|
|
}
|
|
}
|
|
|
|
model_attributes = { blog: Blog.new(id: 1) }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog do
|
|
include_data false
|
|
link :self do
|
|
href object.blog.id.to_s
|
|
meta(id: object.blog.id)
|
|
end
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_simple_meta
|
|
expected = { meta: { id: '1' } }
|
|
|
|
model_attributes = { blog: Blog.new(id: 1) }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog do
|
|
include_data false
|
|
meta(id: object.blog.id.to_s)
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_block_meta
|
|
expected = {
|
|
meta: {
|
|
id: 1
|
|
}
|
|
}
|
|
|
|
model_attributes = { blog: Blog.new(id: 1) }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog do
|
|
include_data false
|
|
meta(id: object.blog.id)
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_simple_link
|
|
expected = {
|
|
data: {
|
|
id: '1337',
|
|
type: 'bios'
|
|
},
|
|
links: {
|
|
self: '//example.com/link_author/relationships/bio'
|
|
}
|
|
}
|
|
|
|
model_attributes = { bio: Bio.new(id: 1337) }
|
|
relationship_name = :bio
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :bio do
|
|
link :self, '//example.com/link_author/relationships/bio'
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_block_link
|
|
expected = {
|
|
data: { id: '1337', type: 'profiles' },
|
|
links: { related: '//example.com/profiles/1337' }
|
|
}
|
|
|
|
model_attributes = { profile: Profile.new(id: 1337) }
|
|
relationship_name = :profile
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :profile do
|
|
id = object.profile.id
|
|
link :related do
|
|
"//example.com/profiles/#{id}" if id != 123
|
|
end
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_with_everything
|
|
expected = {
|
|
data: [{ id: '1337', type: 'likes' }],
|
|
links: {
|
|
related: {
|
|
href: '//example.com/likes/1337',
|
|
meta: { ids: '1337' }
|
|
}
|
|
},
|
|
meta: { liked: true }
|
|
}
|
|
|
|
model_attributes = { likes: [Like.new(id: 1337)] }
|
|
relationship_name = :likes
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_many :likes do
|
|
link :related do
|
|
ids = object.likes.map(&:id).join(',')
|
|
href "//example.com/likes/#{ids}"
|
|
meta ids: ids
|
|
end
|
|
meta liked: object.likes.any?
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_nil_link
|
|
expected = {
|
|
data: { id: '123', type: 'profiles' }
|
|
}
|
|
|
|
model_attributes = { profile: Profile.new(id: 123) }
|
|
relationship_name = :profile
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :profile do
|
|
id = object.profile.id
|
|
link :related do
|
|
"//example.com/profiles/#{id}" if id != 123
|
|
end
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_block_link_href
|
|
expected = {
|
|
data: [{ id: '1337', type: 'locations' }],
|
|
links: {
|
|
related: { href: '//example.com/locations/1337' }
|
|
}
|
|
}
|
|
|
|
model_attributes = { locations: [Location.new(id: 1337)] }
|
|
relationship_name = :locations
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_many :locations do
|
|
link :related do
|
|
ids = object.locations.map(&:id).join(',')
|
|
href "//example.com/locations/#{ids}"
|
|
end
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_block_link_href_and_meta
|
|
expected = {
|
|
data: [{ id: '1337', type: 'posts' }],
|
|
links: {
|
|
related: {
|
|
href: '//example.com/posts/1337',
|
|
meta: { ids: '1337' }
|
|
}
|
|
}
|
|
}
|
|
|
|
model_attributes = { posts: [Post.new(id: 1337, comments: [], author: nil)] }
|
|
relationship_name = :posts
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_many :posts do
|
|
link :related do
|
|
ids = object.posts.map(&:id).join(',')
|
|
href "//example.com/posts/#{ids}"
|
|
meta ids: ids
|
|
end
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_block_link_meta
|
|
expected = {
|
|
data: [{ id: '1337', type: 'comments' }],
|
|
links: {
|
|
self: {
|
|
meta: { ids: [1] }
|
|
}
|
|
}
|
|
}
|
|
|
|
model_attributes = { comments: [Comment.new(id: 1337)] }
|
|
relationship_name = :comments
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_many :comments do
|
|
link :self do
|
|
meta ids: [1]
|
|
end
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_meta
|
|
expected = {
|
|
data: [{ id: 'from-serializer-method', type: 'roles' }],
|
|
meta: { count: 1 }
|
|
}
|
|
|
|
model_attributes = { roles: [Role.new(id: 'from-record')] }
|
|
relationship_name = :roles
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_many :roles do |serializer|
|
|
meta count: object.roles.count
|
|
serializer.cached_roles
|
|
end
|
|
def cached_roles
|
|
[
|
|
Role.new(id: 'from-serializer-method')
|
|
]
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
def test_relationship_not_including_data
|
|
expected = {
|
|
links: { self: '//example.com/link_author/relationships/blog' }
|
|
}
|
|
|
|
model_attributes = { blog: Object }
|
|
relationship_name = :blog
|
|
model = new_model(model_attributes)
|
|
model.define_singleton_method(:read_attribute_for_serialization) do |attr|
|
|
fail 'should not be called' if attr == :blog
|
|
super(attr)
|
|
end
|
|
assert_nothing_raised do
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
has_one :blog do
|
|
link :self, '//example.com/link_author/relationships/blog'
|
|
include_data false
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
end
|
|
|
|
def test_relationship_including_data_explicit
|
|
expected = {
|
|
data: { id: '1337', type: 'authors' },
|
|
meta: { name: 'Dan Brown' }
|
|
}
|
|
|
|
model_attributes = { reviewer: Author.new(id: 1337) }
|
|
relationship_name = :reviewer
|
|
model = new_model(model_attributes)
|
|
actual = build_serializer_and_serialize_relationship(model, relationship_name) do
|
|
belongs_to :reviewer do
|
|
meta name: 'Dan Brown'
|
|
include_data true
|
|
end
|
|
end
|
|
assert_equal(expected, actual)
|
|
end
|
|
|
|
private
|
|
|
|
def build_serializer_and_serialize_relationship(model, relationship_name, &block)
|
|
serializer_class = Class.new(ActiveModel::Serializer, &block)
|
|
hash = serializable(model, serializer: serializer_class, adapter: :json_api).serializable_hash
|
|
hash[:data][:relationships][relationship_name]
|
|
end
|
|
|
|
def new_model(model_attributes)
|
|
Class.new(ActiveModelSerializers::Model) do
|
|
attributes(*model_attributes.keys)
|
|
|
|
def self.name
|
|
'TestModel'
|
|
end
|
|
end.new(model_attributes)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|