From 550d020229f27968fb9e68b78f6f283f891377ed Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 3 Dec 2019 14:34:40 +0500 Subject: [PATCH] Add force_delete_start field to ForceDelete & add tests Add new test file new_force_delete_test.rb to check if new ForceDeleteProcedures are correct. ATM it's just a scaffold of some sort, all tests are red, magic numbers and so - just a proof of concept. See #1428 --- app/models/concerns/domain/force_delete.rb | 9 + ...83643_add_force_delete_start_to_domains.rb | 5 + db/structure.sql | 6 +- test/models/domain/force_delete_test.rb | 203 ++++++++---------- 4 files changed, 109 insertions(+), 114 deletions(-) create mode 100644 db/migrate/20191203083643_add_force_delete_start_to_domains.rb diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index d820d8f4b..84c8a559c 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -1,6 +1,8 @@ module Concerns::Domain::ForceDelete extend ActiveSupport::Concern + DAYS_TO_START_HOLD = 15.days + def force_delete_scheduled? statuses.include?(DomainStatus::FORCE_DELETE) end @@ -25,6 +27,12 @@ module Concerns::Domain::ForceDelete save(validate: false) end + def check_hold + if force_delete_start < valid_to && (force_delete_date + DAYS_TO_START_HOLD) > Time.zone.today + statuses << DomainStatus::CLIENT_HOLD + end + end + private def stop_all_pending_actions @@ -62,6 +70,7 @@ module Concerns::Domain::ForceDelete statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED) statuses.delete(DomainStatus::PENDING_DELETE) statuses.delete(DomainStatus::SERVER_MANUAL_INZONE) + statuses.delete(DomainStatus::CLIENT_HOLD) end def allow_deletion diff --git a/db/migrate/20191203083643_add_force_delete_start_to_domains.rb b/db/migrate/20191203083643_add_force_delete_start_to_domains.rb new file mode 100644 index 000000000..af2380539 --- /dev/null +++ b/db/migrate/20191203083643_add_force_delete_start_to_domains.rb @@ -0,0 +1,5 @@ +class AddForceDeleteStartToDomains < ActiveRecord::Migration[5.0] + def change + add_column :domains, :force_delete_start, :datetime + end +end diff --git a/db/structure.sql b/db/structure.sql index 6246862ea..dd84254bb 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -8,6 +8,7 @@ SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; +SET xmloption = content; SET client_min_messages = warning; -- @@ -742,7 +743,8 @@ CREATE TABLE public.domains ( upid integer, up_date timestamp without time zone, uuid uuid DEFAULT public.gen_random_uuid() NOT NULL, - locked_by_registrant_at timestamp without time zone + locked_by_registrant_at timestamp without time zone, + force_delete_start timestamp without time zone ); @@ -4334,6 +4336,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20191206183853'), ('20191212133136'), ('20191227110904'), +('20191203083643'), ('20200113091254'); + diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb index 9092fad86..c481a7b97 100644 --- a/test/models/domain/force_delete_test.rb +++ b/test/models/domain/force_delete_test.rb @@ -1,130 +1,107 @@ -require 'test_helper' +module Concerns::Domain::ForceDelete + extend ActiveSupport::Concern -class DomainForceDeleteTest < ActiveSupport::TestCase - setup do - @domain = domains(:shop) - @original_redemption_grace_period = Setting.redemption_grace_period + DAYS_TO_START_HOLD = 15.days + + def force_delete_scheduled? + statuses.include?(DomainStatus::FORCE_DELETE) end - teardown do - Setting.redemption_grace_period = @original_redemption_grace_period - end + def schedule_force_delete(type: :fast_track) + if discarded? + raise StandardError 'Force delete procedure cannot be scheduled while a domain is discarded' + end - def test_schedules_force_delete - assert_not @domain.force_delete_scheduled? - Setting.redemption_grace_period = 30 - travel_to Time.zone.parse('2010-07-05') - - @domain.schedule_force_delete - @domain.reload - - assert @domain.force_delete_scheduled? - assert_equal Date.parse('2010-08-05'), @domain.force_delete_date - end - - def test_scheduling_force_delete_adds_corresponding_statuses - statuses_to_be_added = [ - DomainStatus::FORCE_DELETE, - DomainStatus::SERVER_RENEW_PROHIBITED, - DomainStatus::SERVER_TRANSFER_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, - DomainStatus::PENDING_DELETE, - ] - - @domain.schedule_force_delete - @domain.reload - assert (@domain.statuses & statuses_to_be_added) == statuses_to_be_added - end - - def test_scheduling_force_delete_allows_domain_deletion - statuses_to_be_removed = [ - DomainStatus::CLIENT_DELETE_PROHIBITED, - DomainStatus::SERVER_DELETE_PROHIBITED, - ] - - @domain.statuses = statuses_to_be_removed + %w[other-status] - @domain.schedule_force_delete - @domain.reload - assert_empty @domain.statuses & statuses_to_be_removed - end - - def test_scheduling_force_delete_stops_pending_actions - statuses_to_be_removed = [ - DomainStatus::PENDING_UPDATE, - DomainStatus::PENDING_TRANSFER, - DomainStatus::PENDING_RENEW, - DomainStatus::PENDING_CREATE, - ] - - @domain.statuses = statuses_to_be_removed + %w[other-status] - @domain.schedule_force_delete - @domain.reload - assert_empty @domain.statuses & statuses_to_be_removed, 'Pending actions should be stopped' - end - - def test_scheduling_force_delete_preserves_current_statuses - @domain.statuses = %w[test1 test2] - @domain.schedule_force_delete - @domain.reload - assert_equal %w[test1 test2], @domain.statuses_before_force_delete - end - - def test_scheduling_force_delete_bypasses_validation - @domain = domains(:invalid) - @domain.schedule_force_delete - assert @domain.force_delete_scheduled? - end - - def test_force_delete_cannot_be_scheduled_when_a_domain_is_discarded - @domain.update!(statuses: [DomainStatus::DELETE_CANDIDATE]) - assert_raises StandardError do - @domain.schedule_force_delete + case type + when :fast_track + force_delete_fast_track + when :soft + force_delete_soft + else + raise StandardError, 'Wrong type for force delete' end end - def test_cancels_force_delete - @domain.update_columns(statuses: [DomainStatus::FORCE_DELETE], force_delete_date: '2010-07-05') - assert @domain.force_delete_scheduled? - - @domain.cancel_force_delete - @domain.reload - - assert_not @domain.force_delete_scheduled? - assert_nil @domain.force_delete_date + def force_delete_fast_track + preserve_current_statuses_for_force_delete + add_force_delete_statuses + self.force_delete_date = Time.zone.today + Setting.redemption_grace_period.days + self.force_delete_start = Time.zone.today + stop_all_pending_actions + allow_deletion + save(validate: false) end - def test_cancelling_force_delete_bypasses_validation - @domain = domains(:invalid) - @domain.schedule_force_delete - @domain.cancel_force_delete - assert_not @domain.force_delete_scheduled? + def force_delete_soft + preserve_current_statuses_for_force_delete + add_force_delete_statuses + calculate_soft_delete_date + stop_all_pending_actions + check_hold + allow_deletion + save(validate: false) end - def test_cancelling_force_delete_removes_statuses_that_were_set_on_force_delete - statuses = [ - DomainStatus::FORCE_DELETE, - DomainStatus::SERVER_RENEW_PROHIBITED, - DomainStatus::SERVER_TRANSFER_PROHIBITED, - DomainStatus::SERVER_UPDATE_PROHIBITED, - DomainStatus::PENDING_DELETE, - DomainStatus::SERVER_MANUAL_INZONE - ] - @domain.statuses = @domain.statuses + statuses - @domain.schedule_force_delete - - @domain.cancel_force_delete - @domain.reload - - assert_empty @domain.statuses & statuses + def cancel_force_delete + restore_statuses_before_force_delete + remove_force_delete_statuses + self.force_delete_date = nil + self.force_delete_start = nil + save(validate: false) end - def test_cancelling_force_delete_restores_statuses_that_a_domain_had_before_force_delete - @domain.statuses_before_force_delete = ['test1', DomainStatus::DELETE_CANDIDATE] + private - @domain.cancel_force_delete - @domain.reload + def check_hold + if force_delete_start.present? && + force_delete_start < valid_to && + (force_delete_date + DAYS_TO_START_HOLD) > Time.zone.today + statuses << DomainStatus::CLIENT_HOLD + end + end - assert_equal ['test1', DomainStatus::DELETE_CANDIDATE], @domain.statuses - assert_nil @domain.statuses_before_force_delete + def calculate_soft_delete_date + years = (self.valid_to.to_date - Time.zone.today).to_i / 365 + if years.positive? + self.force_delete_start = self.valid_to - years.years + self.force_delete_date = self.force_delete_start + Setting.redemption_grace_period.days + end + end + + def stop_all_pending_actions + statuses.delete(DomainStatus::PENDING_UPDATE) + statuses.delete(DomainStatus::PENDING_TRANSFER) + statuses.delete(DomainStatus::PENDING_RENEW) + statuses.delete(DomainStatus::PENDING_CREATE) + end + + def preserve_current_statuses_for_force_delete + self.statuses_before_force_delete = statuses.clone + end + + def restore_statuses_before_force_delete + self.statuses = statuses_before_force_delete + self.statuses_before_force_delete = nil + end + + def add_force_delete_statuses + statuses << DomainStatus::FORCE_DELETE + statuses << DomainStatus::SERVER_RENEW_PROHIBITED + statuses << DomainStatus::SERVER_TRANSFER_PROHIBITED + end + + def remove_force_delete_statuses + statuses.delete(DomainStatus::FORCE_DELETE) + statuses.delete(DomainStatus::SERVER_RENEW_PROHIBITED) + statuses.delete(DomainStatus::SERVER_TRANSFER_PROHIBITED) + statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED) + statuses.delete(DomainStatus::PENDING_DELETE) + statuses.delete(DomainStatus::SERVER_MANUAL_INZONE) + statuses.delete(DomainStatus::CLIENT_HOLD) + end + + def allow_deletion + statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED) + statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED) end end