Project

General

Profile

« Previous | Next » 

Revision 56d54dc2

Added by Amir Fefer about 7 years ago

Fixes #19034 - add tasks for clearing expired notifications

View differences:

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