Move send new badge achievement notification to ActiveJob (#2474)
This commit is contained in:
parent
30dcb23169
commit
743316b528
10 changed files with 175 additions and 23 deletions
12
app/jobs/notifications/new_badge_achievement_job.rb
Normal file
12
app/jobs/notifications/new_badge_achievement_job.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
module Notifications
|
||||
class NewBadgeAchievementJob < ApplicationJob
|
||||
queue_as :send_new_badge_achievement_notification
|
||||
|
||||
def perform(badge_achievement_id, service = NewBadgeAchievement::Send)
|
||||
badge_achievement = BadgeAchievement.find_by(id: badge_achievement_id)
|
||||
return unless badge_achievement
|
||||
|
||||
service.call(badge_achievement)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
module Notifications
|
||||
class NewCommentJob < ApplicationJob
|
||||
queue_as :send_new_comment_notification
|
||||
|
||||
def perform(comment_id, service = NewComment::Send)
|
||||
comment = Comment.find_by(id: comment_id)
|
||||
service.call(comment) if comment
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
module Notifications
|
||||
class NewReactionJob < ApplicationJob
|
||||
queue_as :send_new_reaction_notification
|
||||
|
||||
# @param reaction_data [Hash]
|
||||
# * :reactable_id [Integer] - article or comment id
|
||||
# * :reactable_type [String] - "Article" or "Comment"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class BadgeAchievement < ApplicationRecord
|
|||
private
|
||||
|
||||
def notify_recipient
|
||||
Notification.send_new_badge_notification(self)
|
||||
Notification.send_new_badge_achievement_notification(self)
|
||||
end
|
||||
|
||||
def send_email_notification
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ class Notification < ApplicationRecord
|
|||
end
|
||||
|
||||
def send_new_follower_notification_without_delay(follow, is_read = false)
|
||||
return unless Follow.need_new_follower_notification_for?(follow.followable_type)
|
||||
|
||||
follow_data = follow.attributes.slice("follower_id", "followable_id", "followable_type").symbolize_keys
|
||||
Notifications::NewFollowerJob.perform_now(follow_data, is_read)
|
||||
end
|
||||
|
|
@ -60,28 +62,20 @@ class Notification < ApplicationRecord
|
|||
Notifications::NewCommentJob.perform_now(comment.id)
|
||||
end
|
||||
|
||||
def send_new_badge_notification(badge_achievement)
|
||||
json_data = {
|
||||
user: user_data(badge_achievement.user),
|
||||
badge_achievement: {
|
||||
badge_id: badge_achievement.badge_id,
|
||||
rewarding_context_message: badge_achievement.rewarding_context_message,
|
||||
badge: {
|
||||
title: badge_achievement.badge.title,
|
||||
description: badge_achievement.badge.description,
|
||||
badge_image_url: badge_achievement.badge.badge_image_url
|
||||
}
|
||||
}
|
||||
}
|
||||
Notification.create(
|
||||
user_id: badge_achievement.user.id,
|
||||
notifiable_id: badge_achievement.id,
|
||||
notifiable_type: "BadgeAchievement",
|
||||
action: nil,
|
||||
json_data: json_data,
|
||||
)
|
||||
def send_new_badge_achievement_notification(badge_achievement)
|
||||
Notifications::NewBadgeAchievementJob.perform_later(badge_achievement.id)
|
||||
end
|
||||
# NOTE: this alias is temporary until the transition to ActiveJob is completed
|
||||
# and all old DelayedJob jobs are processed by the queue workers.
|
||||
# It can be removed after pre-existing jobs are done
|
||||
alias send_new_badge_notification send_new_badge_achievement_notification
|
||||
|
||||
# NOTE: this method is temporary until the transition to ActiveJob is completed
|
||||
# and all old DelayedJob jobs are processed by the queue workers.
|
||||
# It can be removed after pre-existing jobs are done
|
||||
def send_new_badge_notification_without_delay(badge_achievement)
|
||||
Notifications::NewBadgeAchievementJob.perform_now(badge_achievement.id)
|
||||
end
|
||||
handle_asynchronously :send_new_badge_notification
|
||||
|
||||
def send_reaction_notification(reaction, receiver)
|
||||
return if reaction.skip_notification_for?(receiver)
|
||||
|
|
|
|||
45
app/services/notifications/new_badge_achievement/send.rb
Normal file
45
app/services/notifications/new_badge_achievement/send.rb
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# send notifications about the new badge achievement
|
||||
module Notifications
|
||||
module NewBadgeAchievement
|
||||
class Send
|
||||
def initialize(badge_achievement)
|
||||
@badge_achievement = badge_achievement
|
||||
end
|
||||
|
||||
delegate :user_data, to: Notifications
|
||||
|
||||
def self.call(*args)
|
||||
new(*args).call
|
||||
end
|
||||
|
||||
def call
|
||||
Notification.create(
|
||||
user_id: badge_achievement.user.id,
|
||||
notifiable_id: badge_achievement.id,
|
||||
notifiable_type: "BadgeAchievement",
|
||||
action: nil,
|
||||
json_data: json_data,
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :badge_achievement
|
||||
|
||||
def json_data
|
||||
{
|
||||
user: user_data(badge_achievement.user),
|
||||
badge_achievement: {
|
||||
badge_id: badge_achievement.badge_id,
|
||||
rewarding_context_message: badge_achievement.rewarding_context_message,
|
||||
badge: {
|
||||
title: badge_achievement.badge.title,
|
||||
description: badge_achievement.badge.description,
|
||||
badge_image_url: badge_achievement.badge.badge_image_url
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
spec/jobs/notifications/new_badge_achievement_job_spec.rb
Normal file
24
spec/jobs/notifications/new_badge_achievement_job_spec.rb
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe Notifications::NewBadgeAchievementJob, type: :job do
|
||||
include_examples "#enqueues_job", "send_new_badge_achievement_notification", 5
|
||||
|
||||
describe "#perform_now" do
|
||||
let(:new_badge_service) { double }
|
||||
|
||||
before do
|
||||
allow(new_badge_service).to receive(:call)
|
||||
end
|
||||
|
||||
it "calls the service" do
|
||||
badge_achievement = create(:badge_achievement)
|
||||
described_class.perform_now(badge_achievement.id, new_badge_service)
|
||||
expect(new_badge_service).to have_received(:call).with(badge_achievement).once
|
||||
end
|
||||
|
||||
it "doesn't call a service if a nonexistent badge achievement is passed" do
|
||||
described_class.perform_now(9999, new_badge_service)
|
||||
expect(new_badge_service).not_to have_received(:call)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -7,6 +7,7 @@ RSpec.describe Notification, type: :model do
|
|||
let(:organization) { create(:organization) }
|
||||
let(:article) { create(:article, user_id: user.id, page_views_count: 4000, positive_reactions_count: 70) }
|
||||
let(:follow_instance) { user.follow(user2) }
|
||||
let(:badge_achievement) { create(:badge_achievement) }
|
||||
|
||||
describe "when trying to #send_new_follower_notification after following a tag" do
|
||||
let(:tag) { create(:tag) }
|
||||
|
|
@ -425,4 +426,28 @@ RSpec.describe Notification, type: :model do
|
|||
expect(notification.aggregated?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_new_badge_achievement_notification" do
|
||||
it "enqueues a new badge achievement job" do
|
||||
assert_enqueued_with(job: Notifications::NewBadgeAchievementJob, args: [badge_achievement.id]) do
|
||||
Notification.send_new_badge_achievement_notification(badge_achievement)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_new_badge_notification (deprecated)" do
|
||||
it "enqueues a new badge achievement job" do
|
||||
assert_enqueued_with(job: Notifications::NewBadgeAchievementJob, args: [badge_achievement.id]) do
|
||||
Notification.send_new_badge_notification(badge_achievement)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#send_new_badge_notification_without_delay (deprecated)" do
|
||||
it "creates a notification" do
|
||||
expect do
|
||||
Notification.send_new_badge_notification_without_delay(badge_achievement)
|
||||
end.to change(Notification, :count).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -221,7 +221,9 @@ RSpec.describe "NotificationsIndex", type: :request do
|
|||
sign_in user
|
||||
badge = create(:badge)
|
||||
badge_achievement = create(:badge_achievement, user: user, badge: badge)
|
||||
Notification.send_new_badge_notification_without_delay(badge_achievement)
|
||||
perform_enqueued_jobs do
|
||||
Notification.send_new_badge_achievement_notification(badge_achievement)
|
||||
end
|
||||
get "/notifications"
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe Notifications::NewBadgeAchievement::Send, type: :service do
|
||||
let(:badge_achievement) { create(:badge_achievement) }
|
||||
|
||||
def expected_json_data
|
||||
{
|
||||
user: Notifications.user_data(badge_achievement.user),
|
||||
badge_achievement: {
|
||||
badge_id: badge_achievement.badge_id,
|
||||
rewarding_context_message: badge_achievement.rewarding_context_message,
|
||||
badge: {
|
||||
title: badge_achievement.badge.title,
|
||||
description: badge_achievement.badge.description,
|
||||
badge_image_url: badge_achievement.badge.badge_image_url
|
||||
}
|
||||
}
|
||||
}.to_json
|
||||
end
|
||||
|
||||
it "creates a notification" do
|
||||
expect do
|
||||
described_class.call(badge_achievement)
|
||||
end.to change(Notification, :count).by(1)
|
||||
end
|
||||
|
||||
it "creates a notification for the badge achievement user" do
|
||||
notification = described_class.call(badge_achievement)
|
||||
expect(notification.user).to eq(badge_achievement.user)
|
||||
end
|
||||
|
||||
it "creates a notification for the badge achievement" do
|
||||
notification = described_class.call(badge_achievement)
|
||||
expect(notification.notifiable_id).to eq(badge_achievement.id)
|
||||
expect(notification.notifiable_type).to eq("BadgeAchievement")
|
||||
end
|
||||
|
||||
it "creates a notification with no action" do
|
||||
notification = described_class.call(badge_achievement)
|
||||
expect(notification.action).to be(nil)
|
||||
end
|
||||
|
||||
it "creates a notification with the proper json data" do
|
||||
notification = described_class.call(badge_achievement)
|
||||
json_data = notification.json_data.to_json
|
||||
expect(JSON.parse(json_data)).to eq(JSON.parse(expected_json_data))
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue