diff --git a/Gemfile.lock b/Gemfile.lock index 6d9105baf..efa504d8e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -275,7 +275,7 @@ GEM multi_json (1.12.1) multi_xml (0.6.0) netrc (0.11.0) - nokogiri (1.8.1) + nokogiri (1.8.2) mini_portile2 (~> 2.3.0) nori (2.6.0) open4 (1.3.4) diff --git a/app/models/concerns/domain/deletable.rb b/app/models/concerns/domain/deletable.rb index f724162e5..86c296d88 100644 --- a/app/models/concerns/domain/deletable.rb +++ b/app/models/concerns/domain/deletable.rb @@ -5,6 +5,11 @@ module Concerns::Domain::Deletable alias_attribute :delete_time, :delete_at end + def discard + statuses << DomainStatus::DELETE_CANDIDATE + save + end + def discarded? statuses.include?(DomainStatus::DELETE_CANDIDATE) end diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index e0ea4253d..3ff0e9023 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -23,6 +23,12 @@ class WhoisRecord < ActiveRecord::Base h = HashWithIndifferentAccess.new return h if domain.blank? + if domain.discarded? + h[:name] = domain.name + h[:status] = ['deleteCandidate'] + return h + end + status_map = { 'ok' => 'ok (paid and in zone)' } @@ -34,7 +40,7 @@ class WhoisRecord < ActiveRecord::Base h[:status] = domain.statuses.map { |x| status_map[x] || x } h[:registered] = domain.registered_at.try(:to_s, :iso8601) h[:changed] = domain.updated_at.try(:to_s, :iso8601) - h[:expire] = domain.valid_to.try(:to_date).try(:to_s) + h[:expire] = domain.valid_to.to_date.to_s h[:outzone] = domain.outzone_at.try(:to_date).try(:to_s) h[:delete] = [domain.delete_at, domain.force_delete_at].compact.min.try(:to_date).try(:to_s) @@ -88,7 +94,8 @@ class WhoisRecord < ActiveRecord::Base end def generated_body - template = Rails.root.join("app/views/for_models/whois.erb".freeze) + template_name = domain.discarded? ? 'whois_discarded.erb' : 'whois.erb' + template = Rails.root.join("app/views/for_models/#{template_name}".freeze) ERB.new(template.read, nil, "-").result(binding) end # rubocop:enable Metrics/MethodLength diff --git a/app/presenters/domain_presenter.rb b/app/presenters/domain_presenter.rb index 9597330b8..aac3c1527 100644 --- a/app/presenters/domain_presenter.rb +++ b/app/presenters/domain_presenter.rb @@ -6,6 +6,17 @@ class DomainPresenter @view = view end + def name_with_status + html = domain.name + + if domain.discarded? + label = view.content_tag(:span, 'deleteCandidate', class: 'label label-warning') + html += " #{label}" + end + + html.html_safe + end + def expire_time view.l(domain.expire_time) end diff --git a/app/views/admin/domains/show.haml b/app/views/admin/domains/show.haml deleted file mode 100644 index 17a85b841..000000000 --- a/app/views/admin/domains/show.haml +++ /dev/null @@ -1,24 +0,0 @@ -- content_for :actions do - = link_to(t(:edit_statuses), edit_admin_domain_path(@domain), class: 'btn btn-primary') - = link_to(t(:history), admin_domain_domain_versions_path(@domain.id), method: :get, class: 'btn btn-primary') - -= render 'shared/title', name: @domain.name - -.row - .col-md-6= render 'admin/domains/partials/general' - .col-md-6= render 'admin/domains/partials/owner' -.row - .col-md-12= render 'admin/domains/partials/tech_contacts' -.row - .col-md-12= render 'admin/domains/partials/admin_contacts' -.row - .col-md-12= render 'admin/domains/partials/statuses' -.row - .col-md-12= render 'admin/domains/partials/nameservers' -.row - .col-md-12= render 'admin/domains/partials/dnskeys' -.row - .col-md-12= render 'admin/domains/partials/keyrelays' -.row - .col-md-12 - = render 'admin/domains/partials/legal_documents', legal_documents: @domain.legal_documents diff --git a/app/views/admin/domains/show.html.erb b/app/views/admin/domains/show.html.erb new file mode 100644 index 000000000..1501b35bb --- /dev/null +++ b/app/views/admin/domains/show.html.erb @@ -0,0 +1,71 @@ +<% domain = DomainPresenter.new(domain: @domain, view: self) %> + + + + + +
+
+ <%= render 'admin/domains/partials/general' %> +
+
+ <%= render 'admin/domains/partials/owner' %> +
+
+ +
+
+ <%= render 'admin/domains/partials/tech_contacts' %> +
+
+ +
+
+ <%= render 'admin/domains/partials/admin_contacts' %> +
+
+ +
+
+ <%= render 'admin/domains/partials/statuses' %> +
+
+ +
+
+ <%= render 'admin/domains/partials/nameservers' %> +
+
+ +
+
+ <%= render 'admin/domains/partials/dnskeys' %> +
+
+ +
+
+ <%= render 'admin/domains/partials/keyrelays' %> +
+
+ +
+
+ <%= render 'admin/domains/partials/legal_documents', legal_documents: + @domain.legal_documents %> +
+
diff --git a/app/views/admin/domains/zonefile.haml b/app/views/admin/domains/zonefile.haml deleted file mode 100644 index 72473ef53..000000000 --- a/app/views/admin/domains/zonefile.haml +++ /dev/null @@ -1,8 +0,0 @@ -- content_for :actions do - = link_to(t(:back_to_domain), admin_domain_path(@domain), class: 'btn btn-default') -= render 'shared/title', name: t(:zonefile) - -.row - .col-md-12 - = preserve do - %pre= @zonefile diff --git a/app/views/epp/domains/create.xml.builder b/app/views/epp/domains/create.xml.builder index 213a2aa8f..2293f5657 100644 --- a/app/views/epp/domains/create.xml.builder +++ b/app/views/epp/domains/create.xml.builder @@ -8,7 +8,7 @@ xml.epp_head do xml.tag!('domain:creData', 'xmlns:domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd') do xml.tag!('domain:name', @domain.name) xml.tag!('domain:crDate', @domain.created_at.try(:iso8601)) - xml.tag!('domain:exDate', @domain.valid_to.try(:iso8601)) + xml.tag!('domain:exDate', @domain.valid_to.iso8601) end end diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder index 8bf169acd..2d10f8baf 100644 --- a/app/views/epp/domains/info.xml.builder +++ b/app/views/epp/domains/info.xml.builder @@ -48,7 +48,7 @@ xml.epp_head do xml.tag!('domain:upDate', @domain.updated_at.try(:iso8601)) end - xml.tag!('domain:exDate', @domain.valid_to.try(:iso8601)) + xml.tag!('domain:exDate', @domain.valid_to.iso8601) # TODO Make domain transferrable #xml.tag!('domain:trDate', @domain.transferred_at) if @domain.transferred_at diff --git a/app/views/epp/domains/partials/_transfer.xml.builder b/app/views/epp/domains/partials/_transfer.xml.builder index 151af28b3..bfcc7db94 100644 --- a/app/views/epp/domains/partials/_transfer.xml.builder +++ b/app/views/epp/domains/partials/_transfer.xml.builder @@ -5,5 +5,5 @@ builder.tag!('domain:trnData', 'xmlns:domain' => 'https://epp.tld.ee/schema/doma builder.tag!('domain:reDate', dt.transfer_requested_at.try(:iso8601)) builder.tag!('domain:acID', dt.old_registrar.code) builder.tag!('domain:acDate', dt.transferred_at.try(:iso8601) || dt.wait_until.try(:iso8601)) - builder.tag!('domain:exDate', dt.domain_valid_to.try(:iso8601)) + builder.tag!('domain:exDate', dt.domain_valid_to.iso8601) end diff --git a/app/views/epp/domains/renew.xml.builder b/app/views/epp/domains/renew.xml.builder index 5d03c7128..e407ff0e7 100644 --- a/app/views/epp/domains/renew.xml.builder +++ b/app/views/epp/domains/renew.xml.builder @@ -7,7 +7,7 @@ xml.epp_head do xml.resData do xml.tag!('domain:renData', 'xmlns:domain' => 'https://epp.tld.ee/schema/domain-eis-1.0.xsd') do xml.tag!('domain:name', @domain[:name]) - xml.tag!('domain:exDate', @domain.valid_to.try(:iso8601)) + xml.tag!('domain:exDate', @domain.valid_to.iso8601) end end diff --git a/app/views/for_models/whois_discarded.erb b/app/views/for_models/whois_discarded.erb new file mode 100644 index 000000000..ecaa6f9af --- /dev/null +++ b/app/views/for_models/whois_discarded.erb @@ -0,0 +1,8 @@ +Estonia .ee Top Level Domain WHOIS server + +Domain: +name: <%= json['name'] %> +status: <%= json['status'] %> + +Estonia .ee Top Level Domain WHOIS server +More information at http://internet.ee diff --git a/config/locales/admin/domains.en.yml b/config/locales/admin/domains.en.yml index 200657d01..87c2c9c6a 100644 --- a/config/locales/admin/domains.en.yml +++ b/config/locales/admin/domains.en.yml @@ -5,6 +5,10 @@ en: header: Domains registrant: Registrant + show: + edit_btn: Edit statuses + history_btn: History + search_form: reset_btn: Reset diff --git a/config/locales/en.yml b/config/locales/en.yml index 4cdd5a41f..7ac84379f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -337,7 +337,6 @@ en: transfer_requested: 'Transfer requested.' message_was_not_found: 'Message was not found' - zonefile: 'Zonefile' only_one_parameter_allowed: 'Only one parameter allowed: %{param_1} or %{param_2}' exactly_one_parameter_required: 'Exactly one parameter required: %{params}' ds_data_with_key_allowed: 'Allow DS data with key' diff --git a/db/migrate/20180331200125_change_domains_valid_to_to_not_null.rb b/db/migrate/20180331200125_change_domains_valid_to_to_not_null.rb new file mode 100644 index 000000000..049b08806 --- /dev/null +++ b/db/migrate/20180331200125_change_domains_valid_to_to_not_null.rb @@ -0,0 +1,5 @@ +class ChangeDomainsValidToToNotNull < ActiveRecord::Migration + def change + change_column_null :domains, :valid_to, false + end +end diff --git a/db/structure.sql b/db/structure.sql index 616a83c64..744ea9e19 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -872,7 +872,7 @@ CREATE TABLE domains ( registrar_id integer NOT NULL, registered_at timestamp without time zone, status character varying, - valid_to timestamp without time zone, + valid_to timestamp without time zone NOT NULL, registrant_id integer NOT NULL, transfer_code character varying NOT NULL, created_at timestamp without time zone, @@ -4714,3 +4714,5 @@ INSERT INTO schema_migrations (version) VALUES ('20180314122722'); INSERT INTO schema_migrations (version) VALUES ('20180327151906'); +INSERT INTO schema_migrations (version) VALUES ('20180331200125'); + diff --git a/spec/factories/domain.rb b/spec/factories/domain.rb index fc4d3a97b..39ad2240d 100644 --- a/spec/factories/domain.rb +++ b/spec/factories/domain.rb @@ -3,6 +3,7 @@ FactoryBot.define do sequence(:name) { |n| "test#{n}.com" } period 1 period_unit 'y' # Year + valid_to Time.zone.parse('2010-07-05') registrar registrant @@ -10,9 +11,5 @@ FactoryBot.define do domain.admin_domain_contacts << FactoryBot.build(:admin_domain_contact) domain.tech_domain_contacts << FactoryBot.build(:tech_domain_contact) end - - factory :domain_discarded do - statuses [DomainStatus::DELETE_CANDIDATE] - end end end diff --git a/spec/models/concerns/domain/deletable_spec.rb b/spec/models/concerns/domain/deletable_spec.rb deleted file mode 100644 index 826299b69..000000000 --- a/spec/models/concerns/domain/deletable_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'rails_helper' - -RSpec.describe Domain, db: false do - it { is_expected.to alias_attribute(:delete_time, :delete_at) } - - describe '#discarded?' do - context 'when :deleteCandidate status is present' do - let(:domain) { described_class.new(statuses: [DomainStatus::DELETE_CANDIDATE]) } - - specify { expect(domain).to be_discarded } - end - - context 'when :deleteCandidate status is absent' do - let(:domain) { described_class.new(statuses: []) } - - specify { expect(domain).to_not be_discarded } - end - end -end diff --git a/spec/requests/epp/domain/delete/discarded_spec.rb b/spec/requests/epp/domain/delete/discarded_spec.rb deleted file mode 100644 index 55e74d965..000000000 --- a/spec/requests/epp/domain/delete/discarded_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:delete' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request_xml) { <<-XML - - - - - - test.com - - - - - dGVzdCBmYWlsCg== - - - - - XML - } - - before :example do - login_as user - end - - context 'when domain is not discarded' do - let!(:domain) { create(:domain, name: 'test.com') } - - it 'returns epp code of 1001' do - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response).to have_code_of(1001) - end - end - - context 'when domain is discarded' do - let!(:domain) { create(:domain_discarded, name: 'test.com') } - - it 'returns epp code of 2105' do - post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response).to have_code_of(2105) - end - end -end diff --git a/spec/requests/epp/domain/update/discarded_spec.rb b/spec/requests/epp/domain/update/discarded_spec.rb deleted file mode 100644 index 4a31b7d10..000000000 --- a/spec/requests/epp/domain/update/discarded_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'rails_helper' - -RSpec.describe 'EPP domain:update' do - let(:registrar) { create(:registrar) } - let(:user) { create(:api_user_epp, registrar: registrar) } - let(:session_id) { create(:epp_session, user: user).session_id } - let(:request_xml) { <<-XML - - - - - - test.com - - - - - XML - } - - before :example do - login_as user - end - - context 'when domain is not discarded' do - let!(:domain) { create(:domain, name: 'test.com') } - - it 'returns epp code of 1000' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response).to have_code_of(1000) - end - end - - context 'when domain is discarded' do - let!(:domain) { create(:domain_discarded, name: 'test.com') } - - it 'returns epp code of 2105' do - post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => "session=#{session_id}" - expect(response).to have_code_of(2105) - end - end -end diff --git a/test/integration/admin/domains/details_test.rb b/test/integration/admin/domains/details_test.rb new file mode 100644 index 000000000..a3ec6bdeb --- /dev/null +++ b/test/integration/admin/domains/details_test.rb @@ -0,0 +1,16 @@ +require 'test_helper' + +class AdminAreaDomainDetailsTest < ActionDispatch::IntegrationTest + setup do + login_as users(:admin) + @domain = domains(:shop) + end + + def test_discarded_domain_has_corresponding_label + visit admin_domain_url(@domain) + assert_no_css 'span.label.label-warning', text: 'deleteCandidate' + @domain.discard + visit admin_domain_url(@domain) + assert_css 'span.label.label-warning', text: 'deleteCandidate' + end +end diff --git a/test/integration/epp/domain/domain_delete_test.rb b/test/integration/epp/domain/domain_delete_test.rb index bdd326a3e..eae4d39ff 100644 --- a/test/integration/epp/domain/domain_delete_test.rb +++ b/test/integration/epp/domain/domain_delete_test.rb @@ -25,4 +25,31 @@ class EppDomainDeleteTest < ActionDispatch::IntegrationTest assert_equal '1001', Nokogiri::XML(response.body).at_css('result')[:code] assert_equal 1, Nokogiri::XML(response.body).css('result').size end + + def test_discarded_domain_cannot_be_deleted + domains(:shop).discard + + request_xml = <<-XML + + + + + + shop.test + + + + + dGVzdCBmYWlsCg== + + + + + XML + + assert_no_difference 'Domain.count' do + post '/epp/command/delete', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + end + assert_equal '2105', Nokogiri::XML(response.body).at_css('result')[:code] + end end diff --git a/test/integration/epp/domain/update/transfer_code_test.rb b/test/integration/epp/domain/domain_update_test.rb similarity index 53% rename from test/integration/epp/domain/update/transfer_code_test.rb rename to test/integration/epp/domain/domain_update_test.rb index 92ee58a02..ac7160558 100644 --- a/test/integration/epp/domain/update/transfer_code_test.rb +++ b/test/integration/epp/domain/domain_update_test.rb @@ -1,7 +1,7 @@ require 'test_helper' class EppDomainUpdateTest < ActionDispatch::IntegrationTest - def test_overwrites_existing + def test_update_domain request_xml = <<-XML @@ -20,9 +20,29 @@ class EppDomainUpdateTest < ActionDispatch::IntegrationTest XML - post '/epp/command/update', { frame: request_xml }, { 'HTTP_COOKIE' => 'session=api_bestnames' } + post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' assert_equal 'f0ff7d17b0', domains(:shop).transfer_code assert_equal '1000', Nokogiri::XML(response.body).at_css('result')[:code] assert_equal 1, Nokogiri::XML(response.body).css('result').size end + + def test_discarded_domain_cannot_be_updated + domains(:shop).discard + + request_xml = <<-XML + + + + + + shop.test + + + + + XML + + post '/epp/command/update', { frame: request_xml }, 'HTTP_COOKIE' => 'session=api_bestnames' + assert_equal '2105', Nokogiri::XML(response.body).at_css('result')[:code] + end end diff --git a/test/models/domain/deletable_test.rb b/test/models/domain/deletable_test.rb new file mode 100644 index 000000000..dbec7bc7f --- /dev/null +++ b/test/models/domain/deletable_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class DomainDeletableTest < ActiveSupport::TestCase + setup do + @domain = domains(:shop) + end + + def test_discard + refute @domain.discarded? + @domain.discard + @domain.reload + assert @domain.discarded? + end +end