diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index eea0ccc03..8880e83d4 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-18.04] - ruby: [2.6, 2.7 ] + ruby: [ 2.7 ] runs-on: ${{ matrix.os }} continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }} steps: @@ -100,11 +100,6 @@ jobs: - name: Give test coverage reporter executable permissions run: chmod +x cc-test-reporter - - uses: actions/download-artifact@v1 - with: - name: coverage-2.6 - path: coverage - - uses: actions/download-artifact@v1 with: name: coverage-2.7 diff --git a/.ruby-version b/.ruby-version index 57cf282eb..37c2961c2 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.5 +2.7.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 153354e74..90abb0d34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +28.01.2021 +* Fixed transfer with shared admin and tech contacts [#1808](https://github.com/internetee/registry/issues/1808) +* Improved DNSSEC key validation for illegal characters [#1790](https://github.com/internetee/registry/issues/1790) +* Fix for whois record creation issue on releasing domain to auction [#1139](https://github.com/internetee/registry/issues/1139) +* Improved registrar account activity tests [#1824](https://github.com/internetee/registry/pull/1824) + +27.01.2021 +* Figaro update to 1.2.0 [#1823](https://github.com/internetee/registry/pull/1823) + +26.01.2021 +* Ruby update to 2.7 [#1791](https://github.com/internetee/registry/issues/1791) + +21.01.2021 +* Registrant API: optimised contact linking [#1807](https://github.com/internetee/registry/pull/1807) + +20.01.2021 +* Fixed legaldoc assignment issue on registrant confirmation [#1806](https://github.com/internetee/registry/pull/1806) + +14.01.2021 +* Fixed IDN and punycode support for REPP domain transfer_info request [#1801](https://github.com/internetee/registry/issues/1801) + 06.01.2021 * IMproved tests whois update for bulk nameserver change [#1739](https://github.com/internetee/registry/issues/1739) * Bulk ForceDelete funcionality in admin [#1177](https://github.com/internetee/registry/issues/1177) diff --git a/Dockerfile b/Dockerfile index 5d241eeef..97b0452e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM internetee/ruby:2.6-buster +FROM internetee/ruby:2.7-buster RUN mkdir -p /opt/webapps/app/tmp/pids WORKDIR /opt/webapps/app diff --git a/Gemfile b/Gemfile index b248030e9..fc6de7a2a 100644 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,7 @@ gem 'rest-client' gem 'uglifier' # load env -gem 'figaro', '1.1.1' +gem 'figaro', '~> 1.2' # model related gem 'activerecord-import' diff --git a/Gemfile.lock b/Gemfile.lock index c5be80f31..9e53ae2b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -204,8 +204,8 @@ GEM erubis (2.7.0) execjs (2.7.0) ffi (1.13.1) - figaro (1.1.1) - thor (~> 0.14) + figaro (1.2.0) + thor (>= 0.14.0, < 2) globalid (0.4.2) activesupport (>= 4.2.0) gyoku (1.3.1) @@ -506,7 +506,7 @@ DEPENDENCIES e_invoice! epp! epp-xml (= 1.1.0)! - figaro (= 1.1.1) + figaro (~> 1.2) haml (~> 5.0) isikukood iso8601 (= 0.12.1) diff --git a/app/controllers/api/v1/registrant/contacts_controller.rb b/app/controllers/api/v1/registrant/contacts_controller.rb index e11458ff8..ec59ed83f 100644 --- a/app/controllers/api/v1/registrant/contacts_controller.rb +++ b/app/controllers/api/v1/registrant/contacts_controller.rb @@ -24,7 +24,7 @@ module Api end def show - contact = current_user_contacts.find_by(uuid: params[:uuid]) + contact = representable_contact(params[:uuid]) links = params[:links] == 'true' if contact @@ -91,6 +91,22 @@ module Api private + def representable_contact(uuid) + country = current_registrant_user.country.alpha2 + contact = Contact.find_by(uuid: uuid, ident: current_registrant_user.ident, + ident_type: 'priv', ident_country_code: country) + return contact if contact + + Contact.find_by(uuid: uuid, ident_type: 'org', ident: company_codes, + ident_country_code: country) + rescue CompanyRegister::NotAvailableError + nil + end + + def company_codes + current_registrant_user.companies.collect(&:registration_number) + end + def current_user_contacts current_registrant_user.contacts(representable: false) rescue CompanyRegister::NotAvailableError diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb index 05386b535..25cf8fc91 100644 --- a/app/controllers/repp/v1/base_controller.rb +++ b/app/controllers/repp/v1/base_controller.rb @@ -1,7 +1,7 @@ module Repp module V1 class BaseController < ActionController::API # rubocop:disable Metrics/ClassLength - rescue_from ActiveRecord::RecordNotFound, with: :not_found_error + around_action :log_request before_action :authenticate_user before_action :validate_webclient_ca before_action :check_ip_restriction @@ -9,22 +9,31 @@ module Repp before_action :set_paper_trail_whodunnit - rescue_from ActionController::ParameterMissing, Apipie::ParamInvalid, - Apipie::ParamMissing do |exception| - render json: { code: 2003, message: exception }, status: :bad_request + private + + def log_request + yield + rescue ActiveRecord::RecordNotFound + @response = { code: 2303, message: 'Object does not exist' } + render(json: @response, status: :not_found) + rescue ActionController::ParameterMissing, Apipie::ParamInvalid, Apipie::ParamMissing => e + @response = { code: 2003, message: e } + render(json: @response, status: :bad_request) + ensure + create_repp_log end - after_action do + # rubocop:disable Metrics/AbcSize + def create_repp_log ApiLog::ReppLog.create( request_path: request.path, request_method: request.request_method, request_params: request.params.except('route_info').to_json, uuid: request.try(:uuid), - response: @response.to_json, response_code: status, ip: request.ip, + response: @response.to_json, response_code: response.status, ip: request.ip, api_user_name: current_user.try(:username), api_user_registrar: current_user.try(:registrar).try(:to_s) ) end - - private + # rubocop:enable Metrics/AbcSize def set_domain registrar = current_user.registrar @@ -131,11 +140,6 @@ module Repp render(json: @response, status: :unauthorized) end - - def not_found_error - @response = { code: 2303, message: 'Object does not exist' } - render(json: @response, status: :not_found) - end end end end diff --git a/app/controllers/repp/v1/domains_controller.rb b/app/controllers/repp/v1/domains_controller.rb index 70970b7e1..86d8e9d76 100644 --- a/app/controllers/repp/v1/domains_controller.rb +++ b/app/controllers/repp/v1/domains_controller.rb @@ -3,6 +3,7 @@ module Repp module V1 class DomainsController < BaseController # rubocop:disable Metrics/ClassLength before_action :set_authorized_domain, only: %i[transfer_info destroy] + before_action :validate_registrar_authorization, only: %i[transfer_info destroy] before_action :forward_registrar_id, only: %i[create destroy] before_action :set_domain, only: %i[show update] @@ -182,11 +183,7 @@ module Repp def set_authorized_domain @epp_errors ||= [] - h = {} - h[transfer_info_params[:id].match?(/\A[0-9]+\z/) ? :id : :name] = transfer_info_params[:id] - @domain = Epp::Domain.find_by!(h) - - validate_registrar_authorization + @domain = domain_from_url_hash end def validate_registrar_authorization @@ -197,6 +194,13 @@ module Repp handle_errors end + def domain_from_url_hash + entry = transfer_info_params[:id] + return Domain.find(entry) if entry.match?(/\A[0-9]+\z/) + + Domain.find_by!('name = ? OR name_puny = ?', entry, entry) + end + def limit index_params[:limit] || 200 end diff --git a/app/lib/to_stdout.rb b/app/lib/to_stdout.rb new file mode 100644 index 000000000..eeab82c15 --- /dev/null +++ b/app/lib/to_stdout.rb @@ -0,0 +1,6 @@ +class ToStdout + def self.msg(message) + time = Time.zone.now.utc + STDOUT << "#{time} - #{message}\n" unless Rails.env.test? + end +end diff --git a/app/models/actions/domain_create.rb b/app/models/actions/domain_create.rb index 0c3e19805..c2597cffc 100644 --- a/app/models/actions/domain_create.rb +++ b/app/models/actions/domain_create.rb @@ -68,7 +68,25 @@ module Actions domain.registrar = current_registrar assign_domain_period assign_domain_auth_codes - domain.dnskeys_attributes = params[:dnskeys_attributes] if params[:dnskeys_attributes] + assign_dnskeys + end + + def assign_dnskeys + return unless params[:dnskeys_attributes]&.any? + + params[:dnskeys_attributes].each { |dk| verify_public_key_integrity(dk) } + params.dnskeys_attributes = params[:dnskeys_attributes] + end + + def verify_public_key_integrity(dnssec) + return if dnssec[:public_key].blank? + + value = dnssec[:public_key] + if !value.is_a?(String) || Base64.strict_encode64(Base64.strict_decode64(value)) != value + domain.add_epp_error(2005, nil, nil, %i[dnskeys invalid]) + end + rescue ArgumentError + domain.add_epp_error(2005, nil, nil, %i[dnskeys invalid]) end def assign_domain_auth_codes diff --git a/app/models/actions/domain_update.rb b/app/models/actions/domain_update.rb index 4b4549286..7a9223c81 100644 --- a/app/models/actions/domain_update.rb +++ b/app/models/actions/domain_update.rb @@ -92,18 +92,20 @@ module Actions end def validate_dnskey_integrity(key) - if key[:pubKey] && !Setting.key_data_allowed + if key[:public_key] && !Setting.key_data_allowed domain.add_epp_error('2306', nil, nil, %i[dnskeys key_data_not_allowed]) - elsif key[:digest] && !Setting.ds_data_allowed + elsif key[:ds_digest] && !Setting.ds_data_allowed domain.add_epp_error('2306', nil, nil, %i[dnskeys ds_data_not_allowed]) end + verify_public_key_integrity(key) + @dnskeys << key.except(:action) end def assign_removable_dnskey(key) dnkey = domain.dnskeys.find_by(key.except(:action)) - domain.add_epp_error('2303', nil, nil, %i[dnskeys not_found]) unless dnkey + domain.add_epp_error(2303, nil, nil, %i[dnskeys not_found]) unless dnkey @dnskeys << { id: dnkey.id, _destroy: 1 } if dnkey end @@ -240,5 +242,16 @@ module Actions false end + + def verify_public_key_integrity(dnssec) + return if dnssec[:public_key].blank? + + value = dnssec[:public_key] + if !value.is_a?(String) || Base64.strict_encode64(Base64.strict_decode64(value)) != value + domain.add_epp_error('2005', nil, nil, %i[dnskeys invalid]) + end + rescue ArgumentError + domain.add_epp_error('2005', nil, nil, %i[dnskeys invalid]) + end end end diff --git a/app/models/concerns/domain/releasable.rb b/app/models/concerns/domain/releasable.rb index 4aa5faa58..0a17b062a 100644 --- a/app/models/concerns/domain/releasable.rb +++ b/app/models/concerns/domain/releasable.rb @@ -39,13 +39,15 @@ module Concerns def release if release_to_auction - transaction do - domain_name.sell_at_auction if domain_name.auctionable? - destroy! - registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}", - attached_obj_id: id, - attached_obj_type: self.class) - end + ToStdout.msg 'Destroying domain' + destroy! + ToStdout.msg "Checking if domain_name is auctionable: #{domain_name.auctionable?}" + domain_name.sell_at_auction if domain_name.auctionable? + + ToStdout.msg 'Sending registrar notification' + registrar.notifications.create!(text: "#{I18n.t(:domain_deleted)}: #{name}", + attached_obj_id: id, + attached_obj_type: self.class) else discard end diff --git a/app/models/concerns/domain/transferable.rb b/app/models/concerns/domain/transferable.rb index 9de2fff83..5400e9409 100644 --- a/app/models/concerns/domain/transferable.rb +++ b/app/models/concerns/domain/transferable.rb @@ -59,7 +59,7 @@ module Concerns::Domain::Transferable copied_ids = [] domain_contacts.each do |dc| contact = Contact.find(dc.contact_id) - next if copied_ids.include?(contact.id) || contact.registrar == new_registrar + next if copied_ids.include?(uniq_contact_hash(dc)) || contact.registrar == new_registrar if registrant_id_was == contact.id # registrant was copied previously, do not copy it again oc = OpenStruct.new(id: registrant_id) @@ -72,7 +72,11 @@ module Concerns::Domain::Transferable else dc.update(contact_id: oc.id) end - copied_ids << contact.id + copied_ids << uniq_contact_hash(dc) end end + + def uniq_contact_hash(contact) + Digest::SHA1.hexdigest(contact.contact_id.to_s + contact.type) + end end diff --git a/app/models/contact.rb b/app/models/contact.rb index e30312b4a..7ae51992d 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -360,9 +360,11 @@ class Contact < ApplicationRecord @desc end + # Limits returned objects to 11 def related_domains - a = related_domain_descriptions - a.keys.map { |d| { name: d, id: a[d][:id], roles: a[d][:roles] } } + ids = DomainContact.select(:domain_id).where(contact_id: id).limit(11).map(&:domain_id).uniq + res = Domain.where(id: ids).or(Domain.where(registrant_id: id)).select(:name, :uuid).limit(11) + res.pluck(:name, :uuid).map { |name, id| { name: name, id: id } } end def status_notes_array=(notes) diff --git a/app/models/dns/domain_name.rb b/app/models/dns/domain_name.rb index c1af4d5e7..1e9cd6587 100644 --- a/app/models/dns/domain_name.rb +++ b/app/models/dns/domain_name.rb @@ -36,6 +36,7 @@ module DNS auction = Auction.new auction.domain = name auction.start + ToStdout.msg "Created the auction: #{auction.inspect}" update_whois_from_auction(auction) end @@ -100,7 +101,8 @@ module DNS whois_record = Whois::Record.find_or_create_by!(name: name) do |record| record.json = {} end - + ToStdout.msg "Starting to update WHOIS record #{whois_record.inspect}\n\n"\ + "from auction #{auction.inspect}" whois_record.update_from_auction(auction) end end diff --git a/app/models/domain.rb b/app/models/domain.rb index 88fa94fbc..3acc08575 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -78,7 +78,7 @@ class Domain < ApplicationRecord true end - after_commit :update_whois_record, unless: -> { domain_name.at_auction? } + after_commit :update_whois_record after_create :update_reserved_domains def update_reserved_domains diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb index 0ba8ceec5..cd17ba5dc 100644 --- a/app/models/epp/domain.rb +++ b/app/models/epp/domain.rb @@ -128,6 +128,7 @@ class Epp::Domain < Domain def attach_legal_document(legal_document_data) return unless legal_document_data + return unless legal_document_data[:body] return if legal_document_data[:body].starts_with?(ENV['legal_documents_dir']) legal_documents.create( diff --git a/app/models/whois/record.rb b/app/models/whois/record.rb index 1d827e22a..dc9cc2ba0 100644 --- a/app/models/whois/record.rb +++ b/app/models/whois/record.rb @@ -2,23 +2,34 @@ module Whois class Record < Whois::Server self.table_name = 'whois_records' + def self.without_auctions + ids = Whois::Record.all.select { |record| Auction.where(domain: record.name).blank? } + .pluck(:id) + Whois::Record.where(id: ids) + end + def self.disclaimer Setting.registry_whois_disclaimer end + # rubocop:disable Metrics/AbcSize def update_from_auction(auction) if auction.started? update!(json: { name: auction.domain, status: ['AtAuction'], disclaimer: self.class.disclaimer }) + ToStdout.msg "Updated from auction WHOIS record #{inspect}" elsif auction.no_bids? + ToStdout.msg "Destroying WHOIS record #{inspect}" destroy! elsif auction.awaiting_payment? || auction.payment_received? update!(json: { name: auction.domain, status: ['PendingRegistration'], disclaimer: self.class.disclaimer, registration_deadline: auction.whois_deadline }) + ToStdout.msg "Updated from auction WHOIS record #{inspect}" end end + # rubocop:enable Metrics/AbcSize end end diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb index 3563b9630..19805d583 100644 --- a/app/models/whois_record.rb +++ b/app/models/whois_record.rb @@ -97,7 +97,7 @@ class WhoisRecord < ApplicationRecord end def destroy_whois_record - Whois::Record.where(name: name).delete_all + Whois::Record.without_auctions.where(name: name).delete_all end private diff --git a/config/application.rb b/config/application.rb index a5fb17c9d..014c03269 100644 --- a/config/application.rb +++ b/config/application.rb @@ -36,8 +36,10 @@ module DomainNameRegistry # Autoload all model subdirs config.autoload_paths += Dir[Rails.root.join('app', 'models', '**/')] + config.autoload_paths += Dir[Rails.root.join('app', 'lib', '**/')] config.autoload_paths += Dir[Rails.root.join('app', 'interactions', '**/')] config.eager_load_paths << config.root.join('lib', 'validators') + config.eager_load_paths << config.root.join('app', 'lib') config.watchable_dirs['lib'] = %i[rb] config.active_record.schema_format = :sql diff --git a/lib/gem_monkey_patches/i18n.rb b/lib/gem_monkey_patches/i18n.rb index 2f7fceff7..7d0613247 100644 --- a/lib/gem_monkey_patches/i18n.rb +++ b/lib/gem_monkey_patches/i18n.rb @@ -5,6 +5,7 @@ module I18n alias_method :original_localize, :localize def localize(object, options = {}) + options.merge!({ default: '-' }) object.present? ? original_localize(object, options) : '' end end diff --git a/test/integration/api/registrant/registrant_api_contacts_test.rb b/test/integration/api/registrant/registrant_api_contacts_test.rb index 191222764..f3998a2e9 100644 --- a/test/integration/api/registrant/registrant_api_contacts_test.rb +++ b/test/integration/api/registrant/registrant_api_contacts_test.rb @@ -57,6 +57,15 @@ class RegistrantApiContactsTest < ApplicationIntegrationTest assert_equal({ errors: [base: ['Not authorized']] }, json_body) end + def test_gets_contact_domain_links_when_requested + get "/api/v1/registrant/contacts/#{@contact.uuid}?links=true", headers: @auth_headers + + expected_links = @contact.domains.uniq.map { |d| { name: d.name, id: d.uuid }} + assert_response :ok + response_json = JSON.parse(response.body, symbolize_names: true) + + assert_empty expected_links - response_json[:links] + end private def auth_token diff --git a/test/integration/epp/domain/create/base_test.rb b/test/integration/epp/domain/create/base_test.rb index 9d817524d..e3b7a39ee 100644 --- a/test/integration/epp/domain/create/base_test.rb +++ b/test/integration/epp/domain/create/base_test.rb @@ -2,6 +2,51 @@ require 'test_helper' class EppDomainCreateBaseTest < EppTestCase + def test_illegal_chars_in_dns_key + name = "new.#{dns_zones(:one).origin}" + contact = contacts(:john) + registrant = contact.becomes(Registrant) + + pub_key = "AwEAAddt2AkLf\n + \n + YGKgiEZB5SmIF8E\n + vrjxNMH6HtxW\rEA4RJ9Ao6LCWheg8" + + request_xml = <<-XML + + + + + + #{name} + #{registrant.code} + + + + + + 257 + 3 + 8 + #{pub_key} + + + + #{'test' * 2000} + + + + + XML + assert_no_difference 'Domain.count' do + post epp_create_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + + assert_epp_response :parameter_value_syntax_error + end + + def test_not_registers_domain_without_legaldoc now = Time.zone.parse('2010-07-05') travel_to now diff --git a/test/integration/epp/domain/transfer/request_test.rb b/test/integration/epp/domain/transfer/request_test.rb index 1c3614421..273a9f490 100644 --- a/test/integration/epp/domain/transfer/request_test.rb +++ b/test/integration/epp/domain/transfer/request_test.rb @@ -3,6 +3,7 @@ require 'test_helper' class EppDomainTransferRequestTest < EppTestCase def setup @domain = domains(:shop) + @contact = contacts(:jane) @new_registrar = registrars(:goodnames) @original_transfer_wait_time = Setting.transfer_wait_time Setting.transfer_wait_time = 0 @@ -12,6 +13,95 @@ class EppDomainTransferRequestTest < EppTestCase Setting.transfer_wait_time = @original_transfer_wait_time end + def test_transfer_domain_with_contacts_if_registrant_and_tech_are_shared + @domain.tech_domain_contacts[0].update!(contact_id: @domain.registrant.id) + + @domain.tech_domain_contacts[1].delete + @domain.reload + + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } + + assert_epp_response :completed_successfully + + @domain.reload + + tech = Contact.find_by(id: @domain.tech_domain_contacts[0].contact_id) + + assert_equal @domain.contacts.where(original_id: @domain.registrant.original_id).count, 1 + assert_equal tech.registrar_id, @domain.registrar.id + end + + def test_transfer_domain_with_contacts_if_registrant_and_admin_are_shared + @domain.admin_domain_contacts[0].update!(contact_id: @domain.registrant.id) + @domain.tech_domain_contacts[0].update!(contact_id: @contact.id) + + @domain.tech_domain_contacts[1].delete + @domain.reload + + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } + + assert_epp_response :completed_successfully + + @domain.reload + + admin = Contact.find_by(id: @domain.admin_domain_contacts[0].contact_id) + + assert_equal @domain.contacts.where(original_id: @domain.registrant.original_id).count, 1 + assert_equal admin.registrar_id, @domain.registrar.id + end + + def test_transfer_domain_with_contacts_if_admin_and_tech_are_shared + @domain.admin_domain_contacts[0].update!(contact_id: @contact.id) + @domain.tech_domain_contacts[0].update!(contact_id: @contact.id) + + @domain.tech_domain_contacts[1].delete + @domain.reload + + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } + + assert_epp_response :completed_successfully + + @domain.reload + + admin = Contact.find_by(id: @domain.admin_domain_contacts[0].contact_id) + tech = Contact.find_by(id: @domain.tech_domain_contacts[0].contact_id) + + result_hash = @domain.contacts.pluck(:original_id).group_by(&:itself).transform_values(&:count) + assert result_hash[admin.original_id], 2 + + assert_equal admin.registrar_id, @domain.registrar.id + assert_equal tech.registrar_id, @domain.registrar.id + end + + def test_transfer_domain_with_contacts_if_admin_and_tech_and_registrant_are_shared + @domain.tech_domain_contacts[0].update!(contact_id: @domain.registrant.id) + @domain.admin_domain_contacts[0].update!(contact_id: @domain.registrant.id) + + @domain.tech_domain_contacts[1].delete + @domain.reload + + post epp_transfer_path, params: { frame: request_xml }, + headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } + + assert_epp_response :completed_successfully + + @domain.reload + + admin = Contact.find_by(id: @domain.admin_domain_contacts[0].contact_id) + tech = Contact.find_by(id: @domain.tech_domain_contacts[0].contact_id) + + assert_equal @domain.contacts.where(original_id: @domain.registrant.original_id).count, 2 + + result_hash = @domain.contacts.pluck(:original_id).group_by(&:itself).transform_values(&:count) + assert result_hash[@domain.registrant.original_id], 2 + + assert_equal admin.registrar_id, @domain.registrar.id + assert_equal tech.registrar_id, @domain.registrar.id + end + def test_transfers_domain_at_once post epp_transfer_path, params: { frame: request_xml }, headers: { 'HTTP_COOKIE' => 'session=api_goodnames' } diff --git a/test/integration/repp/v1/domains/transfer_info_test.rb b/test/integration/repp/v1/domains/transfer_info_test.rb index 5bbfca1a6..a3b8fe874 100644 --- a/test/integration/repp/v1/domains/transfer_info_test.rb +++ b/test/integration/repp/v1/domains/transfer_info_test.rb @@ -38,4 +38,17 @@ class ReppV1DomainsTransferInfoTest < ActionDispatch::IntegrationTest assert_equal 'Authorization error', json[:message] assert_empty json[:data] end + + def test_processes_puny_domains + @domain.update(name_puny: 'xn--prototp-s2aa.ee') + + headers = @auth_headers + headers['Auth-Code'] = @domain.transfer_code + + get "/repp/v1/domains/xn--prototp-s2aa.ee/transfer_info", headers: headers + json = JSON.parse(response.body, symbolize_names: true) + + assert_response :ok + assert_equal 1000, json[:code] + end end diff --git a/test/models/domain/releasable/auctionable_test.rb b/test/models/domain/releasable/auctionable_test.rb index de3ac0ff6..d24f46913 100644 --- a/test/models/domain/releasable/auctionable_test.rb +++ b/test/models/domain/releasable/auctionable_test.rb @@ -25,6 +25,7 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase def test_skips_auction_when_domains_is_blocked assert_equal 'shop.test', @domain.name blocked_domains(:one).update!(name: 'shop.test') + @domain.save!(validate: false) @domain.release @@ -34,6 +35,7 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase def test_skips_auction_when_domains_is_reserved assert_equal 'shop.test', @domain.name reserved_domains(:one).update!(name: 'shop.test') + @domain.save!(validate: false) @domain.release @@ -58,6 +60,24 @@ class DomainReleasableAuctionableTest < ActiveSupport::TestCase end end + def test_updates_whois_server + @domain.update!(delete_date: '2010-07-04') + travel_to Time.zone.parse('2010-07-05') + old_whois = @domain.whois_record + + Domain.release_domains + + assert_raises ActiveRecord::RecordNotFound do + old_whois.reload + end + + whois_record = Whois::Record.find_by(name: @domain.name) + json = { "name"=>@domain.name, + "status"=>["AtAuction"], + "disclaimer"=> Setting.registry_whois_disclaimer } + assert_equal whois_record.json, json + end + def test_notifies_registrar @domain.update!(delete_date: '2010-07-04') travel_to Time.zone.parse('2010-07-05') diff --git a/test/system/admin_area/prices_test.rb b/test/system/admin_area/prices_test.rb index dbb91966a..f5a299c38 100644 --- a/test/system/admin_area/prices_test.rb +++ b/test/system/admin_area/prices_test.rb @@ -20,6 +20,7 @@ class AdminAreaPricesTest < ApplicationSystemTestCase fill_in 'Valid from', with: effective_date click_on 'Create price' + assert_text 'Price has been created' assert_text I18n.localize(effective_date) end diff --git a/test/system/registrar_area/account_activities_test.rb b/test/system/registrar_area/account_activities_test.rb new file mode 100644 index 000000000..1944dc2fb --- /dev/null +++ b/test/system/registrar_area/account_activities_test.rb @@ -0,0 +1,28 @@ +require 'application_system_test_case' + +class RegistrarAccountActivitiesTest < ApplicationSystemTestCase + setup do + @registrar = registrars(:bestnames) + sign_in users(:api_bestnames) + end + + def test_show_account_activity_page + account_activities(:one).update(sum: "123.00") + visit registrar_account_activities_path + assert_text 'Account activity' + end + + def test_download_account_activity + now = Time.zone.parse('2010-07-05 08:00') + travel_to now + account_activities(:one).update(sum: "123.00") + + get registrar_account_activities_path(format: :csv) + + assert_response :ok + assert_equal "text/csv", response.headers['Content-Type'] + assert_equal %(attachment; filename="account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv"; filename*=UTF-8''account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv), + response.headers['Content-Disposition'] + assert_not_empty response.body + end +end \ No newline at end of file