Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validation event check force delete to a job #2369

Merged
merged 9 commits into from
May 17, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions app/jobs/check_force_delete_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class CheckForceDeleteJob < ApplicationJob
def perform(contact_ids)
contacts = Contact.find(contact_ids)

contacts.each do |contact|
email = contact.email

if contact.need_to_start_force_delete?
Domains::ForceDeleteEmail::Base.run(email: email)
elsif contact.need_to_lift_force_delete?
domain_list(email).each { |domain| refresh_status_notes(contact, domain) }
end
end
end

private

def refresh_status_notes(contact, domain)
force_delete_emails = domain.status_notes[DomainStatus::FORCE_DELETE]
return unless force_delete_emails

force_delete_emails.slice!(contact.email_history)
force_delete_emails.lstrip!
domain.save(validate: false)

notify_registrar(domain) unless force_delete_emails.empty?
end

def domain_list(email)
domain_contacts = Contact.where(email: email).map(&:domain_contacts).flatten
registrant_ids = Registrant.where(email: email).pluck(:id)

(domain_contacts.map(&:domain).flatten + Domain.where(registrant_id: registrant_ids)).uniq
end

def notify_registrar(domain)
domain.registrar.notifications.create!(text: I18n.t('force_delete_auto_email',
domain_name: domain.name,
outzone_date: domain.outzone_date,
purge_date: domain.purge_date,
email: domain.status_notes[DomainStatus::FORCE_DELETE]))
end
end
4 changes: 1 addition & 3 deletions app/models/concerns/email_verifable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ def validate_email_data(level:, count:)
def need_to_start_force_delete?
flag = false
ValidationEvent::INVALID_EVENTS_COUNT_BY_LEVEL.each do |level, count|
if validation_events.count >= count && validate_email_data(level: level, count: count)
flag = true
end
flag = true if validation_events.count >= count && validate_email_data(level: level, count: count)
end

flag
Expand Down
54 changes: 0 additions & 54 deletions app/models/validation_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ class ValidationEvent < ApplicationRecord
scope :smtp, -> { where('event_data @> ?', { 'check_level': 'smtp' }.to_json) }
scope :by_object, ->(object) { where(validation_eventable: object) }

# after_create :check_for_force_delete

def self.validated_ids_by(klass)
recent.successful.where('validation_eventable_type = ?', klass)
.pluck(:validation_eventable_id)
Expand All @@ -57,56 +55,4 @@ def event_type
def object
validation_eventable
end

def check_for_force_delete
if object.need_to_start_force_delete?
start_force_delete
elsif object.need_to_lift_force_delete?
refresh_status_notes
lift_force_delete
end
end

def start_force_delete
Domains::ForceDeleteEmail::Base.run(email: email)
end

def refresh_status_notes
domain_list.each do |domain|
next unless domain.status_notes[DomainStatus::FORCE_DELETE]

domain.status_notes[DomainStatus::FORCE_DELETE].slice!(object.email_history)
domain.status_notes[DomainStatus::FORCE_DELETE].lstrip!
domain.save(validate: false)

notify_registrar(domain) unless domain.status_notes[DomainStatus::FORCE_DELETE].empty?
end
end

def domain_list
domain_contacts = Contact.where(email: email).map(&:domain_contacts).flatten
registrant_ids = Registrant.where(email: email).pluck(:id)

(domain_contacts.map(&:domain).flatten + Domain.where(registrant_id: registrant_ids)).uniq
end

def notify_registrar(domain)
domain.registrar.notifications.create!(text: I18n.t('force_delete_auto_email',
domain_name: domain.name,
outzone_date: domain.outzone_date,
purge_date: domain.purge_date,
email: domain.status_notes[DomainStatus::FORCE_DELETE]))
end

def lift_force_delete
# domain_contacts = Contact.where(email: email).map(&:domain_contacts).flatten
# registrant_ids = Registrant.where(email: email).pluck(:id)
#
# domains = domain_contacts.map(&:domain).flatten +
# Domain.where(registrant_id: registrant_ids)
#
# domains.each do |domain|
# Domains::ForceDeleteLift::Base.run(domain: domain)
# end
end
end
29 changes: 29 additions & 0 deletions lib/tasks/check_force_delete.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
desc 'Check Force Delete'
task :check_force_delete, %i[batch batch_size batches_delay] => :environment do |_t, args|
args.with_defaults(batch: false, batch_size: 1_000, batches_delay: 15)

batch = ActiveModel::Type::Boolean.new.cast(args[:batch])
batch_size = args[:batch_size].to_i
batches_delay = args[:batches_delay].to_i.minutes

invalid_contacts = Contact.joins(:validation_events).select do |contact|
events = contact.validation_events
mx = events.mx.select(&:failed?).count >= ValidationEvent::MX_CHECK
regex = events.regex.select(&:failed?).present?

(contact.need_to_start_force_delete? || contact.need_to_lift_force_delete?) && (mx || regex)
end.uniq

if batch
waiting_minutes = 0.minutes

