Skip to content

Commit

Permalink
Prevent ActiveJob::DeserializationError when deserialising expired jo…
Browse files Browse the repository at this point in the history
…bs (#2036)

Prevents an exception from being raised when looking for an ActiveJob with specific arguments if one or more of the active jobs in the queue have arguments that cannot be deserialised (e.g. if the record has now been deleted).
  • Loading branch information
aymeric-ledorze authored and JonRowe committed Oct 23, 2018
1 parent 9af9514 commit cc7c714
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
12 changes: 9 additions & 3 deletions lib/rspec/rails/matchers/active_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def supports_block_expectations?
def check(jobs)
@matching_jobs, @unmatching_jobs = jobs.partition do |job|
if arguments_match?(job) && other_attributes_match?(job)
args = ::ActiveJob::Arguments.deserialize(job[:args])
args = deserialize_arguments(job)
@block.call(*args)
true
else
Expand All @@ -125,7 +125,7 @@ def base_message

def base_job_message(job)
msg_parts = []
msg_parts << "with #{::ActiveJob::Arguments.deserialize(job[:args])}" if job[:args].any?
msg_parts << "with #{deserialize_arguments(job)}" if job[:args].any?
msg_parts << "on queue #{job[:queue]}" if job[:queue]
msg_parts << "at #{Time.at(job[:at])}" if job[:at]

Expand All @@ -136,7 +136,7 @@ def base_job_message(job)

def arguments_match?(job)
if @args.any?
deserialized_args = ::ActiveJob::Arguments.deserialize(job[:args])
deserialized_args = deserialize_arguments(job)
RSpec::Mocks::ArgumentListMatcher.new(*@args).args_match?(*deserialized_args)
else
true
Expand Down Expand Up @@ -169,6 +169,12 @@ def set_expected_number(relativity, count)
end
end

def deserialize_arguments(job)
::ActiveJob::Arguments.deserialize(job[:args])
rescue ::ActiveJob::DeserializationError
job[:args]
end

def queue_adapter
::ActiveJob::Base.queue_adapter
end
Expand Down
18 changes: 17 additions & 1 deletion spec/rspec/rails/matchers/active_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ def initialize(id)
end

def ==(comparison_object)
id == comparison_object.id
(GlobalIdModel === comparison_object) && (id == comparison_object.id)
end

def to_global_id(options = {})
@global_id ||= GlobalID.create(self, :app => "rspec-suite")
end
end

class FailingGlobalIdModel < GlobalIdModel
def self.find(id)
raise URI::GID::MissingModelIdError
end
end
end

RSpec.describe "ActiveJob matchers", :skip => !RSpec::Rails::FeatureCheck.has_active_job? do
Expand Down Expand Up @@ -293,6 +299,16 @@ def self.name; "LoggingJob"; end
}
end

it "ignores undeserializable arguments" do
failing_global_id_object = FailingGlobalIdModel.new("21")
global_id_object = GlobalIdModel.new("42")

expect{
hello_job.perform_later(failing_global_id_object)
hello_job.perform_later(global_id_object)
}.to have_enqueued_job(hello_job).with(global_id_object)
end

it "only calls with block if other conditions are met" do
noon = Date.tomorrow.noon
midnight = Date.tomorrow.midnight
Expand Down

0 comments on commit cc7c714

Please sign in to comment.