diaspora/spec/support/serializer_matchers.rb
cmrd Senya 7374661e2f
Update the user data export archive format.
This commit introduces changes to the user data export archive format.
This extends data set which is included in the archive. This data can be
then imported to other pods when this feature is implemented.

Also the commit adds the archive format json schema. ATM it is used in
automatic tests only, but in future it will also be used to validate
incoming archives.
2017-08-10 09:36:26 +03:00

79 lines
3.2 KiB
Ruby

# This file contains custom RSpec matchers for AMS.
# NOTE: It was developed for AMS v0.9 and the API might be changed in future, so that should be examined when moving
# between stable versions of AMS (e.g. 0.9 to 0.10, or 0.9 to a possible 1.0).
# This is a matcher that tests a ActiveModel Serializer derivatives to run a serializer for
# an association with expected properties and data.
#
# This matcher is expected to be used in unit testing of ActiveModel Serializer derivatives.
#
# It is mostly a wrapper around RSpec::Mocks::Matchers::Receive matcher with expectations based on
# ActiveModel::Serializer internal API knowledge.
# NOTE: this matcher uses knowledge of AMS internals
RSpec::Matchers.define :serialize_association do |association_name|
match do |root_serializer_class|
association = fetch_association(root_serializer_class, association_name)
execute_receive_matcher_with(association)
end
# Sets expectation for a specific serializer class to be used for has_one association serialization
chain :with_serializer, :association_serializer_class
# Sets expectation for a specific serializer class to be user for has_many association serialization
chain :with_each_serializer, :each_serializer_class
# Sets expectation for actual data to be passed to the serializer of the association
chain :with_object, :association_object
alias_method :with_objects, :with_object
private
# subject is what comes from the expect method argument in usual notation.
# So this method is equivalent of calling `expect(subject).to receive(:build_serializer)` but valid within a custom
# RSpec matcher's match method.
def execute_receive_matcher_with(subject)
receive_matcher.matches?(subject)
end
def receive_matcher
receive(:build_serializer).and_wrap_original do |original, object, options, &block|
with_object_expectation(object)
original.call(object, options, &block).tap do |serializer|
expect(serializer).to be_an_instance_of(serializer_class) unless serializer_class.nil?
expect(serializer).to serialize_each_with(each_serializer_class) unless each_serializer_class.nil?
end
end
end
def with_object_expectation(object)
if association_object.is_a?(Array)
expect(object).to match_array(association_object)
elsif !association_object.nil?
expect(object).to eq(association_object)
end
end
def fetch_association(serializer_class, association_name)
serializer_class._associations[association_name]
end
def serializer_class
@serializer_class ||= pick_serializer_class
end
def pick_serializer_class
return association_serializer_class unless association_serializer_class.nil?
return ActiveModel::ArraySerializer unless each_serializer_class.nil?
end
end
# This serializer tests that ActiveModel::ArraySerializer uses specific serializer for each member object of the array.
# We could also set a mock expectation on each serializer, but it maybe overly complicated for our present
# requirements.
# NOTE: this matcher uses knowledge of AMS internals
RSpec::Matchers.define :serialize_each_with do |expected|
match do |actual|
actual.is_a?(ActiveModel::ArraySerializer) && actual.instance_variable_get("@each_serializer") == expected
end
end