invalid_contacts.find_in_batches(batch_size: batch_size) do |contact_batches|
CheckForceDeleteJob.set(wait: waiting_minutes).perform_later(contact_batches)
waiting_minutes += batches_delay
end
else
invalid_contacts.each do |contact|
CheckForceDeleteJob.perform_later([contact.id])
end
end
end
188 changes: 102 additions & 86 deletions test/models/domain/force_delete_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require 'test_helper'

class ForceDeleteTest < ActionMailer::TestCase
include ActiveJob::TestHelper

setup do
@domain = domains(:shop)
Setting.redemption_grace_period = 30
Expand Down Expand Up @@ -380,115 +382,121 @@ def test_schedules_force_delete_after_registrant_bounce
assert notification.text.include? asserted_text
end

# def test_schedules_force_delete_invalid_contact
# @domain.update(valid_to: Time.zone.parse('2012-08-05'))
# assert_not @domain.force_delete_scheduled?
# travel_to Time.zone.parse('2010-07-05')
# email = '`@internet.ee'
# asserted_text = "Invalid email: #{email}"
def test_schedules_force_delete_invalid_contact
@domain.update(valid_to: Time.zone.parse('2012-08-05'))
assert_not @domain.force_delete_scheduled?
travel_to Time.zone.parse('2010-07-05')
email = '`@internet.ee'
asserted_text = "Invalid email: #{email}"

# Truemail.configure.default_validation_type = :regex
Truemail.configure.default_validation_type = :regex

# contact = @domain.admin_contacts.first
# contact.update_attribute(:email, email)
contact = @domain.admin_contacts.first
contact.update_attribute(:email, email)

# ValidationEvent::VALID_EVENTS_COUNT_THRESHOLD.times do
# contact.verify_email
# end
ValidationEvent::VALID_EVENTS_COUNT_THRESHOLD.times do
contact.verify_email
end

# @domain.reload
perform_check_force_delete_job(contact.id)
@domain.reload

# assert @domain.force_delete_scheduled?
# assert_equal Date.parse('2010-09-19'), @domain.force_delete_date.to_date
# assert_equal Date.parse('2010-08-05'), @domain.force_delete_start.to_date
# assert_equal @domain.status_notes[DomainStatus::FORCE_DELETE], email
# notification = @domain.registrar.notifications.last
# assert notification.text.include? asserted_text
# end
assert @domain.force_delete_scheduled?
assert_equal Date.parse('2010-09-19'), @domain.force_delete_date.to_date
assert_equal Date.parse('2010-08-05'), @domain.force_delete_start.to_date
assert_equal @domain.status_notes[DomainStatus::FORCE_DELETE], email
notification = @domain.registrar.notifications.last
assert notification.text.include? asserted_text
end

# def test_add_invalid_email_to_domain_status_notes
# domain = domains(:airport)
# domain.update(valid_to: Time.zone.parse('2012-08-05'),
# statuses: %w[serverForceDelete serverRenewProhibited serverTransferProhibited],
# force_delete_data: { 'template_name': 'invalid_email', 'force_delete_type': 'soft' },
# status_notes: { "serverForceDelete": '`@internet2.ee' })
def test_add_invalid_email_to_domain_status_notes
domain = domains(:airport)
domain.update(valid_to: Time.zone.parse('2012-08-05'),
statuses: %w[serverForceDelete serverRenewProhibited serverTransferProhibited],
force_delete_data: { 'template_name': 'invalid_email', 'force_delete_type': 'soft' },
status_notes: { "serverForceDelete": '`@internet2.ee' })

# travel_to Time.zone.parse('2010-07-05')
# email = '`@internet.ee'
# invalid_emails = '`@internet2.ee `@internet.ee'
# asserted_text = "Invalid email: #{invalid_emails}"
travel_to Time.zone.parse('2010-07-05')
email = '`@internet.ee'
invalid_emails = '`@internet2.ee `@internet.ee'
asserted_text = "Invalid email: #{invalid_emails}"

# Truemail.configure.default_validation_type = :regex
Truemail.configure.default_validation_type = :regex

# contact_first = domain.admin_contacts.first
# contact_first.update_attribute(:email_history, '[email protected]')
# contact_first.update_attribute(:email, email)
contact_first = domain.admin_contacts.first
contact_first.update_attribute(:email_history, '[email protected]')
contact_first.update_attribute(:email, email)

# ValidationEvent::VALID_EVENTS_COUNT_THRESHOLD.times do
# contact_first.verify_email
# end
ValidationEvent::VALID_EVENTS_COUNT_THRESHOLD.times do
contact_first.verify_email
end

# domain.reload
perform_check_force_delete_job(contact_first.id)
domain.reload

# assert_equal domain.status_notes[DomainStatus::FORCE_DELETE], invalid_emails
# notification = domain.registrar.notifications.last
# assert_not notification.text.include? asserted_text
# end
assert_equal domain.status_notes[DomainStatus::FORCE_DELETE], invalid_emails
notification = domain.registrar.notifications.last
assert_not notification.text.include? asserted_text
end

