diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb
index 96f1a94b3..45f45dab6 100644
--- a/app/models/concerns/domain/force_delete.rb
+++ b/app/models/concerns/domain/force_delete.rb
@@ -1,30 +1,48 @@
module Concerns::Domain::ForceDelete
extend ActiveSupport::Concern
- included do
- alias_attribute :force_delete_time, :force_delete_at
- end
-
def force_delete_scheduled?
statuses.include?(DomainStatus::FORCE_DELETE)
end
def schedule_force_delete
- self.statuses_backup = statuses
- statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
- statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
+ preserve_current_statuses_for_force_delete
+ add_force_delete_statuses
+ self.force_delete_at = (Time.zone.now + (Setting.redemption_grace_period.days + 1.day)).utc
+ .beginning_of_day
+ stop_all_pending_actions
+ allow_deletion
+ save(validate: false)
+ end
+
+ def cancel_force_delete
+ raise 'Domain must be discarded before cancelling force delete procedure' unless discarded?
+
+ restore_statuses_before_force_delete
+ remove_force_delete_statuses
+ self.force_delete_at = nil
+ save(validate: false)
+ end
+
+ private
+
+ 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
- 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::SERVER_MANUAL_INZONE)
- statuses.delete(DomainStatus::PENDING_DELETE)
+ def preserve_current_statuses_for_force_delete
+ self.statuses_before_force_delete = statuses
+ 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
@@ -34,21 +52,19 @@ module Concerns::Domain::ForceDelete
if (statuses & [DomainStatus::SERVER_HOLD, DomainStatus::CLIENT_HOLD]).empty?
statuses << DomainStatus::SERVER_MANUAL_INZONE
end
-
- self.force_delete_at = (Time.zone.now + (Setting.redemption_grace_period.days + 1.day)).utc.beginning_of_day unless force_delete_at
- save!(validate: false)
end
- def cancel_force_delete
- s = []
- s << DomainStatus::EXPIRED if statuses.include?(DomainStatus::EXPIRED)
- s << DomainStatus::SERVER_HOLD if statuses.include?(DomainStatus::SERVER_HOLD)
- s << DomainStatus::DELETE_CANDIDATE if statuses.include?(DomainStatus::DELETE_CANDIDATE)
+ 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)
+ end
- self.statuses = (statuses_backup + s).uniq
-
- self.force_delete_at = nil
- self.statuses_backup = []
- save(validate: false)
+ def allow_deletion
+ statuses.delete(DomainStatus::CLIENT_DELETE_PROHIBITED)
+ statuses.delete(DomainStatus::SERVER_DELETE_PROHIBITED)
end
end
diff --git a/app/models/domain.rb b/app/models/domain.rb
index 0ec5c67fd..855d98e12 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -577,6 +577,7 @@ class Domain < ActiveRecord::Base
hash = super
hash['auth_info'] = hash.delete('transfer_code') # API v1 requirement
hash['valid_from'] = hash['registered_at'] # API v1 requirement
+ hash.delete('statuses_before_force_delete')
hash
end
diff --git a/app/presenters/domain_presenter.rb b/app/presenters/domain_presenter.rb
index 11d767203..30441ec7d 100644
--- a/app/presenters/domain_presenter.rb
+++ b/app/presenters/domain_presenter.rb
@@ -34,7 +34,7 @@ class DomainPresenter
end
def force_delete_date
- view.l(domain.force_delete_time, format: :date) if domain.force_delete_time
+ view.l(domain.force_delete_at, format: :date) if domain.force_delete_at
end
def admin_contact_names
diff --git a/app/views/admin/domains/partials/_general.html.erb b/app/views/admin/domains/partials/_general.html.erb
index 7e09a7756..5be18eba4 100644
--- a/app/views/admin/domains/partials/_general.html.erb
+++ b/app/views/admin/domains/partials/_general.html.erb
@@ -31,8 +31,8 @@
<%= t('.delete_time') %>
<%= l(@domain.delete_at) %>
- <%= t('.force_delete_time') %>
- <%= l(@domain.force_delete_at) %>
+ <%= Domain.human_attribute_name :force_delete_at %>
+ <%= l @domain.force_delete_at %>
diff --git a/config/locales/admin/domains.en.yml b/config/locales/admin/domains.en.yml
index da4c4f013..9ae02ba21 100644
--- a/config/locales/admin/domains.en.yml
+++ b/config/locales/admin/domains.en.yml
@@ -37,7 +37,6 @@ en:
general:
outzone_time: Outzone time
delete_time: Delete time
- force_delete_time: Force delete time
admin_contacts:
title: Admin. contacts
diff --git a/db/migrate/20180422154642_rename_domains_statuses_backup_to_statuses_before_force_delete.rb b/db/migrate/20180422154642_rename_domains_statuses_backup_to_statuses_before_force_delete.rb
new file mode 100644
index 000000000..a6784f02e
--- /dev/null
+++ b/db/migrate/20180422154642_rename_domains_statuses_backup_to_statuses_before_force_delete.rb
@@ -0,0 +1,5 @@
+class RenameDomainsStatusesBackupToStatusesBeforeForceDelete < ActiveRecord::Migration
+ def change
+ rename_column :domains, :statuses_backup, :statuses_before_force_delete
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index b07f08000..3bd6939f6 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -909,7 +909,7 @@ CREATE TABLE public.domains (
statuses character varying[],
reserved boolean DEFAULT false,
status_notes public.hstore,
- statuses_backup character varying[] DEFAULT '{}'::character varying[],
+ statuses_before_force_delete character varying[] DEFAULT '{}'::character varying[],
upid integer,
up_date timestamp without time zone,
uuid uuid DEFAULT public.gen_random_uuid() NOT NULL
@@ -4747,6 +4747,8 @@ INSERT INTO schema_migrations (version) VALUES ('20180327151906');
INSERT INTO schema_migrations (version) VALUES ('20180331200125');
+INSERT INTO schema_migrations (version) VALUES ('20180422154642');
+
INSERT INTO schema_migrations (version) VALUES ('20180612042234');
INSERT INTO schema_migrations (version) VALUES ('20180612042625');
diff --git a/doc/repp/v1/domain.md b/doc/repp/v1/domain.md
index adb9c4c8e..4c9476125 100644
--- a/doc/repp/v1/domain.md
+++ b/doc/repp/v1/domain.md
@@ -63,10 +63,7 @@ Content-Type: application/json
],
"reserved": false,
"status_notes": {
- },
- "statuses_backup": [
-
- ]
+ }
}
],
"total_number_of_records": 2
diff --git a/spec/models/concerns/domain/force_delete_spec.rb b/spec/models/concerns/domain/force_delete_spec.rb
deleted file mode 100644
index cc022a6d7..000000000
--- a/spec/models/concerns/domain/force_delete_spec.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe Domain do
- it { is_expected.to alias_attribute(:force_delete_time, :force_delete_at) }
-
- before :example do
- create(:zone, origin: 'ee')
- end
-
- it 'should set force delete time' do
- domain = build(:domain)
- domain.nameservers.build(attributes_for(:nameserver))
- domain.nameservers.build(attributes_for(:nameserver))
- domain.save!
-
- domain.statuses = ['ok']
- domain.schedule_force_delete
-
- domain.statuses.should match_array([
- "serverForceDelete",
- "pendingDelete",
- "serverManualInzone",
- "serverRenewProhibited",
- "serverTransferProhibited",
- "serverUpdateProhibited"
- ])
-
- domain.cancel_force_delete
-
- domain.statuses.should == ['ok']
-
- domain.statuses = [
- DomainStatus::CLIENT_DELETE_PROHIBITED,
- DomainStatus::SERVER_DELETE_PROHIBITED,
- DomainStatus::PENDING_UPDATE,
- DomainStatus::PENDING_TRANSFER,
- DomainStatus::PENDING_RENEW,
- DomainStatus::PENDING_CREATE,
- DomainStatus::CLIENT_HOLD,
- DomainStatus::EXPIRED,
- DomainStatus::SERVER_HOLD,
- DomainStatus::DELETE_CANDIDATE
- ]
-
- domain.save
-
- domain.schedule_force_delete
-
- domain.statuses.should match_array([
- "clientHold",
- "deleteCandidate",
- "expired",
- "serverForceDelete",
- "pendingDelete",
- "serverHold",
- "serverRenewProhibited",
- "serverTransferProhibited",
- "serverUpdateProhibited"
- ])
-
- domain.cancel_force_delete
-
- domain.statuses.should match_array([
- "clientDeleteProhibited",
- "clientHold",
- "deleteCandidate",
- "expired",
- "pendingCreate",
- "pendingRenew",
- "pendingTransfer",
- "pendingUpdate",
- "serverDeleteProhibited",
- "serverHold"
- ])
- end
-
- it 'should should be manual in zone and held after force delete' do
- domain = create(:domain)
- Setting.redemption_grace_period = 1
-
- domain.valid?
- domain.outzone_at = Time.zone.now + 1.day # before redemption grace period
- # what should this be?
- # domain.server_holdable?.should be true
- domain.statuses.include?(DomainStatus::SERVER_HOLD).should be false
- domain.statuses.include?(DomainStatus::SERVER_MANUAL_INZONE).should be false
- domain.schedule_force_delete
- domain.server_holdable?.should be false
- domain.statuses.include?(DomainStatus::SERVER_MANUAL_INZONE).should be true
- domain.statuses.include?(DomainStatus::SERVER_HOLD).should be false
- end
-
- it 'should not allow update after force delete' do
- domain = create(:domain)
- domain.valid?
- domain.pending_update_prohibited?.should be false
- domain.update_prohibited?.should be false
- domain.schedule_force_delete
- domain.pending_update_prohibited?.should be true
- domain.update_prohibited?.should be true
- end
-end
diff --git a/spec/presenters/domain_presenter_spec.rb b/spec/presenters/domain_presenter_spec.rb
index d0cef5e6d..ff4fc2841 100644
--- a/spec/presenters/domain_presenter_spec.rb
+++ b/spec/presenters/domain_presenter_spec.rb
@@ -63,7 +63,7 @@ RSpec.describe DomainPresenter do
subject(:force_delete_date) { presenter.force_delete_date }
context 'when present' do
- let(:domain) { instance_double(Domain, force_delete_time: '05.07.2010') }
+ let(:domain) { instance_double(Domain, force_delete_at: '05.07.2010') }
it 'returns localized date' do
expect(view).to receive(:l).with('05.07.2010', format: :date).and_return('delete date')
@@ -72,7 +72,7 @@ RSpec.describe DomainPresenter do
end
context 'when absent' do
- let(:domain) { instance_double(Domain, force_delete_time: nil) }
+ let(:domain) { instance_double(Domain, force_delete_at: nil) }
specify { expect(force_delete_date).to be_nil }
end
diff --git a/test/integration/admin/domains/force_delete_test.rb b/test/integration/admin/domains/force_delete_test.rb
index 3e5d7d4d6..d48444fb9 100644
--- a/test/integration/admin/domains/force_delete_test.rb
+++ b/test/integration/admin/domains/force_delete_test.rb
@@ -44,8 +44,8 @@ class AdminAreaDomainForceDeleteTest < ActionDispatch::IntegrationTest
end
def test_cancels_scheduled_domain_force_delete
- @domain.update_attribute(:statuses, [DomainStatus::FORCE_DELETE])
- assert @domain.force_delete_scheduled?
+ @domain.discard
+ @domain.schedule_force_delete
visit edit_admin_domain_url(@domain)
click_link_or_button 'Cancel force delete'
diff --git a/test/models/domain/force_delete_test.rb b/test/models/domain/force_delete_test.rb
new file mode 100644
index 000000000..535ad84d8
--- /dev/null
+++ b/test/models/domain/force_delete_test.rb
@@ -0,0 +1,129 @@
+require 'test_helper'
+
+class DomainForceDeleteTest < ActiveSupport::TestCase
+ def setup
+ @domain = domains(:shop)
+ end
+
+ def test_schedule_force_delete
+ @original_redemption_grace_period = Setting.redemption_grace_period
+ Setting.redemption_grace_period = 30
+ travel_to Time.zone.parse('2010-07-05 00:00')
+
+ @domain.schedule_force_delete
+ @domain.reload
+
+ assert @domain.force_delete_scheduled?
+ assert_equal Time.zone.parse('2010-08-04 03:00'), @domain.force_delete_at
+
+ travel_back
+ Setting.redemption_grace_period = @original_redemption_grace_period
+ 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_cancelling_force_delete_on_a_discarded_domain
+ @domain.discard
+ @domain.schedule_force_delete
+ @domain.cancel_force_delete
+ @domain.reload
+ assert_not @domain.force_delete_scheduled?
+ assert_nil @domain.force_delete_at
+ end
+
+ def test_cancelling_force_delete_requires_a_domain_to_be_discarded
+ @domain.schedule_force_delete
+ assert_raises StandardError do
+ @domain.cancel_force_delete
+ end
+ end
+
+ def test_cancelling_force_delete_bypasses_validation
+ @domain = domains(:invalid)
+ @domain.discard
+ @domain.schedule_force_delete
+ @domain.cancel_force_delete
+ assert_not @domain.force_delete_scheduled?
+ 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.discard
+ @domain.statuses = @domain.statuses + statuses
+ @domain.schedule_force_delete
+
+ @domain.cancel_force_delete
+ @domain.reload
+
+ assert_empty @domain.statuses & statuses
+ end
+
+ def test_cancelling_force_delete_restores_statuses_that_a_domain_had_before_force_delete
+ @domain.discard
+ @domain.statuses_before_force_delete = ['test1', DomainStatus::DELETE_CANDIDATE]
+
+ @domain.cancel_force_delete
+ @domain.reload
+
+ assert_equal ['test1', DomainStatus::DELETE_CANDIDATE], @domain.statuses
+ assert_nil @domain.statuses_before_force_delete
+ end
+end
diff --git a/test/support/rails5_assetions.rb b/test/support/rails5_assertions.rb
similarity index 100%
rename from test/support/rails5_assetions.rb
rename to test/support/rails5_assertions.rb
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 500861f75..56a4a7aeb 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -11,7 +11,7 @@ require 'minitest/mock'
require 'capybara/rails'
require 'capybara/minitest'
require 'webmock/minitest'
-require 'support/rails5_assetions' # Remove once upgraded to Rails 5
+require 'support/rails5_assertions' # Remove once upgraded to Rails 5
require 'application_system_test_case'