Remove old tests.
This commit is contained in:
parent
a529d2808a
commit
713e0ef58d
@ -1,152 +0,0 @@
|
||||
require 'spec_helper'
|
||||
require 'active_record'
|
||||
require 'sqlite3'
|
||||
|
||||
RSpec.describe 'active record' do
|
||||
# Setup DB
|
||||
before(:all) do
|
||||
@db_file = 'test.db'
|
||||
|
||||
# Open a database
|
||||
db = SQLite3::Database.new @db_file
|
||||
|
||||
# Create tables
|
||||
db.execute_batch <<-SQL
|
||||
create table suppliers (
|
||||
name varchar(30),
|
||||
id int primary key
|
||||
);
|
||||
|
||||
create table accounts (
|
||||
name varchar(30),
|
||||
id int primary key,
|
||||
supplier_id int,
|
||||
FOREIGN KEY (supplier_id) REFERENCES suppliers(id)
|
||||
);
|
||||
SQL
|
||||
|
||||
# Insert records
|
||||
@account_id = 2
|
||||
@supplier_id = 1
|
||||
@supplier_id_without_account = 3
|
||||
db.execute_batch <<-SQL
|
||||
insert into suppliers values ('Supplier1', #{@supplier_id}),
|
||||
('SupplierWithoutAccount', #{@supplier_id_without_account});
|
||||
insert into accounts values ('Dollar Account', #{@account_id}, #{@supplier_id});
|
||||
SQL
|
||||
end
|
||||
|
||||
# Setup Active Record
|
||||
before(:all) do
|
||||
class Supplier < ActiveRecord::Base
|
||||
has_one :account
|
||||
end
|
||||
|
||||
class Account < ActiveRecord::Base
|
||||
belongs_to :supplier
|
||||
end
|
||||
|
||||
ActiveRecord::Base.establish_connection(
|
||||
adapter: 'sqlite3',
|
||||
database: @db_file
|
||||
)
|
||||
end
|
||||
|
||||
context 'has one patch' do
|
||||
it 'has account_id method for a supplier' do
|
||||
expect(Supplier.first.respond_to?(:account_id)).to be true
|
||||
expect(Supplier.first.account_id).to eq @account_id
|
||||
end
|
||||
|
||||
it 'has account_id method return nil if account not present' do
|
||||
expect(Supplier.find(@supplier_id_without_account).account_id).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
# Clean up DB
|
||||
after(:all) do
|
||||
File.delete(@db_file) if File.exist?(@db_file)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe 'active record has_one through' do
|
||||
# Setup DB
|
||||
before(:all) do
|
||||
@db_file = 'test_two.db'
|
||||
|
||||
# Open a database
|
||||
db = SQLite3::Database.new @db_file
|
||||
|
||||
# Create tables
|
||||
db.execute_batch <<-SQL
|
||||
create table forests (
|
||||
id int primary key,
|
||||
name varchar(30)
|
||||
);
|
||||
|
||||
create table trees (
|
||||
id int primary key,
|
||||
forest_id int,
|
||||
name varchar(30),
|
||||
|
||||
FOREIGN KEY (forest_id) REFERENCES forests(id)
|
||||
);
|
||||
|
||||
create table fruits (
|
||||
id int primary key,
|
||||
tree_id int,
|
||||
name varchar(30),
|
||||
|
||||
FOREIGN KEY (tree_id) REFERENCES trees(id)
|
||||
);
|
||||
SQL
|
||||
|
||||
# Insert records
|
||||
db.execute_batch <<-SQL
|
||||
insert into forests values (1, 'sherwood');
|
||||
insert into trees values (2, 1,'pine');
|
||||
insert into fruits values (3, 2, 'pine nut');
|
||||
|
||||
insert into fruits(id,name) values (4,'apple');
|
||||
SQL
|
||||
end
|
||||
|
||||
# Setup Active Record
|
||||
before(:all) do
|
||||
class Forest < ActiveRecord::Base
|
||||
has_many :trees
|
||||
end
|
||||
|
||||
class Tree < ActiveRecord::Base
|
||||
belongs_to :forest
|
||||
end
|
||||
|
||||
class Fruit < ActiveRecord::Base
|
||||
belongs_to :tree
|
||||
has_one :forest, through: :tree
|
||||
end
|
||||
|
||||
ActiveRecord::Base.establish_connection(
|
||||
adapter: 'sqlite3',
|
||||
database: @db_file
|
||||
)
|
||||
end
|
||||
|
||||
context 'revenue' do
|
||||
it 'has an forest_id' do
|
||||
expect(Fruit.find(3).respond_to?(:forest_id)).to be true
|
||||
expect(Fruit.find(3).forest_id).to eq 1
|
||||
expect(Fruit.find(3).forest.name).to eq 'sherwood'
|
||||
end
|
||||
|
||||
it 'has nil if tree id not available' do
|
||||
expect(Fruit.find(4).respond_to?(:tree_id)).to be true
|
||||
expect(Fruit.find(4).forest_id).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
# Clean up DB
|
||||
after(:all) do
|
||||
File.delete(@db_file) if File.exist?(@db_file)
|
||||
end
|
||||
end
|
@ -1,73 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi do
|
||||
describe '.call_proc' do
|
||||
context 'with a Proc' do
|
||||
context 'with no parameters' do
|
||||
let(:function) { proc { 42 } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(42)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a single parameter' do
|
||||
let(:function) { proc { |a| 42 + a } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(43)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple parameters' do
|
||||
let(:function) { proc { |a, b| 42 + a + b } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(45)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with default parameters' do
|
||||
let(:function) { proc { |a = 0, b = 0| 42 + a + b } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(45)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a lambda' do
|
||||
context 'with no parameters' do
|
||||
let(:function) { -> { 42 } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(42)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a single parameter' do
|
||||
let(:function) { ->(a) { 42 + a } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(43)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple parameters' do
|
||||
let(:function) { ->(a, b) { 42 + a + b } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(45)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with default parameters' do
|
||||
let(:function) { ->(a = 0, b = 0) { 42 + a + b } }
|
||||
|
||||
it 'calls the proc' do
|
||||
expect(FastJsonapi.call_proc(function, 1, 2)).to eq(45)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,50 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
context 'instrument' do
|
||||
before(:each) do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:include] = [:actors]
|
||||
|
||||
movies = build_movies(2)
|
||||
@serializer = MovieSerializer.new(movies, options)
|
||||
end
|
||||
|
||||
context 'serializable_hash' do
|
||||
it 'should send not notifications' do
|
||||
events = []
|
||||
|
||||
ActiveSupport::Notifications.subscribe(FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION) do |*args|
|
||||
events << ActiveSupport::Notifications::Event.new(*args)
|
||||
end
|
||||
|
||||
serialized_hash = @serializer.serializable_hash
|
||||
|
||||
expect(events.length).to eq(0)
|
||||
|
||||
expect(serialized_hash.key?(:data)).to eq(true)
|
||||
expect(serialized_hash.key?(:meta)).to eq(true)
|
||||
expect(serialized_hash.key?(:included)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'serialized_json' do
|
||||
it 'should send not notifications' do
|
||||
events = []
|
||||
|
||||
ActiveSupport::Notifications.subscribe(FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION) do |*args|
|
||||
events << ActiveSupport::Notifications::Event.new(*args)
|
||||
end
|
||||
|
||||
json = @serializer.serialized_json
|
||||
|
||||
expect(events.length).to eq(0)
|
||||
|
||||
expect(json.length).to be > 50
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,76 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
context 'instrument' do
|
||||
before(:all) do
|
||||
require 'fast_jsonapi/instrumentation'
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
[:serialized_json, :serializable_hash].each do |m|
|
||||
alias_command = "alias_method :#{m}, :#{m}_without_instrumentation"
|
||||
FastJsonapi::ObjectSerializer.class_eval(alias_command)
|
||||
|
||||
remove_command = "remove_method :#{m}_without_instrumentation"
|
||||
FastJsonapi::ObjectSerializer.class_eval(remove_command)
|
||||
end
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:include] = [:actors]
|
||||
|
||||
movies = build_movies(2)
|
||||
@serializer = MovieSerializer.new(movies, options)
|
||||
end
|
||||
|
||||
context 'serializable_hash' do
|
||||
it 'should send notifications' do
|
||||
events = []
|
||||
|
||||
ActiveSupport::Notifications.subscribe(FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION) do |*args|
|
||||
events << ActiveSupport::Notifications::Event.new(*args)
|
||||
end
|
||||
|
||||
serialized_hash = @serializer.serializable_hash
|
||||
|
||||
expect(events.length).to eq(1)
|
||||
|
||||
event = events.first
|
||||
|
||||
expect(event.duration).to be > 0
|
||||
expect(event.payload).to eq({ name: 'MovieSerializer' })
|
||||
expect(event.name).to eq(FastJsonapi::ObjectSerializer::SERIALIZABLE_HASH_NOTIFICATION)
|
||||
|
||||
expect(serialized_hash.key?(:data)).to eq(true)
|
||||
expect(serialized_hash.key?(:meta)).to eq(true)
|
||||
expect(serialized_hash.key?(:included)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context 'serialized_json' do
|
||||
it 'should send notifications' do
|
||||
events = []
|
||||
|
||||
ActiveSupport::Notifications.subscribe(FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION) do |*args|
|
||||
events << ActiveSupport::Notifications::Event.new(*args)
|
||||
end
|
||||
|
||||
json = @serializer.serialized_json
|
||||
|
||||
expect(events.length).to eq(1)
|
||||
|
||||
event = events.first
|
||||
|
||||
expect(event.duration).to be > 0
|
||||
expect(event.payload).to eq({ name: 'MovieSerializer' })
|
||||
expect(event.name).to eq(FastJsonapi::ObjectSerializer::SERIALIZED_JSON_NOTIFICATION)
|
||||
|
||||
expect(json.length).to be > 50
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,118 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
context 'params option' do
|
||||
let(:hash) { serializer.serializable_hash }
|
||||
|
||||
before(:context) do
|
||||
class Movie
|
||||
def viewed?(user)
|
||||
user.viewed.include?(id)
|
||||
end
|
||||
end
|
||||
|
||||
class MovieSerializer
|
||||
attribute :viewed do |movie, params|
|
||||
params[:user] ? movie.viewed?(params[:user]) : false
|
||||
end
|
||||
|
||||
attribute :no_param_attribute do |_movie|
|
||||
'no-param-attribute'
|
||||
end
|
||||
end
|
||||
|
||||
User = Struct.new(:viewed)
|
||||
end
|
||||
|
||||
after(:context) do
|
||||
Object.send(:remove_const, User) if Object.constants.include?(User)
|
||||
end
|
||||
|
||||
context 'enforces a hash only params' do
|
||||
let(:params) { User.new([]) }
|
||||
|
||||
it 'fails when creating a serializer with an object as params' do
|
||||
expect(-> { MovieSerializer.new(movie, { params: User.new([]) }) }).to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'succeeds creating a serializer with a hash' do
|
||||
expect(-> { MovieSerializer.new(movie, { params: { current_user: User.new([]) } }) }).not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'passing params to the serializer' do
|
||||
let(:params) { { user: User.new([movie.id]) } }
|
||||
let(:options_with_params) { { params: params } }
|
||||
|
||||
context 'with a single record' do
|
||||
let(:serializer) { MovieSerializer.new(movie, options_with_params) }
|
||||
|
||||
it 'handles attributes that use params' do
|
||||
expect(hash[:data][:attributes][:viewed]).to eq(true)
|
||||
end
|
||||
|
||||
it "handles attributes that don't use params" do
|
||||
expect(hash[:data][:attributes][:no_param_attribute]).to eq('no-param-attribute')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a list of records' do
|
||||
let(:movies) { build_movies(3) }
|
||||
let(:user) { User.new(movies.map { |m| [true, false].sample ? m.id : nil }.compact) }
|
||||
let(:params) { { user: user } }
|
||||
let(:serializer) { MovieSerializer.new(movies, options_with_params) }
|
||||
|
||||
it 'has 3 items' do
|
||||
hash[:data].length == 3
|
||||
end
|
||||
|
||||
it 'handles passing params to a list of resources' do
|
||||
param_attribute_values = hash[:data].map { |data| [data[:id], data[:attributes][:viewed]] }
|
||||
expected_values = movies.map { |m| [m.id.to_s, user.viewed.include?(m.id)] }
|
||||
|
||||
expect(param_attribute_values).to eq(expected_values)
|
||||
end
|
||||
|
||||
it 'handles attributes without params' do
|
||||
no_param_attribute_values = hash[:data].map { |data| data[:attributes][:no_param_attribute] }
|
||||
expected_values = (1..3).map { 'no-param-attribute' }
|
||||
|
||||
expect(no_param_attribute_values).to eq(expected_values)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without passing params to the serializer' do
|
||||
context 'with a single movie' do
|
||||
let(:serializer) { MovieSerializer.new(movie) }
|
||||
|
||||
it 'handles param attributes' do
|
||||
expect(hash[:data][:attributes][:viewed]).to eq(false)
|
||||
end
|
||||
|
||||
it "handles attributes that don't use params" do
|
||||
expect(hash[:data][:attributes][:no_param_attribute]).to eq('no-param-attribute')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple movies' do
|
||||
let(:serializer) { MovieSerializer.new(build_movies(3)) }
|
||||
|
||||
it 'handles attributes with params' do
|
||||
param_attribute_values = hash[:data].map { |data| data[:attributes][:viewed] }
|
||||
|
||||
expect(param_attribute_values).to eq([false, false, false])
|
||||
end
|
||||
|
||||
it "handles attributes that don't use params" do
|
||||
no_param_attribute_values = hash[:data].map { |data| data[:attributes][:no_param_attribute] }
|
||||
expected_attribute_values = (1..3).map { 'no-param-attribute' }
|
||||
|
||||
expect(no_param_attribute_values).to eq(expected_attribute_values)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,107 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
context 'when caching has_many' do
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:links] = { self: 'self' }
|
||||
|
||||
options[:include] = [:actors]
|
||||
movies = build_movies(2)
|
||||
serializable_hash = CachingMovieSerializer.new(movies, options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data].length).to eq 2
|
||||
expect(serializable_hash[:data][0][:relationships].length).to eq 3
|
||||
expect(serializable_hash[:data][0][:attributes].length).to eq 2
|
||||
|
||||
expect(serializable_hash[:meta]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:links]).to be_instance_of(Hash)
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included][0]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:included].length).to eq 3
|
||||
|
||||
serializable_hash = CachingMovieSerializer.new(movie).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:meta]).to be nil
|
||||
expect(serializable_hash[:links]).to be nil
|
||||
expect(serializable_hash[:included]).to be nil
|
||||
end
|
||||
|
||||
it 'uses cached values for the record' do
|
||||
previous_name = movie.name
|
||||
previous_actors = movie.actors
|
||||
CachingMovieSerializer.new(movie).serializable_hash
|
||||
|
||||
movie.name = 'should not match'
|
||||
allow(movie).to receive(:actor_ids).and_return([99])
|
||||
|
||||
expect(previous_name).not_to eq(movie.name)
|
||||
expect(previous_actors).not_to eq(movie.actors)
|
||||
serializable_hash = CachingMovieSerializer.new(movie).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data][:attributes][:name]).to eq(previous_name)
|
||||
expect(serializable_hash[:data][:relationships][:actors][:data].length).to eq movie.actors.length
|
||||
end
|
||||
|
||||
it 'uses cached values for has many as specified' do
|
||||
previous_name = movie.name
|
||||
previous_actors = movie.actors
|
||||
CachingMovieWithHasManySerializer.new(movie).serializable_hash
|
||||
|
||||
movie.name = 'should not match'
|
||||
allow(movie).to receive(:actor_ids).and_return([99])
|
||||
|
||||
expect(previous_name).not_to eq(movie.name)
|
||||
expect(previous_actors).not_to eq(movie.actors)
|
||||
serializable_hash = CachingMovieWithHasManySerializer.new(movie).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data][:attributes][:name]).to eq(previous_name)
|
||||
expect(serializable_hash[:data][:relationships][:actors][:data].length).to eq previous_actors.length
|
||||
end
|
||||
end
|
||||
|
||||
# FIXME: remove this if block once deprecated cache_options are not supported anymore
|
||||
context 'when using deprecated cache options' do
|
||||
let(:deprecated_caching_movie_serializer_class) do
|
||||
rails = OpenStruct.new
|
||||
rails.cache = ActiveSupport::Cache::MemoryStore.new
|
||||
stub_const('Rails', rails)
|
||||
|
||||
Class.new do
|
||||
def self.name
|
||||
'DeprecatedCachingMovieSerializer'
|
||||
end
|
||||
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name, :release_year
|
||||
has_many :actors
|
||||
belongs_to :owner, record_type: :user
|
||||
belongs_to :movie_type
|
||||
|
||||
cache_options enabled: true
|
||||
end
|
||||
end
|
||||
|
||||
it 'uses cached values for the record' do
|
||||
previous_name = movie.name
|
||||
previous_actors = movie.actors
|
||||
deprecated_caching_movie_serializer_class.new(movie).serializable_hash
|
||||
|
||||
movie.name = 'should not match'
|
||||
allow(movie).to receive(:actor_ids).and_return([99])
|
||||
|
||||
expect(previous_name).not_to eq(movie.name)
|
||||
expect(previous_actors).not_to eq(movie.actors)
|
||||
serializable_hash = deprecated_caching_movie_serializer_class.new(movie).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data][:attributes][:name]).to eq(previous_name)
|
||||
expect(serializable_hash[:data][:relationships][:actors][:data].length).to eq movie.actors.length
|
||||
end
|
||||
end
|
||||
end
|
@ -1,674 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
describe '#has_many' do
|
||||
subject(:relationship) { serializer.relationships_to_serialize[:roles] }
|
||||
|
||||
before do
|
||||
serializer.has_many(*children)
|
||||
end
|
||||
|
||||
after do
|
||||
serializer.relationships_to_serialize = {}
|
||||
end
|
||||
|
||||
context 'with namespace' do
|
||||
before do
|
||||
class AppName::V1::RoleSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
end
|
||||
|
||||
let(:serializer) { AppName::V1::MovieSerializer }
|
||||
let(:children) { [:roles] }
|
||||
let(:relationship_serializer) { AppName::V1::RoleSerializer }
|
||||
|
||||
context 'with overrides' do
|
||||
let(:children) { [:roles, id_method_name: :roles_only_ids, record_type: :super_role] }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :roles_only_ids, :super_role
|
||||
end
|
||||
|
||||
context 'without overrides' do
|
||||
let(:children) { [:roles] }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :role_ids, :role
|
||||
end
|
||||
end
|
||||
|
||||
context 'without namespace' do
|
||||
before do
|
||||
class RoleSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
end
|
||||
|
||||
let(:serializer) { MovieSerializer }
|
||||
let(:relationship_serializer) { RoleSerializer }
|
||||
|
||||
context 'with overrides' do
|
||||
let(:children) { [:roles, id_method_name: :roles_only_ids, record_type: :super_role] }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :roles_only_ids, :super_role
|
||||
end
|
||||
|
||||
context 'without overrides' do
|
||||
let(:children) { [:roles] }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :role_ids, :role
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#has_many with block' do
|
||||
before do
|
||||
MovieSerializer.has_many :awards do |movie|
|
||||
movie.actors.map(&:awards).flatten
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.relationships_to_serialize.delete(:awards)
|
||||
end
|
||||
|
||||
context 'awards is not included' do
|
||||
subject(:hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
it 'returns correct hash' do
|
||||
expect(hash[:data][:relationships][:awards][:data].length).to eq(6)
|
||||
expect(hash[:data][:relationships][:awards][:data][0]).to eq({ id: '9', type: :award })
|
||||
expect(hash[:data][:relationships][:awards][:data][-1]).to eq({ id: '28', type: :award })
|
||||
end
|
||||
end
|
||||
|
||||
context 'state is included' do
|
||||
subject(:hash) { MovieSerializer.new(movie, include: [:awards]).serializable_hash }
|
||||
|
||||
it 'returns correct hash' do
|
||||
expect(hash[:included].length).to eq 6
|
||||
expect(hash[:included][0][:id]).to eq '9'
|
||||
expect(hash[:included][0][:type]).to eq :award
|
||||
expect(hash[:included][0][:attributes]).to eq({ id: 9, title: 'Test Award 9' })
|
||||
expect(hash[:included][0][:relationships]).to eq({ actor: { data: { id: '1', type: :actor } } })
|
||||
expect(hash[:included][-1][:id]).to eq '28'
|
||||
expect(hash[:included][-1][:type]).to eq :award
|
||||
expect(hash[:included][-1][:attributes]).to eq({ id: 28, title: 'Test Award 28' })
|
||||
expect(hash[:included][-1][:relationships]).to eq({ actor: { data: { id: '3', type: :actor } } })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#has_many with block and id_method_name' do
|
||||
before do
|
||||
MovieSerializer.has_many(:awards, id_method_name: :imdb_award_id) do |movie|
|
||||
movie.actors.map(&:awards).flatten
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.relationships_to_serialize.delete(:awards)
|
||||
end
|
||||
|
||||
context 'awards is not included' do
|
||||
subject(:hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
it 'returns correct hash where id is obtained from the method specified via `id_method_name`' do
|
||||
expected_award_data = movie.actors.map(&:awards).flatten.map do |actor|
|
||||
{ id: actor.imdb_award_id.to_s, type: actor.class.name.downcase.to_sym }
|
||||
end
|
||||
serialized_award_data = hash[:data][:relationships][:awards][:data]
|
||||
|
||||
expect(serialized_award_data).to eq(expected_award_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#has_many with &:proc' do
|
||||
before do
|
||||
MovieSerializer.has_many :stars, &:actors
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.relationships_to_serialize.delete(:stars)
|
||||
end
|
||||
|
||||
subject(:hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
it 'returns correct hash' do
|
||||
expect(hash[:data][:relationships][:stars][:data].length).to eq(3)
|
||||
expect(hash[:data][:relationships][:stars][:data][0]).to eq({ id: '1', type: :actor })
|
||||
expect(hash[:data][:relationships][:stars][:data][1]).to eq({ id: '2', type: :actor })
|
||||
expect(hash[:data][:relationships][:stars][:data][2]).to eq({ id: '3', type: :actor })
|
||||
end
|
||||
end
|
||||
|
||||
describe '#belongs_to' do
|
||||
subject(:relationship) { MovieSerializer.relationships_to_serialize[:area] }
|
||||
|
||||
before do
|
||||
MovieSerializer.belongs_to(*parent)
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.relationships_to_serialize = {}
|
||||
end
|
||||
|
||||
context 'with overrides' do
|
||||
before do
|
||||
class MyAreaSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
end
|
||||
|
||||
let(:parent) { [:area, id_method_name: :blah_id, record_type: :awesome_area, serializer: :my_area] }
|
||||
let(:relationship_serializer) { MyAreaSerializer }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :blah_id, :awesome_area
|
||||
end
|
||||
|
||||
context 'without overrides' do
|
||||
before do
|
||||
class AreaSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
end
|
||||
|
||||
let(:parent) { [:area] }
|
||||
let(:relationship_serializer) { AreaSerializer }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :area_id, :area
|
||||
end
|
||||
end
|
||||
|
||||
describe '#belongs_to with block' do
|
||||
before do
|
||||
ActorSerializer.belongs_to :state do |actor|
|
||||
actor.agency.state
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
ActorSerializer.relationships_to_serialize.delete(:actorc)
|
||||
end
|
||||
|
||||
context 'state is not included' do
|
||||
subject(:hash) { ActorSerializer.new(actor).serializable_hash }
|
||||
|
||||
it 'returns correct hash' do
|
||||
expect(hash[:data][:relationships][:state][:data]).to eq({ id: '1', type: :state })
|
||||
end
|
||||
end
|
||||
|
||||
context 'state is included' do
|
||||
subject(:hash) { ActorSerializer.new(actor, include: [:state]).serializable_hash }
|
||||
|
||||
it 'returns correct hash' do
|
||||
expect(hash[:included].length).to eq 1
|
||||
expect(hash[:included][0][:id]).to eq '1'
|
||||
expect(hash[:included][0][:type]).to eq :state
|
||||
expect(hash[:included][0][:attributes]).to eq({ id: 1, name: 'Test State 1' })
|
||||
expect(hash[:included][0][:relationships]).to eq({ agency: { data: [{ id: '432', type: :agency }] } })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#belongs_to with &:proc' do
|
||||
before do
|
||||
MovieSerializer.belongs_to :user, &:owner
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.relationships_to_serialize.delete(:user)
|
||||
end
|
||||
|
||||
subject(:hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
it 'returns correct hash' do
|
||||
expect(hash[:data][:relationships][:user][:data]).to eq({ id: '3', type: :owner })
|
||||
end
|
||||
end
|
||||
|
||||
describe '#has_one' do
|
||||
subject(:relationship) { MovieSerializer.relationships_to_serialize[:area] }
|
||||
|
||||
before do
|
||||
MovieSerializer.has_one(*partner)
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.relationships_to_serialize = {}
|
||||
end
|
||||
|
||||
context 'with overrides' do
|
||||
before do
|
||||
class MyAreaSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
end
|
||||
|
||||
let(:partner) { [:area, id_method_name: :blah_id, record_type: :awesome_area, serializer: :my_area] }
|
||||
let(:relationship_serializer) { MyAreaSerializer }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :blah_id, :awesome_area
|
||||
end
|
||||
|
||||
context 'without overrides' do
|
||||
before do
|
||||
class AreaSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
end
|
||||
|
||||
let(:partner) { [:area] }
|
||||
let(:relationship_serializer) { AreaSerializer }
|
||||
|
||||
it_behaves_like 'returning correct relationship hash', :area_id, :area
|
||||
end
|
||||
end
|
||||
|
||||
describe '#has_one with &:proc' do
|
||||
before do
|
||||
MovieSerializer.has_one :user, &:owner
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.relationships_to_serialize.delete(:user)
|
||||
end
|
||||
|
||||
subject(:hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
it 'returns correct hash' do
|
||||
expect(hash[:data][:relationships][:user][:data]).to eq({ id: '3', type: :owner })
|
||||
end
|
||||
end
|
||||
|
||||
describe '#set_id' do
|
||||
let(:params) { {} }
|
||||
subject(:serializable_hash) do
|
||||
MovieSerializer.new(resource, { params: params }).serializable_hash
|
||||
end
|
||||
|
||||
context 'method name' do
|
||||
before do
|
||||
MovieSerializer.set_id :owner_id
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.set_id nil
|
||||
end
|
||||
|
||||
context 'when one record is given' do
|
||||
let(:resource) { movie }
|
||||
|
||||
it 'returns correct hash which id equals owner_id' do
|
||||
expect(serializable_hash[:data][:id].to_i).to eq movie.owner_id
|
||||
end
|
||||
end
|
||||
|
||||
context 'when an array of records is given' do
|
||||
let(:resource) { build_movies(2) }
|
||||
|
||||
it 'returns correct hash which id equals owner_id' do
|
||||
expect(serializable_hash[:data][0][:id].to_i).to eq movie.owner_id
|
||||
expect(serializable_hash[:data][1][:id].to_i).to eq movie.owner_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with block' do
|
||||
let(:params) { { prefix: 'movie' } }
|
||||
|
||||
before do
|
||||
MovieSerializer.set_id do |record, params|
|
||||
"#{params[:prefix]}-#{record.owner_id}"
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.set_id nil
|
||||
end
|
||||
|
||||
context 'when one record is given' do
|
||||
let(:resource) { movie }
|
||||
|
||||
it 'returns correct hash which id equals movie-id' do
|
||||
expect(serializable_hash[:data][:id]).to eq "movie-#{movie.owner_id}"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when an array of records is given' do
|
||||
let(:resource) { build_movies(2) }
|
||||
|
||||
it 'returns correct hash which id equals movie-id' do
|
||||
expect(serializable_hash[:data][0][:id]).to eq "movie-#{movie.owner_id}"
|
||||
expect(serializable_hash[:data][1][:id]).to eq "movie-#{movie.owner_id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a lambda' do
|
||||
let(:params) { { prefix: 'movie' } }
|
||||
|
||||
before do
|
||||
MovieSerializer.set_id ->(record) { "#{params[:prefix]}-#{record.owner_id}" }
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.set_id nil
|
||||
end
|
||||
|
||||
let(:resource) { movie }
|
||||
|
||||
it 'returns correct hash which id equals movie-id' do
|
||||
expect(serializable_hash[:data][:id]).to eq "movie-#{movie.owner_id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#use_hyphen' do
|
||||
subject { MovieSerializer.use_hyphen }
|
||||
|
||||
after do
|
||||
MovieSerializer.transform_method = nil
|
||||
end
|
||||
|
||||
it 'sets the correct transform_method when use_hyphen is used' do
|
||||
warning_message = "DEPRECATION WARNING: use_hyphen is deprecated and will be removed from fast_jsonapi 2.0 use (set_key_transform :dash) instead\n"
|
||||
expect { subject }.to output(warning_message).to_stderr
|
||||
expect(MovieSerializer.instance_variable_get(:@transform_method)).to eq :dasherize
|
||||
end
|
||||
end
|
||||
|
||||
describe '#attribute' do
|
||||
subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
context 'with block' do
|
||||
before do
|
||||
movie.release_year = 2008
|
||||
MovieSerializer.attribute :title_with_year do |record|
|
||||
"#{record.name} (#{record.release_year})"
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.attributes_to_serialize.delete(:title_with_year)
|
||||
end
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:attributes][:name]).to eq movie.name
|
||||
expect(serializable_hash[:data][:attributes][:title_with_year]).to eq "#{movie.name} (#{movie.release_year})"
|
||||
end
|
||||
end
|
||||
|
||||
context 'with &:proc' do
|
||||
before do
|
||||
movie.release_year = 2008
|
||||
MovieSerializer.attribute :released_in_year, &:release_year
|
||||
MovieSerializer.attribute :name, &:local_name
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.attributes_to_serialize.delete(:released_in_year)
|
||||
MovieSerializer.attributes_to_serialize.delete(:name)
|
||||
end
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:attributes][:name]).to eq "english #{movie.name}"
|
||||
expect(serializable_hash[:data][:attributes][:released_in_year]).to eq movie.release_year
|
||||
end
|
||||
end
|
||||
|
||||
context 'with lambda' do
|
||||
before do
|
||||
movie.release_year = 2008
|
||||
MovieSerializer.attribute :released_in_year, &:release_year
|
||||
MovieSerializer.attribute :name, ->(object) { object.local_name }
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.attributes_to_serialize.delete(:released_in_year)
|
||||
MovieSerializer.attributes_to_serialize.delete(:name)
|
||||
end
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:attributes][:name]).to eq "english #{movie.name}"
|
||||
expect(serializable_hash[:data][:attributes][:released_in_year]).to eq movie.release_year
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#meta' do
|
||||
subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
context 'with block' do
|
||||
before do
|
||||
movie.release_year = 2008
|
||||
MovieSerializer.meta do |movie|
|
||||
{
|
||||
years_since_release: year_since_release_calculator(movie.release_year)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
movie.release_year = nil
|
||||
MovieSerializer.meta_to_serialize = nil
|
||||
end
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:meta]).to eq({ years_since_release: year_since_release_calculator(movie.release_year) })
|
||||
end
|
||||
end
|
||||
|
||||
context 'with lambda' do
|
||||
before do
|
||||
movie.release_year = 2008
|
||||
MovieSerializer.meta ->(movie) { { years_since_release: year_since_release_calculator(movie.release_year) } }
|
||||
end
|
||||
|
||||
after do
|
||||
movie.release_year = nil
|
||||
MovieSerializer.meta_to_serialize = nil
|
||||
end
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:meta]).to eq({ years_since_release: year_since_release_calculator(movie.release_year) })
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def year_since_release_calculator(release_year)
|
||||
Date.current.year - release_year
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link' do
|
||||
subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
after do
|
||||
MovieSerializer.data_links = {}
|
||||
ActorSerializer.data_links = {}
|
||||
end
|
||||
|
||||
context 'with block calling instance method on serializer' do
|
||||
before do
|
||||
MovieSerializer.link(:self, &:url)
|
||||
end
|
||||
let(:url) { "http://movies.com/#{movie.id}" }
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:links][:self]).to eq url
|
||||
end
|
||||
end
|
||||
|
||||
context 'with block and param' do
|
||||
before do
|
||||
MovieSerializer.link(:public_url) do |movie_object|
|
||||
"http://movies.com/#{movie_object.id}"
|
||||
end
|
||||
end
|
||||
let(:url) { "http://movies.com/#{movie.id}" }
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:links][:public_url]).to eq url
|
||||
end
|
||||
end
|
||||
|
||||
context 'with method' do
|
||||
before do
|
||||
MovieSerializer.link(:object_id, :id)
|
||||
end
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:links][:object_id]).to eq movie.id
|
||||
end
|
||||
end
|
||||
|
||||
context 'with method and convention' do
|
||||
before do
|
||||
MovieSerializer.link(:url)
|
||||
end
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:data][:links][:url]).to eq movie.url
|
||||
end
|
||||
end
|
||||
|
||||
context 'when inheriting from a parent serializer' do
|
||||
subject(:action_serializable_hash) { ActionMovieSerializer.new(movie).serializable_hash }
|
||||
subject(:horror_serializable_hash) { HorrorMovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
it 'returns the link for the correct sub-class' do
|
||||
expect(action_serializable_hash[:data][:links][:url]).to eq "/action-movie/#{movie.id}"
|
||||
end
|
||||
end
|
||||
|
||||
describe 'optional links' do
|
||||
subject(:downloadable_serializable_hash) { OptionalDownloadableMovieSerializer.new(movie, params).serializable_hash }
|
||||
|
||||
context 'when the link is provided' do
|
||||
let(:params) { { params: { signed_url: signed_url } } }
|
||||
let(:signed_url) { 'http://example.com/download_link?signature=abcdef' }
|
||||
|
||||
it 'includes the link' do
|
||||
expect(downloadable_serializable_hash[:data][:links][:download]).to eq signed_url
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the link is not provided' do
|
||||
let(:params) { { params: {} } }
|
||||
it 'does not include the link' do
|
||||
expect(downloadable_serializable_hash[:data][:links]).to_not have_key(:download)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'optional links with a lambda' do
|
||||
subject(:downloadable_serializable_hash) { OptionalDownloadableMovieWithLambdaSerializer.new(movie).serializable_hash }
|
||||
|
||||
context 'when the link should be provided' do
|
||||
before { movie.release_year = 2001 }
|
||||
|
||||
it 'includes the link' do
|
||||
expect(downloadable_serializable_hash[:data][:links][:download]).to eq '/download/232'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the link should not be provided' do
|
||||
before { movie.release_year = 1970 }
|
||||
|
||||
it 'does not include the link' do
|
||||
expect(downloadable_serializable_hash[:data][:links]).to_not have_key(:download)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#key_transform' do
|
||||
subject(:hash) { movie_serializer_class.new(build_movies(2), include: [:movie_type]).serializable_hash }
|
||||
|
||||
let(:movie_serializer_class) { "#{key_transform}_movie_serializer".classify.constantize }
|
||||
|
||||
before(:context) do
|
||||
[:dash, :camel, :camel_lower, :underscore].each do |key_transform|
|
||||
movie_serializer_name = "#{key_transform}_movie_serializer".classify
|
||||
movie_type_serializer_name = "#{key_transform}_movie_type_serializer".classify
|
||||
# https://stackoverflow.com/questions/4113479/dynamic-class-definition-with-a-class-name
|
||||
movie_serializer_class = Object.const_set(movie_serializer_name, Class.new)
|
||||
# https://rubymonk.com/learning/books/5-metaprogramming-ruby-ascent/chapters/24-eval/lessons/67-instance-eval
|
||||
movie_serializer_class.instance_eval do
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
set_key_transform key_transform
|
||||
attributes :name, :release_year
|
||||
has_many :actors
|
||||
belongs_to :owner, record_type: :user
|
||||
belongs_to :movie_type, serializer: "#{key_transform}_movie_type".to_sym
|
||||
end
|
||||
movie_type_serializer_class = Object.const_set(movie_type_serializer_name, Class.new)
|
||||
movie_type_serializer_class.instance_eval do
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_key_transform key_transform
|
||||
attributes :name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when key_transform is dash' do
|
||||
let(:key_transform) { :dash }
|
||||
|
||||
it_behaves_like 'returning key transformed hash', :'movie-type', :'dash-movie-type', :'release-year'
|
||||
end
|
||||
|
||||
context 'when key_transform is camel' do
|
||||
let(:key_transform) { :camel }
|
||||
|
||||
it_behaves_like 'returning key transformed hash', :MovieType, :CamelMovieType, :ReleaseYear
|
||||
end
|
||||
|
||||
context 'when key_transform is camel_lower' do
|
||||
let(:key_transform) { :camel_lower }
|
||||
|
||||
it_behaves_like 'returning key transformed hash', :movieType, :camelLowerMovieType, :releaseYear
|
||||
end
|
||||
|
||||
context 'when key_transform is underscore' do
|
||||
let(:key_transform) { :underscore }
|
||||
|
||||
it_behaves_like 'returning key transformed hash', :movie_type, :underscore_movie_type, :release_year
|
||||
end
|
||||
end
|
||||
|
||||
describe '#set_key_transform after #set_type' do
|
||||
subject(:serializable_hash) { MovieSerializer.new(movie).serializable_hash }
|
||||
|
||||
before do
|
||||
MovieSerializer.set_type type_name
|
||||
MovieSerializer.set_key_transform :camel
|
||||
end
|
||||
|
||||
after do
|
||||
MovieSerializer.transform_method = nil
|
||||
MovieSerializer.set_type :movie
|
||||
end
|
||||
|
||||
context 'when sets singular type name' do
|
||||
let(:type_name) { :film }
|
||||
|
||||
it 'returns correct hash which type equals transformed set_type value' do
|
||||
expect(serializable_hash[:data][:type]).to eq :Film
|
||||
end
|
||||
end
|
||||
|
||||
context 'when sets plural type name' do
|
||||
let(:type_name) { :films }
|
||||
|
||||
it 'returns correct hash which type equals transformed set_type value' do
|
||||
expect(serializable_hash[:data][:type]).to eq :Films
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,81 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
let(:fields) do
|
||||
{
|
||||
movie: %i[name actors advertising_campaign],
|
||||
actor: %i[name agency]
|
||||
}
|
||||
end
|
||||
|
||||
it 'only returns specified fields' do
|
||||
hash = MovieSerializer.new(movie, fields: fields).serializable_hash
|
||||
|
||||
expect(hash[:data][:attributes].keys.sort).to eq %i[name]
|
||||
end
|
||||
|
||||
it 'only returns specified relationships' do
|
||||
hash = MovieSerializer.new(movie, fields: fields).serializable_hash
|
||||
|
||||
expect(hash[:data][:relationships].keys.sort).to eq %i[actors advertising_campaign]
|
||||
end
|
||||
|
||||
it 'returns no fields when none are specified' do
|
||||
hash = MovieSerializer.new(movie, fields: { movie: [] }).serializable_hash
|
||||
|
||||
expect(hash[:data][:attributes].keys).to eq []
|
||||
end
|
||||
|
||||
it 'returns no relationships when none are specified' do
|
||||
hash = MovieSerializer.new(movie, fields: { movie: [] }).serializable_hash
|
||||
|
||||
expect(hash[:data][:relationships].keys).to eq []
|
||||
end
|
||||
|
||||
it 'only returns specified fields for included relationships' do
|
||||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors]).serializable_hash
|
||||
|
||||
expect(hash[:included].first[:attributes].keys.sort).to eq %i[name]
|
||||
end
|
||||
|
||||
it 'only returns specified relationships for included relationships' do
|
||||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors advertising_campaign]).serializable_hash
|
||||
|
||||
expect(hash[:included].first[:relationships].keys.sort).to eq %i[agency]
|
||||
end
|
||||
|
||||
it 'returns all fields for included relationships when no explicit fields have been specified' do
|
||||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors advertising_campaign]).serializable_hash
|
||||
|
||||
expect(hash[:included][3][:attributes].keys.sort).to eq %i[id name]
|
||||
end
|
||||
|
||||
it 'returns all fields for included relationships when no explicit fields have been specified' do
|
||||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors advertising_campaign]).serializable_hash
|
||||
|
||||
expect(hash[:included][3][:relationships].keys.sort).to eq %i[movie]
|
||||
end
|
||||
|
||||
context 'with no included fields specified' do
|
||||
let(:fields) do
|
||||
{
|
||||
movie: %i[name actors advertising_campaign],
|
||||
actor: []
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns no fields for included relationships when none are specified' do
|
||||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors advertising_campaign]).serializable_hash
|
||||
|
||||
expect(hash[:included][2][:attributes].keys).to eq []
|
||||
end
|
||||
|
||||
it 'returns no relationships when none are specified' do
|
||||
hash = MovieSerializer.new(movie, fields: fields, include: %i[actors advertising_campaign]).serializable_hash
|
||||
|
||||
expect(hash[:included][2][:relationships].keys).to eq []
|
||||
end
|
||||
end
|
||||
end
|
@ -1,163 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
after(:all) do
|
||||
classes_to_remove = %i[
|
||||
User
|
||||
UserSerializer
|
||||
Country
|
||||
CountrySerializer
|
||||
Employee
|
||||
EmployeeSerializer
|
||||
Photo
|
||||
PhotoSerializer
|
||||
EmployeeAccount
|
||||
]
|
||||
classes_to_remove.each do |klass_name|
|
||||
Object.send(:remove_const, klass_name) if Object.constants.include?(klass_name)
|
||||
end
|
||||
end
|
||||
|
||||
class User
|
||||
attr_accessor :id, :first_name, :last_name, :uuid
|
||||
|
||||
attr_accessor :address_ids, :country_id, :photo_id
|
||||
end
|
||||
|
||||
class UserSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :user
|
||||
set_id :uuid
|
||||
attributes :first_name, :last_name
|
||||
|
||||
attribute :full_name do |user, _params|
|
||||
"#{user.first_name} #{user.last_name}"
|
||||
end
|
||||
|
||||
has_many :addresses, cached: true
|
||||
belongs_to :country
|
||||
has_one :photo
|
||||
end
|
||||
|
||||
class Address
|
||||
attr_accessor :street, :city, :state, :postal_code
|
||||
end
|
||||
|
||||
class AddressSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :street, :city, :state, :postal_code
|
||||
end
|
||||
|
||||
class Photo
|
||||
attr_accessor :id, :user_id
|
||||
end
|
||||
|
||||
class PhotoSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :id, :name
|
||||
end
|
||||
|
||||
class Country
|
||||
attr_accessor :id, :name
|
||||
end
|
||||
|
||||
class CountrySerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :name
|
||||
end
|
||||
|
||||
class EmployeeAccount
|
||||
attr_accessor :id, :employee_id
|
||||
end
|
||||
|
||||
class EmployeeAccountSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
belongs_to :employee
|
||||
end
|
||||
|
||||
class Employee < User
|
||||
attr_accessor :id, :location, :compensation
|
||||
attr_accessor :account_id
|
||||
end
|
||||
|
||||
class EmployeeSerializer < UserSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :location
|
||||
attributes :compensation
|
||||
|
||||
has_one :account, serializer: EmployeeAccountSerializer
|
||||
end
|
||||
|
||||
it 'sets the correct record type' do
|
||||
expect(EmployeeSerializer.reflected_record_type).to eq :employee
|
||||
expect(EmployeeSerializer.record_type).to eq :employee
|
||||
end
|
||||
|
||||
context 'when testing inheritance of attributes' do
|
||||
it 'includes parent attributes' do
|
||||
subclass_attributes = EmployeeSerializer.attributes_to_serialize
|
||||
superclass_attributes = UserSerializer.attributes_to_serialize
|
||||
expect(subclass_attributes).to include(superclass_attributes)
|
||||
end
|
||||
|
||||
it 'returns inherited attribute with a block correctly' do
|
||||
e = Employee.new
|
||||
e.id = 1
|
||||
e.first_name = 'S'
|
||||
e.last_name = 'K'
|
||||
attributes_hash = EmployeeSerializer.new(e).serializable_hash[:data][:attributes]
|
||||
expect(attributes_hash).to include(full_name: 'S K')
|
||||
end
|
||||
|
||||
it 'includes child attributes' do
|
||||
expect(EmployeeSerializer.attributes_to_serialize[:location].method).to eq(:location)
|
||||
end
|
||||
|
||||
it 'doesnt change parent class attributes' do
|
||||
expect(UserSerializer.attributes_to_serialize).not_to have_key(:location)
|
||||
end
|
||||
|
||||
it 'inherits the id source' do
|
||||
e = Employee.new
|
||||
e.id = 2
|
||||
e.uuid = SecureRandom.uuid
|
||||
id = EmployeeSerializer.new(e).serializable_hash[:data][:id]
|
||||
expect(id).to eq(e.uuid)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when testing inheritance of relationship' do
|
||||
it 'includes parent relationships' do
|
||||
subclass_relationships = EmployeeSerializer.relationships_to_serialize
|
||||
superclass_relationships = UserSerializer.relationships_to_serialize
|
||||
expect(subclass_relationships).to include(superclass_relationships)
|
||||
end
|
||||
|
||||
it 'returns inherited relationship correctly' do
|
||||
e = Employee.new
|
||||
e.country_id = 1
|
||||
relationships_hash = EmployeeSerializer.new(e).serializable_hash[:data][:relationships][:country]
|
||||
expect(relationships_hash).to include(data: { id: '1', type: :country })
|
||||
end
|
||||
|
||||
it 'includes child relationships' do
|
||||
expect(EmployeeSerializer.relationships_to_serialize.keys).to include(:account)
|
||||
end
|
||||
|
||||
it 'doesnt change parent class attributes' do
|
||||
expect(UserSerializer.relationships_to_serialize.keys).not_to include(:account)
|
||||
end
|
||||
|
||||
it 'includes parent cached relationships' do
|
||||
subclass_relationships = EmployeeSerializer.cachable_relationships_to_serialize
|
||||
superclass_relationships = UserSerializer.cachable_relationships_to_serialize
|
||||
expect(subclass_relationships).to include(superclass_relationships)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when test inheritence of other attributes' do
|
||||
it 'inherits the tranform method' do
|
||||
expect(UserSerializer.transform_method).to eq EmployeeSerializer.transform_method
|
||||
end
|
||||
end
|
||||
end
|
@ -1,99 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
class List
|
||||
attr_accessor :id, :name, :items
|
||||
end
|
||||
|
||||
class ChecklistItem
|
||||
attr_accessor :id, :name
|
||||
end
|
||||
|
||||
class Car
|
||||
attr_accessor :id, :model, :year
|
||||
end
|
||||
|
||||
class Animal
|
||||
attr_accessor :id, :uuid, :species
|
||||
end
|
||||
|
||||
class ChecklistItemSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :checklist_item
|
||||
attributes :name
|
||||
set_key_transform :dash
|
||||
end
|
||||
|
||||
class CarSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :car
|
||||
attributes :model, :year
|
||||
set_key_transform :dash
|
||||
end
|
||||
|
||||
class AnimalSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :checklist_item
|
||||
attributes :uuid, :species
|
||||
end
|
||||
|
||||
class ListSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :list
|
||||
attributes :name
|
||||
set_key_transform :dash
|
||||
has_many :items, polymorphic: true
|
||||
end
|
||||
|
||||
class ZooSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :list
|
||||
attributes :name
|
||||
has_many :items, polymorphic: true, id_method_name: :uuid
|
||||
end
|
||||
|
||||
let(:car) do
|
||||
car = Car.new
|
||||
car.id = 1
|
||||
car.model = 'Toyota Corolla'
|
||||
car.year = 1987
|
||||
car
|
||||
end
|
||||
|
||||
let(:checklist_item) do
|
||||
checklist_item = ChecklistItem.new
|
||||
checklist_item.id = 2
|
||||
checklist_item.name = 'Do this action!'
|
||||
checklist_item
|
||||
end
|
||||
|
||||
let(:animal) do
|
||||
animal = Animal.new
|
||||
animal.id = 1
|
||||
animal.species = 'Mellivora capensis'
|
||||
animal.uuid = SecureRandom.uuid
|
||||
animal
|
||||
end
|
||||
|
||||
context 'when serializing id and type of polymorphic relationships' do
|
||||
it 'should return correct type when transform_method is specified' do
|
||||
list = List.new
|
||||
list.id = 1
|
||||
list.items = [checklist_item, car]
|
||||
list_hash = ListSerializer.new(list).to_hash
|
||||
record_type = list_hash[:data][:relationships][:items][:data][0][:type]
|
||||
expect(record_type).to eq 'checklist-item'.to_sym
|
||||
record_type = list_hash[:data][:relationships][:items][:data][1][:type]
|
||||
expect(record_type).to eq 'car'.to_sym
|
||||
end
|
||||
|
||||
it 'should use the correct id method on associated objects' do
|
||||
list = List.new
|
||||
list.id = 1
|
||||
list.items = [animal]
|
||||
list_hash = ZooSerializer.new(list).to_hash
|
||||
id = list_hash[:data][:relationships][:items][:data][0][:id]
|
||||
expect(id).to eq animal.uuid
|
||||
end
|
||||
end
|
||||
end
|
@ -1,111 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
context 'params option' do
|
||||
let(:hash) { serializer.serializable_hash }
|
||||
|
||||
context 'generating links for a serializer relationship' do
|
||||
let(:params) { {} }
|
||||
let(:options_with_params) { { params: params } }
|
||||
let(:relationship_url) { "http://movies.com/#{movie.id}/relationships/actors" }
|
||||
let(:related_url) { "http://movies.com/movies/#{movie.name.parameterize}/actors/" }
|
||||
|
||||
before(:context) do
|
||||
class MovieSerializer
|
||||
has_many :actors, lazy_load_data: false, links: {
|
||||
self: :actors_relationship_url,
|
||||
related: lambda { |object, params = {}|
|
||||
"#{params.key?(:secure) ? 'https' : 'http'}://movies.com/movies/#{object.name.parameterize}/actors/"
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a single record' do
|
||||
let(:serializer) { MovieSerializer.new(movie, options_with_params) }
|
||||
let(:links) { hash[:data][:relationships][:actors][:links] }
|
||||
|
||||
it 'handles relationship links that call a method' do
|
||||
expect(links).to be_present
|
||||
expect(links[:self]).to eq(relationship_url)
|
||||
end
|
||||
|
||||
it 'handles relationship links that call a proc' do
|
||||
expect(links).to be_present
|
||||
expect(links[:related]).to eq(related_url)
|
||||
end
|
||||
|
||||
context 'with serializer params' do
|
||||
let(:params) { { secure: true } }
|
||||
let(:secure_related_url) { related_url.gsub('http', 'https') }
|
||||
|
||||
it 'passes the params to the link serializer correctly' do
|
||||
expect(links).to be_present
|
||||
expect(links[:related]).to eq(secure_related_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'lazy loading relationship data' do
|
||||
before(:context) do
|
||||
class LazyLoadingMovieSerializer < MovieSerializer
|
||||
has_many :actors, lazy_load_data: true, links: {
|
||||
related: :actors_relationship_url
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
let(:serializer) { LazyLoadingMovieSerializer.new(movie) }
|
||||
let(:actor_hash) { hash[:data][:relationships][:actors] }
|
||||
|
||||
it 'does not include the :data key' do
|
||||
expect(actor_hash).to be_present
|
||||
expect(actor_hash).not_to have_key(:data)
|
||||
end
|
||||
end
|
||||
|
||||
context 'including lazy loaded relationships' do
|
||||
before(:context) do
|
||||
class LazyLoadingMovieSerializer < MovieSerializer
|
||||
has_many :actors, lazy_load_data: true, links: {
|
||||
related: :actors_relationship_url
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
let(:serializer) { LazyLoadingMovieSerializer.new(movie, include: [:actors]) }
|
||||
let(:actor_hash) { hash[:data][:relationships][:actors] }
|
||||
|
||||
it 'includes the :data key' do
|
||||
expect(actor_hash).to be_present
|
||||
expect(actor_hash).to have_key(:data)
|
||||
end
|
||||
end
|
||||
|
||||
context 'relationship links defined by a method on the object' do
|
||||
before(:context) do
|
||||
class Movie
|
||||
def relationship_links
|
||||
{ self: "http://movies.com/#{id}/relationships/actors" }
|
||||
end
|
||||
end
|
||||
|
||||
class LinksPassingMovieSerializer < MovieSerializer
|
||||
has_many :actors, links: :relationship_links
|
||||
end
|
||||
end
|
||||
|
||||
let(:serializer) { LinksPassingMovieSerializer.new(movie) }
|
||||
let(:links) { hash[:data][:relationships][:actors][:links] }
|
||||
let(:relationship_url) { "http://movies.com/#{movie.id}/relationships/actors" }
|
||||
|
||||
it 'generates relationship links in the object' do
|
||||
expect(links).to be_present
|
||||
expect(links[:self]).to eq(relationship_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,63 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
context 'params option' do
|
||||
let(:hash) { serializer.serializable_hash }
|
||||
|
||||
before(:context) do
|
||||
class MovieSerializer
|
||||
has_many :agencies do |movie, params|
|
||||
movie.actors.map(&:agency) if params[:authorized]
|
||||
end
|
||||
|
||||
belongs_to :primary_agency do |movie, params|
|
||||
movie.actors.map(&:agency)[0] if params[:authorized]
|
||||
end
|
||||
|
||||
belongs_to :secondary_agency do |movie|
|
||||
movie.actors.map(&:agency)[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'passing params to the serializer' do
|
||||
let(:params) { { authorized: true } }
|
||||
let(:options_with_params) { { params: params } }
|
||||
|
||||
context 'with a single record' do
|
||||
let(:serializer) { MovieSerializer.new(movie, options_with_params) }
|
||||
|
||||
it 'handles relationships that use params' do
|
||||
ids = hash[:data][:relationships][:agencies][:data].map { |a| a[:id] }
|
||||
ids.map!(&:to_i)
|
||||
expect(ids).to eq [0, 1, 2]
|
||||
end
|
||||
|
||||
it "handles relationships that don't use params" do
|
||||
expect(hash[:data][:relationships][:secondary_agency][:data]).to include({ id: 1.to_s })
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a list of records' do
|
||||
let(:movies) { build_movies(3) }
|
||||
let(:params) { { authorized: true } }
|
||||
let(:serializer) { MovieSerializer.new(movies, options_with_params) }
|
||||
|
||||
it 'handles relationship params when passing params to a list of resources' do
|
||||
relationships_hashes = hash[:data].map { |a| a[:relationships][:agencies][:data] }.uniq.flatten
|
||||
expect(relationships_hashes.map { |a| a[:id].to_i }).to contain_exactly 0, 1, 2
|
||||
|
||||
uniq_count = hash[:data].map { |a| a[:relationships][:primary_agency] }.uniq.count
|
||||
expect(uniq_count).to eq 1
|
||||
end
|
||||
|
||||
it 'handles relationships without params' do
|
||||
uniq_count = hash[:data].map { |a| a[:relationships][:secondary_agency] }.uniq.count
|
||||
expect(uniq_count).to eq 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,105 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
class Person
|
||||
attr_accessor :id, :name, :assets
|
||||
end
|
||||
|
||||
class House
|
||||
attr_accessor :id, :address
|
||||
end
|
||||
|
||||
class Car
|
||||
attr_accessor :id, :model, :year
|
||||
end
|
||||
|
||||
class PersonSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :person
|
||||
attributes :name
|
||||
set_key_transform :dash
|
||||
|
||||
has_many :assets, serializer: lambda { |object|
|
||||
if object.is_a?(House)
|
||||
HouseSerializer
|
||||
elsif object.is_a?(Car)
|
||||
CarSerializer
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
class HouseSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :house
|
||||
attributes :address
|
||||
set_key_transform :dash
|
||||
end
|
||||
|
||||
class CarSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :car
|
||||
attributes :model, :year
|
||||
set_key_transform :dash
|
||||
end
|
||||
|
||||
let(:house) do
|
||||
house = House.new
|
||||
house.id = 123
|
||||
house.address = '1600 Pennsylvania Avenue'
|
||||
house
|
||||
end
|
||||
|
||||
let(:car) do
|
||||
car = Car.new
|
||||
car.id = 456
|
||||
car.model = 'Toyota Corolla'
|
||||
car.year = 1987
|
||||
car
|
||||
end
|
||||
|
||||
context 'when serializing a relationship with a serializer block' do
|
||||
it 'should output the correct JSON based on the proper serializer' do
|
||||
person = Person.new
|
||||
person.id = 1
|
||||
person.name = 'Bob'
|
||||
person.assets = [house, car]
|
||||
person_hash = PersonSerializer.new(person).to_hash
|
||||
|
||||
relationships = person_hash[:data][:relationships]
|
||||
house_relationship = relationships[:assets][:data][0]
|
||||
expect(house_relationship[:type].to_s).to eq 'house'
|
||||
expect(house_relationship[:id].to_s).to eq house.id.to_s
|
||||
car_relationship = relationships[:assets][:data][1]
|
||||
expect(car_relationship[:type].to_s).to eq 'car'
|
||||
expect(car_relationship[:id].to_s).to eq car.id.to_s
|
||||
|
||||
expect(person_hash[:data]).to_not have_key :included
|
||||
end
|
||||
|
||||
it 'should output the correct included records' do
|
||||
person = Person.new
|
||||
person.id = 1
|
||||
person.name = 'Bob'
|
||||
person.assets = [house, car]
|
||||
person_hash = PersonSerializer.new(person, { include: [:assets] }).to_hash
|
||||
|
||||
relationships = person_hash[:data][:relationships]
|
||||
house_relationship = relationships[:assets][:data][0]
|
||||
expect(house_relationship[:type].to_s).to eq 'house'
|
||||
expect(house_relationship[:id].to_s).to eq house.id.to_s
|
||||
car_relationship = relationships[:assets][:data][1]
|
||||
expect(car_relationship[:type].to_s).to eq 'car'
|
||||
expect(car_relationship[:id].to_s).to eq car.id.to_s
|
||||
|
||||
included = person_hash[:included]
|
||||
house_included = included[0]
|
||||
expect(house_included[:type].to_s).to eq 'house'
|
||||
expect(house_included[:id].to_s).to eq house.id.to_s
|
||||
expect(house_included[:attributes][:address]).to eq house.address
|
||||
car_included = included[1]
|
||||
expect(car_included[:type].to_s).to eq 'car'
|
||||
expect(car_included[:id].to_s).to eq car.id.to_s
|
||||
expect(car_included[:attributes][:model]).to eq car.model
|
||||
end
|
||||
end
|
||||
end
|
@ -1,587 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
let(:movies) { build_movies(2) }
|
||||
|
||||
context 'when testing instance methods of object serializer' do
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:links] = { self: 'self' }
|
||||
options[:include] = [:actors]
|
||||
serializable_hash = MovieSerializer.new(movies, options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data].length).to eq 2
|
||||
expect(serializable_hash[:data][0][:relationships].length).to eq 4
|
||||
expect(serializable_hash[:data][0][:attributes].length).to eq 2
|
||||
|
||||
expect(serializable_hash[:meta]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:links]).to be_instance_of(Hash)
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included][0]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:included].length).to eq 3
|
||||
|
||||
serializable_hash = MovieSerializer.new(movie).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:meta]).to be nil
|
||||
expect(serializable_hash[:links]).to be nil
|
||||
expect(serializable_hash[:included]).to be nil
|
||||
end
|
||||
|
||||
it 'returns correct nested includes when serializable_hash is called' do
|
||||
# 3 actors, 3 agencies
|
||||
include_object_total = 6
|
||||
|
||||
options = {}
|
||||
options[:include] = [:actors, :'actors.agency']
|
||||
serializable_hash = MovieSerializer.new([movie], options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included].length).to eq include_object_total
|
||||
(0..include_object_total - 1).each do |include|
|
||||
expect(serializable_hash[:included][include]).to be_instance_of(Hash)
|
||||
end
|
||||
|
||||
options[:include] = [:'actors.agency']
|
||||
serializable_hash = MovieSerializer.new([movie], options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included].length).to eq include_object_total
|
||||
(0..include_object_total - 1).each do |include|
|
||||
expect(serializable_hash[:included][include]).to be_instance_of(Hash)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns correct number of records when serialized_json is called for an array' do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
json = MovieSerializer.new(movies, options).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data'].length).to eq 2
|
||||
expect(serializable_hash['meta']).to be_instance_of(Hash)
|
||||
end
|
||||
|
||||
it 'returns correct id when serialized_json is called for a single object' do
|
||||
json = MovieSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['id']).to eq movie.id.to_s
|
||||
end
|
||||
|
||||
it 'returns correct json when serializing nil' do
|
||||
json = MovieSerializer.new(nil).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']).to eq nil
|
||||
end
|
||||
|
||||
it 'returns correct json when record id is nil' do
|
||||
movie.id = nil
|
||||
json = MovieSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['id']).to be nil
|
||||
end
|
||||
|
||||
it 'returns correct json when has_many returns []' do
|
||||
movie.actor_ids = []
|
||||
json = MovieSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['relationships']['actors']['data'].length).to eq 0
|
||||
end
|
||||
|
||||
it 'returns correct json when belongs_to returns nil' do
|
||||
movie.owner_id = nil
|
||||
json = MovieSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['relationships']['owner']['data']).to be nil
|
||||
end
|
||||
|
||||
it 'returns correct json when belongs_to returns nil and there is a block for the relationship' do
|
||||
movie.owner_id = nil
|
||||
json = MovieSerializer.new(movie, { include: [:owner] }).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['relationships']['owner']['data']).to be nil
|
||||
end
|
||||
|
||||
it 'returns correct json when has_one returns nil' do
|
||||
supplier.account_id = nil
|
||||
json = SupplierSerializer.new(supplier).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['relationships']['account']['data']).to be nil
|
||||
end
|
||||
|
||||
it 'returns correct json when serializing []' do
|
||||
json = MovieSerializer.new([]).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']).to eq []
|
||||
end
|
||||
|
||||
describe '#as_json' do
|
||||
it 'returns a json hash' do
|
||||
json_hash = MovieSerializer.new(movie).as_json
|
||||
expect(json_hash['data']['id']).to eq movie.id.to_s
|
||||
end
|
||||
|
||||
it 'returns multiple records' do
|
||||
json_hash = MovieSerializer.new(movies).as_json
|
||||
expect(json_hash['data'].length).to eq 2
|
||||
end
|
||||
|
||||
it 'removes non-relevant attributes' do
|
||||
movie.director = 'steven spielberg'
|
||||
json_hash = MovieSerializer.new(movie).as_json
|
||||
expect(json_hash['data']['director']).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns errors when serializing with non-existent includes key' do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:include] = [:blah_blah]
|
||||
expect { MovieSerializer.new(movies, options).serializable_hash }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'returns errors when serializing with non-existent and existent includes keys' do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:include] = [:actors, :blah_blah]
|
||||
expect { MovieSerializer.new([movie, movie], options).serializable_hash }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'does not throw an error with non-empty string array includes key' do
|
||||
options = {}
|
||||
options[:include] = ['actors']
|
||||
expect { MovieSerializer.new(movie, options) }.not_to raise_error
|
||||
end
|
||||
|
||||
it 'does not throw an error with non-empty string array includes keys' do
|
||||
options = {}
|
||||
options[:include] = ['actors', 'owner']
|
||||
expect { MovieSerializer.new(movie, options) }.not_to raise_error
|
||||
end
|
||||
|
||||
it 'returns keys when serializing with empty string/nil array includes key' do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:include] = ['']
|
||||
expect(MovieSerializer.new(movies, options).serializable_hash.keys).to eq [:data, :meta]
|
||||
options[:include] = [nil]
|
||||
expect(MovieSerializer.new(movies, options).serializable_hash.keys).to eq [:data, :meta]
|
||||
end
|
||||
end
|
||||
|
||||
context 'id attribute is the same for actors and not a primary key' do
|
||||
before do
|
||||
ActorSerializer.set_id :email
|
||||
movie.actor_ids = [0, 0, 0]
|
||||
class << movie
|
||||
def actors
|
||||
super.each_with_index { |actor, i| actor.email = "actor#{i}@email.com" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
after { ActorSerializer.set_id nil }
|
||||
|
||||
let(:options) { { include: ['actors'] } }
|
||||
subject { MovieSerializer.new(movie, options).serializable_hash }
|
||||
|
||||
it 'returns all actors in includes' do
|
||||
expect(
|
||||
subject[:included].select { |i| i[:type] == :actor }.map { |i| i[:id] }
|
||||
).to eq(
|
||||
movie.actors.map(&:email)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'nested includes' do
|
||||
it 'has_many to belongs_to: returns correct nested includes when serializable_hash is called' do
|
||||
# 3 actors, 3 agencies
|
||||
include_object_total = 6
|
||||
|
||||
options = {}
|
||||
options[:include] = [:actors, :'actors.agency']
|
||||
serializable_hash = MovieSerializer.new([movie], options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included].length).to eq include_object_total
|
||||
(0..include_object_total - 1).each do |include|
|
||||
expect(serializable_hash[:included][include]).to be_instance_of(Hash)
|
||||
end
|
||||
|
||||
options[:include] = [:'actors.agency']
|
||||
serializable_hash = MovieSerializer.new([movie], options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included].length).to eq include_object_total
|
||||
(0..include_object_total - 1).each do |include|
|
||||
expect(serializable_hash[:included][include]).to be_instance_of(Hash)
|
||||
end
|
||||
end
|
||||
|
||||
it '`has_many` to `belongs_to` to `belongs_to` - returns correct nested includes when serializable_hash is called' do
|
||||
# 3 actors, 3 agencies, 1 state
|
||||
include_object_total = 7
|
||||
|
||||
options = {}
|
||||
options[:include] = [:actors, :'actors.agency', :'actors.agency.state']
|
||||
serializable_hash = MovieSerializer.new([movie], options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included].length).to eq include_object_total
|
||||
|
||||
actors_serialized = serializable_hash[:included].find_all { |included| included[:type] == :actor }.map { |included| included[:id].to_i }
|
||||
agencies_serialized = serializable_hash[:included].find_all { |included| included[:type] == :agency }.map { |included| included[:id].to_i }
|
||||
states_serialized = serializable_hash[:included].find_all { |included| included[:type] == :state }.map { |included| included[:id].to_i }
|
||||
|
||||
movie.actors.each do |actor|
|
||||
expect(actors_serialized).to include(actor.id)
|
||||
end
|
||||
|
||||
agencies = movie.actors.map(&:agency).uniq
|
||||
agencies.each do |agency|
|
||||
expect(agencies_serialized).to include(agency.id)
|
||||
end
|
||||
|
||||
states = agencies.map(&:state).uniq
|
||||
states.each do |state|
|
||||
expect(states_serialized).to include(state.id)
|
||||
end
|
||||
end
|
||||
|
||||
it 'has_many => has_one returns correct nested includes when serializable_hash is called' do
|
||||
options = {}
|
||||
options[:include] = [:movies, :'movies.advertising_campaign']
|
||||
serializable_hash = MovieTypeSerializer.new([movie_type], options).serializable_hash
|
||||
|
||||
movies_serialized = serializable_hash[:included].find_all { |included| included[:type] == :movie }.map { |included| included[:id].to_i }
|
||||
advertising_campaigns_serialized = serializable_hash[:included].find_all { |included| included[:type] == :advertising_campaign }.map { |included| included[:id].to_i }
|
||||
|
||||
movies = movie_type.movies
|
||||
movies.each do |movie|
|
||||
expect(movies_serialized).to include(movie.id)
|
||||
end
|
||||
|
||||
advertising_campaigns = movies.map(&:advertising_campaign)
|
||||
advertising_campaigns.each do |advertising_campaign|
|
||||
expect(advertising_campaigns_serialized).to include(advertising_campaign.id)
|
||||
end
|
||||
end
|
||||
|
||||
it 'belongs_to: returns correct nested includes when nested attributes are nil when serializable_hash is called' do
|
||||
class Movie
|
||||
def advertising_campaign
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
options = {}
|
||||
options[:include] = [:movies, :'movies.advertising_campaign']
|
||||
|
||||
serializable_hash = MovieTypeSerializer.new([movie_type], options).serializable_hash
|
||||
|
||||
movies_serialized = serializable_hash[:included].find_all { |included| included[:type] == :movie }.map { |included| included[:id].to_i }
|
||||
|
||||
movies = movie_type.movies
|
||||
movies.each do |movie|
|
||||
expect(movies_serialized).to include(movie.id)
|
||||
end
|
||||
end
|
||||
|
||||
it 'polymorphic has_many: returns correct nested includes when serializable_hash is called' do
|
||||
options = {}
|
||||
options[:include] = [:groupees]
|
||||
|
||||
serializable_hash = GroupSerializer.new([group], options).serializable_hash
|
||||
|
||||
persons_serialized = serializable_hash[:included].find_all { |included| included[:type] == :person }.map { |included| included[:id].to_i }
|
||||
groups_serialized = serializable_hash[:included].find_all { |included| included[:type] == :group }.map { |included| included[:id].to_i }
|
||||
|
||||
persons = group.groupees.find_all { |groupee| groupee.is_a?(Person) }
|
||||
persons.each do |person|
|
||||
expect(persons_serialized).to include(person.id)
|
||||
end
|
||||
|
||||
groups = group.groupees.find_all { |groupee| groupee.is_a?(Group) }
|
||||
groups.each do |group|
|
||||
expect(groups_serialized).to include(group.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when testing included do block of object serializer' do
|
||||
it 'should set default_type based on serializer class name' do
|
||||
class BlahSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
expect(BlahSerializer.record_type).to be :blah
|
||||
end
|
||||
|
||||
it 'should set default_type for a multi word class name' do
|
||||
class BlahBlahSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
expect(BlahBlahSerializer.record_type).to be :blah_blah
|
||||
end
|
||||
|
||||
it 'should set default_type for a namespaced serializer' do
|
||||
module V1
|
||||
class BlahSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
end
|
||||
expect(V1::BlahSerializer.record_type).to be :blah
|
||||
end
|
||||
|
||||
it 'shouldnt set default_type for a serializer that doesnt follow convention' do
|
||||
class BlahBlahSerializerBuilder
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
expect(BlahBlahSerializerBuilder.record_type).to be_nil
|
||||
end
|
||||
|
||||
it 'shouldnt set default_type for an anonymous serializer' do
|
||||
serializer_class = Class.new do
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
expect(serializer_class.record_type).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when serializing included, serialize any links' do
|
||||
before do
|
||||
ActorSerializer.link(:self, &:url)
|
||||
end
|
||||
subject(:serializable_hash) do
|
||||
options = {}
|
||||
options[:include] = [:actors]
|
||||
MovieSerializer.new(movie, options).serializable_hash
|
||||
end
|
||||
let(:actor) { movie.actors.first }
|
||||
let(:url) { "http://movies.com/actors/#{actor.id}" }
|
||||
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
expect(serializable_hash[:included][0][:links][:self]).to eq url
|
||||
end
|
||||
end
|
||||
|
||||
context 'when serializing included, params should be available in any serializer' do
|
||||
subject(:serializable_hash) do
|
||||
options = {}
|
||||
options[:include] = [:"actors.awards"]
|
||||
options[:params] = { include_award_year: true }
|
||||
MovieSerializer.new(movie, options).serializable_hash
|
||||
end
|
||||
let(:actor) { movie.actors.first }
|
||||
let(:award) { actor.awards.first }
|
||||
let(:year) { award.year }
|
||||
|
||||
it 'passes params to deeply nested includes' do
|
||||
expect(year).to_not be_blank
|
||||
expect(serializable_hash[:included][0][:attributes][:year]).to eq year
|
||||
end
|
||||
end
|
||||
|
||||
context 'when is_collection option present' do
|
||||
subject { MovieSerializer.new(resource, is_collection_options).serializable_hash }
|
||||
|
||||
context 'autodetect' do
|
||||
let(:is_collection_options) { {} }
|
||||
|
||||
context 'collection if no option present' do
|
||||
let(:resource) { [movie] }
|
||||
it { expect(subject[:data]).to be_a(Array) }
|
||||
end
|
||||
|
||||
context 'single if no option present' do
|
||||
let(:resource) { movie }
|
||||
it { expect(subject[:data]).to be_a(Hash) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'force is_collection to true' do
|
||||
let(:is_collection_options) { { is_collection: true } }
|
||||
|
||||
context 'collection will pass' do
|
||||
let(:resource) { [movie] }
|
||||
it { expect(subject[:data]).to be_a(Array) }
|
||||
end
|
||||
|
||||
context 'single will raise error' do
|
||||
let(:resource) { movie }
|
||||
it { expect { subject }.to raise_error(NoMethodError, /method(.*)each/) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'force is_collection to false' do
|
||||
let(:is_collection_options) { { is_collection: false } }
|
||||
|
||||
context 'collection will fail without id' do
|
||||
let(:resource) { [movie] }
|
||||
it { expect { subject }.to raise_error(FastJsonapi::MandatoryField, /id is a mandatory field/) }
|
||||
end
|
||||
|
||||
context 'single will pass' do
|
||||
let(:resource) { movie }
|
||||
it { expect(subject[:data]).to be_a(Hash) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when optional attributes are determined by record data' do
|
||||
it 'returns optional attribute when attribute is included' do
|
||||
movie.release_year = 2001
|
||||
json = MovieOptionalRecordDataSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['attributes']['release_year']).to eq movie.release_year
|
||||
end
|
||||
|
||||
it "doesn't return optional attribute when attribute is not included" do
|
||||
movie.release_year = 1970
|
||||
json = MovieOptionalRecordDataSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['attributes'].key?('release_year')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when optional attributes are determined by record data with a lambda' do
|
||||
it 'returns optional attribute when attribute is included' do
|
||||
movie.release_year = 2001
|
||||
json = MovieOptionalRecordDataWithLambdaSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['attributes']['release_year']).to eq movie.release_year
|
||||
end
|
||||
|
||||
it "doesn't return optional attribute when attribute is not included" do
|
||||
movie.release_year = 1970
|
||||
json = MovieOptionalRecordDataWithLambdaSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['attributes'].key?('release_year')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when optional attributes are determined by params data' do
|
||||
it 'returns optional attribute when attribute is included' do
|
||||
movie.director = 'steven spielberg'
|
||||
json = MovieOptionalParamsDataSerializer.new(movie, { params: { admin: true } }).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['attributes']['director']).to eq 'steven spielberg'
|
||||
end
|
||||
|
||||
it "doesn't return optional attribute when attribute is not included" do
|
||||
movie.director = 'steven spielberg'
|
||||
json = MovieOptionalParamsDataSerializer.new(movie, { params: { admin: false } }).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['attributes'].key?('director')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
context 'when optional relationships are determined by record data' do
|
||||
it 'returns optional relationship when relationship is included' do
|
||||
json = MovieOptionalRelationshipSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['relationships'].key?('actors')).to be_truthy
|
||||
end
|
||||
|
||||
context 'when relationship is not included' do
|
||||
let(:json) do
|
||||
MovieOptionalRelationshipSerializer.new(movie, options).serialized_json
|
||||
end
|
||||
let(:options) do
|
||||
{}
|
||||
end
|
||||
let(:serializable_hash) do
|
||||
JSON.parse(json)
|
||||
end
|
||||
|
||||
it "doesn't return optional relationship" do
|
||||
movie.actor_ids = []
|
||||
expect(serializable_hash['data']['relationships'].key?('actors')).to be_falsey
|
||||
end
|
||||
|
||||
it "doesn't include optional relationship" do
|
||||
movie.actor_ids = []
|
||||
options[:include] = [:actors]
|
||||
expect(serializable_hash['included']).to be_blank
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when optional relationships are determined by record data with a lambda' do
|
||||
it 'returns optional relationship when relationship is included' do
|
||||
json = MovieOptionalRelationshipWithLambdaSerializer.new(movie).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['relationships'].key?('actors')).to be_truthy
|
||||
end
|
||||
|
||||
context 'when relationship is not included' do
|
||||
let(:json) do
|
||||
MovieOptionalRelationshipWithLambdaSerializer.new(movie, options).serialized_json
|
||||
end
|
||||
let(:options) do
|
||||
{}
|
||||
end
|
||||
let(:serializable_hash) do
|
||||
JSON.parse(json)
|
||||
end
|
||||
|
||||
it "doesn't return optional relationship" do
|
||||
movie.actor_ids = []
|
||||
expect(serializable_hash['data']['relationships'].key?('actors')).to be_falsey
|
||||
end
|
||||
|
||||
it "doesn't include optional relationship" do
|
||||
movie.actor_ids = []
|
||||
options[:include] = [:actors]
|
||||
expect(serializable_hash['included']).to be_blank
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when include has frozen array' do
|
||||
let(:options) { { include: [:actors].freeze } }
|
||||
let(:json) { MovieOptionalRelationshipSerializer.new(movie, options).serialized_json }
|
||||
|
||||
it 'does not raise and error' do
|
||||
expect(json['included']).to_not be_blank
|
||||
end
|
||||
end
|
||||
|
||||
context 'when optional relationships are determined by params data' do
|
||||
it 'returns optional relationship when relationship is included' do
|
||||
json = MovieOptionalRelationshipWithParamsSerializer.new(movie, { params: { admin: true } }).serialized_json
|
||||
serializable_hash = JSON.parse(json)
|
||||
expect(serializable_hash['data']['relationships'].key?('owner')).to be_truthy
|
||||
end
|
||||
|
||||
context 'when relationship is not included' do
|
||||
let(:json) do
|
||||
MovieOptionalRelationshipWithParamsSerializer.new(movie, options).serialized_json
|
||||
end
|
||||
let(:options) do
|
||||
{ params: { admin: false } }
|
||||
end
|
||||
let(:serializable_hash) do
|
||||
JSON.parse(json)
|
||||
end
|
||||
|
||||
it "doesn't return optional relationship" do
|
||||
expect(serializable_hash['data']['relationships'].key?('owner')).to be_falsey
|
||||
end
|
||||
|
||||
it "doesn't include optional relationship" do
|
||||
options[:include] = [:owner]
|
||||
expect(serializable_hash['included']).to be_blank
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when attribute contents are determined by params data' do
|
||||
it 'does not throw an error with no params are passed' do
|
||||
expect { MovieOptionalAttributeContentsWithParamsSerializer.new(movie).serialized_json }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
@ -1,41 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
|
||||
context 'when testing object serializer with ruby struct' do
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
options = {}
|
||||
options[:meta] = { total: 2 }
|
||||
options[:links] = { self: 'self' }
|
||||
options[:include] = [:actors]
|
||||
serializable_hash = MovieSerializer.new([movie_struct, movie_struct], options).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data].length).to eq 2
|
||||
expect(serializable_hash[:data][0][:relationships].length).to eq 4
|
||||
expect(serializable_hash[:data][0][:attributes].length).to eq 2
|
||||
|
||||
expect(serializable_hash[:meta]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:links]).to be_instance_of(Hash)
|
||||
|
||||
expect(serializable_hash[:included]).to be_instance_of(Array)
|
||||
expect(serializable_hash[:included][0]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:included].length).to eq 3
|
||||
|
||||
serializable_hash = MovieSerializer.new(movie_struct).serializable_hash
|
||||
|
||||
expect(serializable_hash[:data]).to be_instance_of(Hash)
|
||||
expect(serializable_hash[:meta]).to be nil
|
||||
expect(serializable_hash[:links]).to be nil
|
||||
expect(serializable_hash[:included]).to be nil
|
||||
expect(serializable_hash[:data][:id]).to eq movie_struct.id.to_s
|
||||
end
|
||||
|
||||
context 'struct without id' do
|
||||
it 'returns correct hash when serializable_hash is called' do
|
||||
serializer = MovieWithoutIdStructSerializer.new(movie_struct_without_id)
|
||||
expect { serializer.serializable_hash }.to raise_error(FastJsonapi::MandatoryField)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,72 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FastJsonapi::ObjectSerializer do
|
||||
include_context 'movie class'
|
||||
include_context 'group class'
|
||||
|
||||
context 'when testing class methods of serialization core' do
|
||||
it 'returns correct hash when id_hash is called' do
|
||||
inputs = [{ id: 23, record_type: :movie }, { id: 'x', record_type: 'person' }]
|
||||
inputs.each do |hash|
|
||||
result_hash = MovieSerializer.send(:id_hash, hash[:id], hash[:record_type])
|
||||
expect(result_hash[:id]).to eq hash[:id].to_s
|
||||
expect(result_hash[:type]).to eq hash[:record_type]
|
||||
end
|
||||
|
||||
result_hash = MovieSerializer.send(:id_hash, nil, 'movie')
|
||||
expect(result_hash).to be nil
|
||||
end
|
||||
|
||||
it 'returns correct hash when attributes_hash is called' do
|
||||
attributes_hash = MovieSerializer.send(:attributes_hash, movie)
|
||||
attribute_names = attributes_hash.keys.sort
|
||||
expect(attribute_names).to eq MovieSerializer.attributes_to_serialize.keys.sort
|
||||
MovieSerializer.attributes_to_serialize.each do |key, attribute|
|
||||
value = attributes_hash[key]
|
||||
expect(value).to eq movie.send(attribute.method)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the correct empty result when relationships_hash is called' do
|
||||
movie.actor_ids = []
|
||||
movie.owner_id = nil
|
||||
relationships_hash = MovieSerializer.send(:relationships_hash, movie)
|
||||
expect(relationships_hash[:actors][:data]).to eq([])
|
||||
expect(relationships_hash[:owner][:data]).to eq(nil)
|
||||
end
|
||||
|
||||
it 'returns correct keys when relationships_hash is called' do
|
||||
relationships_hash = MovieSerializer.send(:relationships_hash, movie)
|
||||
relationship_names = relationships_hash.keys.sort
|
||||
relationships_hashes = MovieSerializer.relationships_to_serialize.values
|
||||
expected_names = relationships_hashes.map(&:key).sort
|
||||
expect(relationship_names).to eq expected_names
|
||||
end
|
||||
|
||||
it 'returns correct values when relationships_hash is called' do
|
||||
relationships_hash = MovieSerializer.relationships_hash(movie)
|
||||
actors_hash = movie.actor_ids.map { |id| { id: id.to_s, type: :actor } }
|
||||
owner_hash = { id: movie.owner_id.to_s, type: :user }
|
||||
expect(relationships_hash[:actors][:data]).to match_array actors_hash
|
||||
expect(relationships_hash[:owner][:data]).to eq owner_hash
|
||||
end
|
||||
|
||||
it 'returns correct hash when record_hash is called' do
|
||||
record_hash = MovieSerializer.send(:record_hash, movie, nil, nil)
|
||||
expect(record_hash[:id]).to eq movie.id.to_s
|
||||
expect(record_hash[:type]).to eq MovieSerializer.record_type
|
||||
expect(record_hash).to have_key(:attributes) if MovieSerializer.attributes_to_serialize.present?
|
||||
expect(record_hash).to have_key(:relationships) if MovieSerializer.relationships_to_serialize.present?
|
||||
end
|
||||
|
||||
it 'serializes known included records only once' do
|
||||
includes_list = [:actors]
|
||||
known_included_objects = {}
|
||||
included_records = []
|
||||
[movie, movie].each do |record|
|
||||
included_records.concat MovieSerializer.send(:get_included_records, record, includes_list, known_included_objects, {}, nil)
|
||||
end
|
||||
expect(included_records.size).to eq 3
|
||||
end
|
||||
end
|
||||
end
|
@ -1,70 +0,0 @@
|
||||
RSpec.shared_context 'group class' do
|
||||
# Person, Group Classes and serializers
|
||||
before(:context) do
|
||||
# models
|
||||
class Person
|
||||
attr_accessor :id, :first_name, :last_name
|
||||
end
|
||||
|
||||
class Group
|
||||
attr_accessor :id, :name, :groupees # Let's assume groupees can be Person or Group objects
|
||||
end
|
||||
|
||||
# serializers
|
||||
class PersonSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :person
|
||||
attributes :first_name, :last_name
|
||||
end
|
||||
|
||||
class GroupSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :group
|
||||
attributes :name
|
||||
has_many :groupees, polymorphic: true
|
||||
end
|
||||
end
|
||||
|
||||
# Person and Group struct
|
||||
before(:context) do
|
||||
PersonStruct = Struct.new(
|
||||
:id, :first_name, :last_name
|
||||
)
|
||||
|
||||
GroupStruct = Struct.new(
|
||||
:id, :name, :groupees, :groupee_ids
|
||||
)
|
||||
end
|
||||
|
||||
after(:context) do
|
||||
classes_to_remove = %i[
|
||||
Person
|
||||
PersonSerializer
|
||||
Group
|
||||
GroupSerializer
|
||||
PersonStruct
|
||||
GroupStruct
|
||||
]
|
||||
classes_to_remove.each do |klass_name|
|
||||
Object.send(:remove_const, klass_name) if Object.constants.include?(klass_name)
|
||||
end
|
||||
end
|
||||
|
||||
let(:group) do
|
||||
group = Group.new
|
||||
group.id = 1
|
||||
group.name = 'Group 1'
|
||||
|
||||
person = Person.new
|
||||
person.id = 1
|
||||
person.last_name = 'Last Name 1'
|
||||
person.first_name = 'First Name 1'
|
||||
|
||||
child_group = Group.new
|
||||
child_group.id = 2
|
||||
child_group.name = 'Group 2'
|
||||
|
||||
group.groupees = [person, child_group]
|
||||
group
|
||||
end
|
||||
end
|
@ -1,495 +0,0 @@
|
||||
RSpec.shared_context 'movie class' do
|
||||
# Movie, Actor Classes and serializers
|
||||
before(:context) do
|
||||
# models
|
||||
class Movie
|
||||
attr_accessor :id,
|
||||
:name,
|
||||
:release_year,
|
||||
:director,
|
||||
:actor_ids,
|
||||
:owner_id,
|
||||
:movie_type_id
|
||||
|
||||
def actors
|
||||
actor_ids.map.with_index do |id, i|
|
||||
a = Actor.new
|
||||
a.id = id
|
||||
a.name = "Test #{a.id}"
|
||||
a.email = "test#{a.id}@test.com"
|
||||
a.agency_id = i
|
||||
a
|
||||
end
|
||||
end
|
||||
|
||||
def movie_type
|
||||
mt = MovieType.new
|
||||
mt.id = movie_type_id
|
||||
mt.name = 'Episode'
|
||||
mt.movie_ids = [id]
|
||||
mt
|
||||
end
|
||||
|
||||
def advertising_campaign_id
|
||||
1
|
||||
end
|
||||
|
||||
def advertising_campaign
|
||||
ac = AdvertisingCampaign.new
|
||||
ac.id = 1
|
||||
ac.movie_id = id
|
||||
ac.name = "Movie #{name} is incredible!!"
|
||||
ac
|
||||
end
|
||||
|
||||
def owner
|
||||
return unless owner_id
|
||||
|
||||
ow = Owner.new
|
||||
ow.id = owner_id
|
||||
ow
|
||||
end
|
||||
|
||||
def cache_key
|
||||
id.to_s
|
||||
end
|
||||
|
||||
def local_name(locale = :english)
|
||||
"#{locale} #{name}"
|
||||
end
|
||||
|
||||
def url
|
||||
"http://movies.com/#{id}"
|
||||
end
|
||||
|
||||
def actors_relationship_url
|
||||
"#{url}/relationships/actors"
|
||||
end
|
||||
end
|
||||
|
||||
class Actor
|
||||
attr_accessor :id, :name, :email, :agency_id
|
||||
|
||||
def agency
|
||||
Agency.new.tap do |a|
|
||||
a.id = agency_id
|
||||
a.name = "Test Agency #{agency_id}"
|
||||
a.state_id = 1
|
||||
end
|
||||
end
|
||||
|
||||
def awards
|
||||
award_ids.map do |i|
|
||||
Award.new.tap do |a|
|
||||
a.id = i
|
||||
a.title = "Test Award #{i}"
|
||||
a.actor_id = id
|
||||
a.imdb_award_id = i * 10
|
||||
a.year = 1990 + i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def award_ids
|
||||
[id * 9, id * 9 + 1]
|
||||
end
|
||||
|
||||
def url
|
||||
"http://movies.com/actors/#{id}"
|
||||
end
|
||||
end
|
||||
|
||||
class AdvertisingCampaign
|
||||
attr_accessor :id, :name, :movie_id
|
||||
end
|
||||
|
||||
class Agency
|
||||
attr_accessor :id, :name, :state_id
|
||||
|
||||
def state
|
||||
State.new.tap do |s|
|
||||
s.id = state_id
|
||||
s.name = "Test State #{state_id}"
|
||||
s.agency_ids = [id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Award
|
||||
attr_accessor :id, :title, :actor_id, :year, :imdb_award_id
|
||||
end
|
||||
|
||||
class State
|
||||
attr_accessor :id, :name, :agency_ids
|
||||
end
|
||||
|
||||
class MovieType
|
||||
attr_accessor :id, :name, :movie_ids
|
||||
|
||||
def movies
|
||||
movie_ids.map.with_index do
|
||||
m = Movie.new
|
||||
m.id = 232
|
||||
m.name = 'test movie'
|
||||
m.actor_ids = [1, 2, 3]
|
||||
m.owner_id = 3
|
||||
m.movie_type_id = 1
|
||||
m
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Agency
|
||||
attr_accessor :id, :name, :actor_ids
|
||||
end
|
||||
|
||||
class Agency
|
||||
attr_accessor :id, :name, :actor_ids
|
||||
end
|
||||
|
||||
class Supplier
|
||||
attr_accessor :id, :account_id
|
||||
end
|
||||
|
||||
class Account
|
||||
attr_accessor :id
|
||||
end
|
||||
|
||||
class Owner
|
||||
attr_accessor :id
|
||||
end
|
||||
|
||||
class OwnerSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
end
|
||||
|
||||
# serializers
|
||||
class MovieSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
# director attr is not mentioned intentionally
|
||||
attributes :name, :release_year
|
||||
has_many :actors
|
||||
belongs_to :owner, record_type: :user do |object, _params|
|
||||
object.owner
|
||||
end
|
||||
belongs_to :movie_type
|
||||
has_one :advertising_campaign
|
||||
end
|
||||
|
||||
class GenreMovieSerializer < MovieSerializer
|
||||
link(:something) { '/something/' }
|
||||
end
|
||||
|
||||
class ActionMovieSerializer < GenreMovieSerializer
|
||||
link(:url) { |object| "/action-movie/#{object.id}" }
|
||||
end
|
||||
|
||||
class HorrorMovieSerializer < GenreMovieSerializer
|
||||
link(:url) { |object| "/horror-movie/#{object.id}" }
|
||||
end
|
||||
|
||||
class OptionalDownloadableMovieSerializer < MovieSerializer
|
||||
link(:download, if: proc { |_record, params| params && params[:signed_url] }) do |_movie, params|
|
||||
params[:signed_url]
|
||||
end
|
||||
end
|
||||
|
||||
class OptionalDownloadableMovieWithLambdaSerializer < MovieSerializer
|
||||
link(:download, if: ->(record) { record.release_year >= 2000 }) do |movie|
|
||||
"/download/#{movie.id}"
|
||||
end
|
||||
end
|
||||
|
||||
class MovieWithoutIdStructSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :name, :release_year
|
||||
end
|
||||
|
||||
class CachingMovieSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name, :release_year
|
||||
has_many :actors
|
||||
belongs_to :owner, record_type: :user
|
||||
belongs_to :movie_type
|
||||
|
||||
cache_options store: ActiveSupport::Cache::MemoryStore.new, expires_in: 5.minutes
|
||||
end
|
||||
|
||||
class CachingMovieWithHasManySerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name, :release_year
|
||||
has_many :actors, cached: true
|
||||
belongs_to :owner, record_type: :user
|
||||
belongs_to :movie_type
|
||||
|
||||
cache_options store: ActiveSupport::Cache::MemoryStore.new, namespace: 'fast-jsonapi'
|
||||
end
|
||||
|
||||
class ActorSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :actor
|
||||
attributes :name, :email
|
||||
belongs_to :agency
|
||||
has_many :awards
|
||||
belongs_to :agency
|
||||
end
|
||||
|
||||
class AgencySerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :id, :name
|
||||
belongs_to :state
|
||||
has_many :actors
|
||||
end
|
||||
|
||||
class AwardSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :id, :title
|
||||
attribute :year, if: proc { |_record, params|
|
||||
if params[:include_award_year].present?
|
||||
params[:include_award_year]
|
||||
else
|
||||
false
|
||||
end
|
||||
}
|
||||
belongs_to :actor
|
||||
end
|
||||
|
||||
class StateSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :id, :name
|
||||
has_many :agency
|
||||
end
|
||||
|
||||
class AdvertisingCampaignSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :id, :name
|
||||
belongs_to :movie
|
||||
end
|
||||
|
||||
class MovieTypeSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie_type
|
||||
attributes :name
|
||||
has_many :movies
|
||||
end
|
||||
|
||||
class MovieSerializerWithAttributeBlock
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name, :release_year
|
||||
end
|
||||
|
||||
class MovieSerializerWithAttributeBlock
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name, :release_year
|
||||
end
|
||||
|
||||
class AgencySerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
attributes :id, :name
|
||||
has_many :actors
|
||||
end
|
||||
|
||||
class SupplierSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :supplier
|
||||
has_one :account
|
||||
end
|
||||
|
||||
class AccountSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :account
|
||||
belongs_to :supplier
|
||||
end
|
||||
|
||||
class MovieOptionalRecordDataSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name
|
||||
attribute :release_year, if: proc { |record| record.release_year >= 2000 }
|
||||
end
|
||||
|
||||
class MovieOptionalRecordDataWithLambdaSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name
|
||||
attribute :release_year, if: ->(record) { record.release_year >= 2000 }
|
||||
end
|
||||
|
||||
class MovieOptionalParamsDataSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name
|
||||
attribute :director, if: proc { |_record, params| params[:admin] == true }
|
||||
end
|
||||
|
||||
class MovieOptionalRelationshipSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name
|
||||
has_many :actors, if: proc { |record| record.actors.any? }
|
||||
end
|
||||
|
||||
class MovieOptionalRelationshipWithLambdaSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name
|
||||
has_many :actors, if: ->(record) { record.actors.any? }
|
||||
end
|
||||
|
||||
class MovieOptionalRelationshipWithParamsSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name
|
||||
belongs_to :owner, record_type: :user, if: proc { |_record, params| params[:admin] == true }
|
||||
end
|
||||
|
||||
class MovieOptionalAttributeContentsWithParamsSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
set_type :movie
|
||||
attributes :name
|
||||
attribute :director do |_record, params|
|
||||
data = {}
|
||||
data[:first_name] = 'steven'
|
||||
data[:last_name] = 'spielberg' if params[:admin]
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Namespaced MovieSerializer
|
||||
before(:context) do
|
||||
# namespaced model stub
|
||||
module AppName
|
||||
module V1
|
||||
class MovieSerializer
|
||||
include FastJsonapi::ObjectSerializer
|
||||
# to test if compute_serializer_name works
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Movie and Actor struct
|
||||
before(:context) do
|
||||
MovieStruct = Struct.new(
|
||||
:id,
|
||||
:name,
|
||||
:release_year,
|
||||
:actor_ids,
|
||||
:actors,
|
||||
:owner_id,
|
||||
:owner,
|
||||
:movie_type_id,
|
||||
:advertising_campaign_id
|
||||
)
|
||||
|
||||
ActorStruct = Struct.new(:id, :name, :email, :agency_id, :award_ids)
|
||||
MovieWithoutIdStruct = Struct.new(:name, :release_year)
|
||||
AgencyStruct = Struct.new(:id, :name, :actor_ids)
|
||||
end
|
||||
|
||||
after(:context) do
|
||||
classes_to_remove = %i[
|
||||
ActionMovieSerializer
|
||||
GenreMovieSerializer
|
||||
HorrorMovieSerializer
|
||||
OptionalDownloadableMovieSerializer
|
||||
OptionalDownloadableMovieWithLambdaSerializer
|
||||
Movie
|
||||
MovieSerializer
|
||||
Actor
|
||||
ActorSerializer
|
||||
MovieType
|
||||
MovieTypeSerializer
|
||||
AppName::V1::MovieSerializer
|
||||
MovieStruct
|
||||
ActorStruct
|
||||
MovieWithoutIdStruct
|
||||
HyphenMovieSerializer
|
||||
MovieWithoutIdStructSerializer
|
||||
Agency
|
||||
AgencyStruct
|
||||
AgencySerializer
|
||||
AdvertisingCampaign
|
||||
AdvertisingCampaignSerializer
|
||||
]
|
||||
classes_to_remove.each do |klass_name|
|
||||
Object.send(:remove_const, klass_name) if Object.constants.include?(klass_name)
|
||||
end
|
||||
end
|
||||
|
||||
let(:movie_struct) do
|
||||
actors = []
|
||||
|
||||
3.times.each do |id|
|
||||
actors << ActorStruct.new(id, id.to_s, id.to_s, id, [id])
|
||||
end
|
||||
|
||||
m = MovieStruct.new
|
||||
m[:id] = 23
|
||||
m[:name] = 'struct movie'
|
||||
m[:release_year] = 1987
|
||||
m[:actor_ids] = [1, 2, 3]
|
||||
m[:owner_id] = 3
|
||||
m[:movie_type_id] = 2
|
||||
m[:actors] = actors
|
||||
m
|
||||
end
|
||||
|
||||
let(:movie_struct_without_id) do
|
||||
MovieWithoutIdStruct.new('struct without id', 2018)
|
||||
end
|
||||
|
||||
let(:movie) do
|
||||
m = Movie.new
|
||||
m.id = 232
|
||||
m.name = 'test movie'
|
||||
m.actor_ids = [1, 2, 3]
|
||||
m.owner_id = 3
|
||||
m.movie_type_id = 1
|
||||
m
|
||||
end
|
||||
|
||||
let(:actor) do
|
||||
Actor.new.tap do |a|
|
||||
a.id = 234
|
||||
a.name = 'test actor'
|
||||
a.email = 'test@test.com'
|
||||
a.agency_id = 432
|
||||
end
|
||||
end
|
||||
|
||||
let(:movie_type) do
|
||||
movie
|
||||
|
||||
mt = MovieType.new
|
||||
mt.id = movie.movie_type_id
|
||||
mt.name = 'Foreign Thriller'
|
||||
mt.movie_ids = [movie.id]
|
||||
mt
|
||||
end
|
||||
|
||||
let(:supplier) do
|
||||
s = Supplier.new
|
||||
s.id = 1
|
||||
s.account_id = 1
|
||||
s
|
||||
end
|
||||
|
||||
def build_movies(count)
|
||||
count.times.map do |i|
|
||||
m = Movie.new
|
||||
m.id = i + 1
|
||||
m.name = 'test movie'
|
||||
m.actor_ids = [1, 2, 3]
|
||||
m.owner_id = 3
|
||||
m.movie_type_id = 1
|
||||
m
|
||||
end
|
||||
end
|
||||
end
|
@ -1,18 +0,0 @@
|
||||
RSpec.shared_examples 'returning correct relationship hash' do |id_method_name, record_type|
|
||||
it 'returns correct relationship hash' do
|
||||
expect(relationship).to be_instance_of(FastJsonapi::Relationship)
|
||||
# expect(relationship.keys).to all(be_instance_of(Symbol))
|
||||
expect(relationship.static_serializer).to be relationship_serializer
|
||||
expect(relationship.id_method_name).to be id_method_name
|
||||
expect(relationship.static_record_type).to be record_type
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'returning key transformed hash' do |relationship_name, resource_type, release_year|
|
||||
it 'returns correctly transformed hash' do
|
||||
expect(hash[:data][0][:attributes]).to have_key(release_year)
|
||||
expect(hash[:data][0][:relationships]).to have_key(relationship_name)
|
||||
expect(hash[:data][0][:relationships][relationship_name][:data][:type]).to eq(resource_type)
|
||||
expect(hash[:included][0][:type]).to eq(resource_type)
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user