Fix integer > nil error when sending reaction notifications (#16627)

* don't set nil when size not called

recently, #16570 worked around an issue where aggregated siblings
wasn't present, by only calling size if present.

Unfortunately, this causes a comparison of integer (new json_data
aggregated siblings count) with nil (result of the safe navigation for dig()&.size
assigned nil to previous_siblings_size, when we expected it to be
0). The initial error on the same data moved farther down the controller.

If old_json_data is present, but does not have an array in
reaction.aggregated_siblings, we want to have previous size be zero.

Remove guard clause and previous assignment

The issue was not that old_json_data was nil (it came from an existing
notification) but that there were missing keys (or rather that the
json data for some notifications didn't have a reaction key at all).

Remove the guard clause and either set to the size, or zero if there
is none. I don't understand what the guard clause was for, so replace the
safety by adding a nil safe call to dig. I don't _believe_ this is
possible but in case it was we can shorten the check here.

* Add test to cover missing json_data['reaction'] key

* Remove unneeded temporary variable
This commit is contained in:
Daniel Uber 2022-02-17 16:30:39 -06:00 committed by GitHub
parent 41ab94eaae
commit 293ff5653a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 3 deletions

View file

@ -54,11 +54,9 @@ module Notifications
json_data = reaction_json_data(recent_reaction, aggregated_reaction_siblings)
previous_siblings_size = 0
notification = Notification.find_or_initialize_by(notification_params)
old_json_data = notification.json_data
previous_siblings_size = old_json_data.dig("reaction", "aggregated_siblings")&.size if old_json_data
previous_siblings_size = notification.json_data&.dig("reaction", "aggregated_siblings")&.size || 0
notification.json_data = json_data
notification.notified_at = Time.current

View file

@ -170,6 +170,23 @@ RSpec.describe Notifications::Reactions::Send, type: :service do
end
end
# regression test for #16627 and #16570
context "when a found reaction has unexpected json data" do
let(:existing_notification) do
create(
:notification,
json_data: { user: {}, article: {} },
action: "Reaction",
user: user,
)
end
it "does not raise error" do
reaction = create(:reaction, reactable: existing_notification.notifiable)
expect { described_class.call(reaction_data(reaction), user) }.not_to raise_error
end
end
context "when a receiver is an organization" do
let(:organization) { create(:organization) }