# def test_remove_invalid_email_from_domain_status_notes
# domain = domains(:airport)
# domain.update(valid_to: Time.zone.parse('2012-08-05'),
# statuses: %w[serverForceDelete serverRenewProhibited serverTransferProhibited],
# force_delete_data: { 'template_name': 'invalid_email', 'force_delete_type': 'soft' },
# status_notes: { "serverForceDelete": '`@internet2.ee `@internet.ee' })
def test_remove_invalid_email_from_domain_status_notes
domain = domains(:airport)
domain.update(valid_to: Time.zone.parse('2012-08-05'),
statuses: %w[serverForceDelete serverRenewProhibited serverTransferProhibited],
force_delete_data: { 'template_name': 'invalid_email', 'force_delete_type': 'soft' },
status_notes: { "serverForceDelete": '`@internet2.ee `@internet.ee' })

# travel_to Time.zone.parse('2010-07-05')
# email = '`@internet2.ee'
# invalid_email = '`@internet.ee'
# asserted_text = "Invalid email: #{invalid_email}"
travel_to Time.zone.parse('2010-07-05')
email = '`@internet2.ee'
invalid_email = '`@internet.ee'
asserted_text = "Invalid email: #{invalid_email}"

# Truemail.configure.default_validation_type = :regex
Truemail.configure.default_validation_type = :regex

# contact_first = domain.admin_contacts.first
# contact_first.update_attribute(:email_history, email)
# contact_first.update_attribute(:email, '[email protected]')
contact_first = domain.admin_contacts.first
contact_first.update_attribute(:email_history, email)
contact_first.update_attribute(:email, '[email protected]')

# travel_to Time.zone.parse('2010-07-05 0:00:03')
# contact_first.verify_email
# domain.reload
travel_to Time.zone.parse('2010-07-05 0:00:03')
contact_first.verify_email

# assert_equal domain.status_notes[DomainStatus::FORCE_DELETE], invalid_email
# notification = domain.registrar.notifications.last
# assert notification.text.include? asserted_text
# end
perform_check_force_delete_job(contact_first.id)
domain.reload

# def test_domain_should_have_several_bounced_emails
# @domain.update(valid_to: Time.zone.parse('2012-08-05'))
# assert_not @domain.force_delete_scheduled?
# travel_to Time.zone.parse('2010-07-05')
# email_one = '`@internet.ee'
# email_two = '@@internet.ee'
assert_equal domain.status_notes[DomainStatus::FORCE_DELETE], invalid_email
notification = domain.registrar.notifications.last
assert notification.text.include? asserted_text
end

def test_domain_should_have_several_bounced_emails
@domain.update(valid_to: Time.zone.parse('2012-08-05'))
assert_not @domain.force_delete_scheduled?
travel_to Time.zone.parse('2010-07-05')
email_one = '`@internet.ee'
email_two = '@@internet.ee'

contact_one = @domain.admin_contacts.first
contact_one.update_attribute(:email, email_one)
contact_one.verify_email
perform_check_force_delete_job(contact_one.id)

# contact_one = @domain.admin_contacts.first
# contact_one.update_attribute(:email, email_one)
# contact_one.verify_email
assert contact_one.need_to_start_force_delete?

# assert contact_one.need_to_start_force_delete?
contact_two = @domain.admin_contacts.first
contact_two.update_attribute(:email, email_two)
contact_two.verify_email
perform_check_force_delete_job(contact_two.id)

# contact_two = @domain.admin_contacts.first
# contact_two.update_attribute(:email, email_two)
# contact_two.verify_email
assert contact_two.need_to_start_force_delete?

# assert contact_two.need_to_start_force_delete?

# @domain.reload

# assert @domain.force_delete_scheduled?
# assert_equal Date.parse('2010-09-19'), @domain.force_delete_date.to_date
# assert_equal Date.parse('2010-08-05'), @domain.force_delete_start.to_date
# assert @domain.status_notes[DomainStatus::FORCE_DELETE].include? email_one
# assert @domain.status_notes[DomainStatus::FORCE_DELETE].include? email_two
# end
@domain.reload

assert @domain.force_delete_scheduled?
assert_equal Date.parse('2010-09-19'), @domain.force_delete_date.to_date
assert_equal Date.parse('2010-08-05'), @domain.force_delete_start.to_date
assert @domain.status_notes[DomainStatus::FORCE_DELETE].include? email_one
assert @domain.status_notes[DomainStatus::FORCE_DELETE].include? email_two
end

def test_lifts_force_delete_after_bounce_changes
@domain.update(valid_to: Time.zone.parse('2012-08-05'))
Expand Down Expand Up @@ -527,4 +535,12 @@ def prepare_bounced_email_address(email)
@bounced_mail.diagnostic = 'smtp; 550 5.1.1 user unknown'
@bounced_mail.save!
end

private

def perform_check_force_delete_job(contact_id)
perform_enqueued_jobs do
CheckForceDeleteJob.perform_now([contact_id])
end
end
end
Loading