Revision 56d54dc2
Added by Amir Fefer about 7 years ago
app/services/ui_notifications/clean_expired.rb | ||
---|---|---|
module UINotifications
|
||
class CleanExpired
|
||
def initialize(blueprint: nil, group: nil, expired_at: Time.now.utc)
|
||
@blueprint = blueprint.present? ? {:notification_blueprints => {:name => blueprint }} : nil
|
||
@group = group.present? ? {:notification_blueprints => {:group => group}} : nil
|
||
expired_at = expired_at.to_time if expired_at.is_a?(String)
|
||
raise(Foreman::Exception, 'Parsing expired time has failed') if expired_at.nil?
|
||
raise(Foreman::Exception, 'Expired time cannot be greater then now') if expired_at > Time.now.utc
|
||
@expired_at = expired_at
|
||
end
|
||
|
||
def clean!
|
||
UINotifications::Base.logger.info("Removing all expired notifications")
|
||
to_delete = Notification.joins(:notification_blueprint)
|
||
.where('notifications.expired_at < ?', @expired_at)
|
||
.where(@blueprint)
|
||
.where(@group)
|
||
NotificationRecipient.where(notification: to_delete).delete_all
|
||
@deleted_count = to_delete.delete_all
|
||
self
|
||
end
|
||
|
||
def deleted_count
|
||
raise 'cleaner has not cleaned anything yet, run #clean! first' if @deleted_count.nil?
|
||
@deleted_count
|
||
end
|
||
end
|
||
end
|
lib/tasks/notifications_cleaner.rake | ||
---|---|---|
namespace :notifications do
|
||
desc "Clean expired notification
|
||
Arguments can be a specific time, a group name or a blueprint name
|
||
With no arguments, all expired notifications will removed
|
||
Examples:
|
||
rake notifications:clean['08:00 AM'] -
|
||
- Will clean all expired notifications until 08:00 AM today
|
||
rake notifications:clean['2017-04-20', 'group1'] -
|
||
- Will clean all expired notifications until the given date, and associated to group1
|
||
rake notifications:clean[,,'blueprint_name'] -
|
||
- Will clean all expired notifications which belongs to the given blueprint name"
|
||
|
||
task :clean, [:time, :group, :blueprint] => :environment do |t, args|
|
||
puts 'Starting expired notifications clean up...'
|
||
begin
|
||
cleaner = UINotifications::CleanExpired.new({blueprint: args.blueprint, group: args.group,
|
||
expired_at: args.time}.compact)
|
||
cleaner.clean!
|
||
puts "Finished, cleaned #{cleaner.deleted_count} notifications"
|
||
rescue => error
|
||
puts "Failed to clean notification: #{error}"
|
||
end
|
||
end
|
||
end
|
test/unit/ui_notifications/clean_expired_test.rb | ||
---|---|---|
require 'test_helper'
|
||
|
||
class CleanExpiredTest < ActiveSupport::TestCase
|
||
test "clean should remove all expired notifications" do
|
||
blueprint = create_blueprint(-5.minutes, false)
|
||
blueprint2 = create_blueprint(5.minutes, true)
|
||
create_notification(blueprint)
|
||
create_notification(blueprint)
|
||
create_notification(blueprint2)
|
||
notifications = Notification.all
|
||
cleaner = UINotifications::CleanExpired.new
|
||
assert_equal 3, notifications.length
|
||
assert_equal 2, cleaner.clean!.deleted_count
|
||
end
|
||
|
||
test "clean with a given time should remove all expired notification until this time" do
|
||
blueprint = create_blueprint(-5.minutes, false)
|
||
blueprint2 = create_blueprint(-1.minutes, false)
|
||
create_notification(blueprint)
|
||
create_notification(blueprint2)
|
||
assert_equal 2, Notification.all.length
|
||
time = Time.zone.now - 3.minutes
|
||
cleaner = UINotifications::CleanExpired.new(expired_at: time.to_s)
|
||
assert_equal 1, cleaner.clean!.deleted_count
|
||
end
|
||
|
||
test "clean with a given group name should remove only expired notifications which belong to a blueprint group" do
|
||
blueprint = create_blueprint(-5.minutes, false)
|
||
blueprint2 = create_blueprint(-5.minutes, false)
|
||
create_notification(blueprint)
|
||
create_notification(blueprint2)
|
||
cleaner = UINotifications::CleanExpired.new(group: blueprint.group)
|
||
assert_equal 2, Notification.all.size
|
||
assert_equal 1, cleaner.clean!.deleted_count
|
||
assert_equal blueprint2.group, Notification.first.notification_blueprint.group
|
||
end
|
||
|
||
test "clean with a given group and time should remove associated time-expired notifications" do
|
||
blueprint = create_blueprint(-5.minutes, false)
|
||
create_notification(blueprint)
|
||
time = Time.zone.now - 6.minutes
|
||
cleaner = UINotifications::CleanExpired.new(expired_at: time.to_s, group: blueprint.group)
|
||
assert_equal 0, cleaner.clean!.deleted_count
|
||
time = Time.zone.now - 3.minutes
|
||
cleaner = UINotifications::CleanExpired.new(expired_at: time.to_s, group: blueprint.group)
|
||
assert_equal 1, cleaner.clean!.deleted_count
|
||
end
|
||
|
||
test "clean by blueprint should remove only expired notifications which belong to a blueprint" do
|
||
blueprint = create_blueprint(-5.minutes, false)
|
||
blueprint2 = create_blueprint(-5.minutes, false)
|
||
create_notification(blueprint)
|
||
create_notification(blueprint2)
|
||
assert_equal 2, Notification.all.size
|
||
cleaner = UINotifications::CleanExpired.new(blueprint: blueprint.name)
|
||
assert_equal 1, cleaner.clean!.deleted_count
|
||
assert_equal blueprint2, Notification.first.notification_blueprint
|
||
end
|
||
|
||
test "clean with a given blueprint name and time should remove only associated time-expired notifications" do
|
||
blueprint = create_blueprint(-5.minutes, false)
|
||
create_notification(blueprint)
|
||
time = Time.zone.now - 6.minutes
|
||
cleaner = UINotifications::CleanExpired.new(expired_at: time.to_s, blueprint: blueprint.name)
|
||
assert_equal 0, cleaner.clean!.deleted_count
|
||
time = Time.zone.now - 3.minutes
|
||
cleaner = UINotifications::CleanExpired.new(expired_at: time.to_s, blueprint: blueprint.name)
|
||
assert_equal 1, cleaner.clean!.deleted_count
|
||
end
|
||
|
||
test "clean with a given time should raise an error if time is in the future" do
|
||
blueprint = create_blueprint(-5.minutes, false)
|
||
blueprint2 = create_blueprint(-1.minutes, false)
|
||
create_notification(blueprint)
|
||
create_notification(blueprint2)
|
||
time = Time.zone.now + 3.minutes
|
||
assert_raise Foreman::Exception do
|
||
assert_equal UINotifications::CleanExpired.new(expired_at: time.to_s).clean!
|
||
end
|
||
end
|
||
|
||
test "clean with a given unparsed time string should raise an error" do
|
||
assert_raise Foreman::Exception do
|
||
assert_equal UINotifications::CleanExpired.new(expired_at: 'unparsed_time').clean!
|
||
end
|
||
end
|
||
|
||
private
|
||
|
||
def create_notification(blueprint)
|
||
FactoryGirl.create(:notification,
|
||
:audience => Notification::AUDIENCE_ADMIN,
|
||
:notification_blueprint => blueprint)
|
||
end
|
||
|
||
def create_blueprint(expired_time, validate = true)
|
||
blueprint = FactoryGirl.build(
|
||
:notification_blueprint,
|
||
:expires_in => expired_time
|
||
)
|
||
blueprint.save(:validate => validate)
|
||
blueprint
|
||
end
|
||
end
|
Also available in: Unified diff
Fixes #19034 - add tasks for clearing expired notifications