diff --git a/app/controllers/epp/base_controller.rb b/app/controllers/epp/base_controller.rb
index 12efbd1d3..a481a8f9a 100644
--- a/app/controllers/epp/base_controller.rb
+++ b/app/controllers/epp/base_controller.rb
@@ -20,13 +20,23 @@ module Epp
rescue_from StandardError, with: :respond_with_command_failed_error
rescue_from AuthorizationError, with: :respond_with_authorization_error
+ rescue_from Shunter::ThrottleError, with: :respond_with_session_limit_exceeded_error
rescue_from ActiveRecord::RecordNotFound, with: :respond_with_object_does_not_exist_error
+
before_action :set_paper_trail_whodunnit
skip_before_action :validate_against_schema
protected
+ def respond_with_session_limit_exceeded_error(exception)
+ epp_errors.add(:epp_errors,
+ code: '2502',
+ msg: Shunter.default_error_message)
+ handle_errors
+ log_exception(exception)
+ end
+
def respond_with_command_failed_error(exception)
epp_errors.add(:epp_errors,
code: '2400',
@@ -51,6 +61,11 @@ module Epp
private
+ def throttled_user
+ authorize!(:throttled_user, @domain) unless current_user || instance_of?(Epp::SessionsController)
+ current_user
+ end
+
def wrap_exceptions
yield
rescue CanCan::AccessDenied
diff --git a/app/controllers/epp/contacts_controller.rb b/app/controllers/epp/contacts_controller.rb
index 10250563c..db96a186d 100644
--- a/app/controllers/epp/contacts_controller.rb
+++ b/app/controllers/epp/contacts_controller.rb
@@ -5,6 +5,9 @@ module Epp
before_action :find_contact, only: [:info, :update, :delete]
before_action :find_password, only: [:info, :update, :delete]
+ THROTTLED_ACTIONS = %i[info check create renew update transfer delete].freeze
+ include Shunter::Integration::Throttle
+
def info
authorize! :info, @contact, @password
render_epp_response 'epp/contacts/info'
diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb
index d2e146c0a..abf360c55 100644
--- a/app/controllers/epp/domains_controller.rb
+++ b/app/controllers/epp/domains_controller.rb
@@ -6,6 +6,9 @@ module Epp
before_action :set_paper_trail_whodunnit
before_action :parse_schemas_prefix_and_version
+ THROTTLED_ACTIONS = %i[info create check renew update transfer delete].freeze
+ include Shunter::Integration::Throttle
+
def info
authorize! :info, @domain
diff --git a/app/controllers/epp/polls_controller.rb b/app/controllers/epp/polls_controller.rb
index a674bcd45..7fe6d2636 100644
--- a/app/controllers/epp/polls_controller.rb
+++ b/app/controllers/epp/polls_controller.rb
@@ -1,5 +1,8 @@
module Epp
class PollsController < BaseController
+ THROTTLED_ACTIONS = %i[poll].freeze
+ include Shunter::Integration::Throttle
+
def poll
authorize! :manage, :poll
req_poll if params[:parsed_frame].css('poll').first['op'] == 'req'
diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb
index 8d8b56e62..0667c9adc 100644
--- a/app/controllers/epp/sessions_controller.rb
+++ b/app/controllers/epp/sessions_controller.rb
@@ -3,6 +3,9 @@ module Epp
skip_authorization_check only: [:hello, :login, :logout]
before_action :set_paper_trail_whodunnit
+ THROTTLED_ACTIONS = %i[login hello].freeze
+ include Shunter::Integration::Throttle
+
def hello
render_epp_response('greeting')
end
diff --git a/app/controllers/repp/v1/accounts_controller.rb b/app/controllers/repp/v1/accounts_controller.rb
index 8395db42c..a405646ca 100644
--- a/app/controllers/repp/v1/accounts_controller.rb
+++ b/app/controllers/repp/v1/accounts_controller.rb
@@ -3,6 +3,11 @@ module Repp
class AccountsController < BaseController # rubocop:disable Metrics/ClassLength
load_and_authorize_resource
+ THROTTLED_ACTIONS = %i[
+ index balance details update_auto_reload_balance disable_auto_reload_balance switch_user update
+ ].freeze
+ include Shunter::Integration::Throttle
+
api :get, '/repp/v1/accounts'
desc 'Get all activities'
def index
diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb
index d84c8e37b..903c9e58b 100644
--- a/app/controllers/repp/v1/base_controller.rb
+++ b/app/controllers/repp/v1/base_controller.rb
@@ -27,6 +27,10 @@ module Repp
@response = { code: 2201, message: 'Authorization error' }
logger.error e.to_s
render(json: @response, status: :unauthorized)
+ rescue Shunter::ThrottleError => e
+ @response = { code: 2502, message: Shunter.default_error_message }
+ logger.error e.to_s
+ render(json: @response, status: :bad_request)
ensure
create_repp_log
end
@@ -167,6 +171,11 @@ module Repp
data[:abilities] = Ability.new(current_user).permissions
data
end
+
+ def throttled_user
+ authorize!(:throttled_user, @domain) unless current_user || action_name == 'tara_callback'
+ current_user
+ end
end
end
end
diff --git a/app/controllers/repp/v1/contacts_controller.rb b/app/controllers/repp/v1/contacts_controller.rb
index 5d8f20ee0..510525ac5 100644
--- a/app/controllers/repp/v1/contacts_controller.rb
+++ b/app/controllers/repp/v1/contacts_controller.rb
@@ -5,6 +5,9 @@ module Repp
before_action :find_contact, only: %i[show update destroy]
skip_around_action :log_request, only: :search
+ THROTTLED_ACTIONS = %i[index check search create show update destroy].freeze
+ include Shunter::Integration::Throttle
+
api :get, '/repp/v1/contacts'
desc 'Get all existing contacts'
def index
diff --git a/app/controllers/repp/v1/domains/admin_contacts_controller.rb b/app/controllers/repp/v1/domains/admin_contacts_controller.rb
index 5db865199..ce06296f5 100644
--- a/app/controllers/repp/v1/domains/admin_contacts_controller.rb
+++ b/app/controllers/repp/v1/domains/admin_contacts_controller.rb
@@ -2,6 +2,9 @@ module Repp
module V1
module Domains
class AdminContactsController < BaseContactsController
+ THROTTLED_ACTIONS = %i[update].freeze
+ include Shunter::Integration::Throttle
+
def update
super
diff --git a/app/controllers/repp/v1/domains/contacts_controller.rb b/app/controllers/repp/v1/domains/contacts_controller.rb
index b41b3a378..a90a2d27a 100644
--- a/app/controllers/repp/v1/domains/contacts_controller.rb
+++ b/app/controllers/repp/v1/domains/contacts_controller.rb
@@ -4,6 +4,9 @@ module Repp
class ContactsController < BaseContactsController
before_action :set_domain, only: %i[index create destroy]
+ THROTTLED_ACTIONS = %i[index create destroy update].freeze
+ include Shunter::Integration::Throttle
+
def_param_group :contacts_apidoc do
param :contacts, Array, required: true, desc: 'Array of new linked contacts' do
param :code, String, required: true, desc: 'Contact code'
diff --git a/app/controllers/repp/v1/domains/dnssec_controller.rb b/app/controllers/repp/v1/domains/dnssec_controller.rb
index fcfaa991a..0acf2e6e9 100644
--- a/app/controllers/repp/v1/domains/dnssec_controller.rb
+++ b/app/controllers/repp/v1/domains/dnssec_controller.rb
@@ -4,6 +4,9 @@ module Repp
class DnssecController < BaseController
before_action :set_domain, only: %i[index create destroy]
+ THROTTLED_ACTIONS = %i[index create destroy].freeze
+ include Shunter::Integration::Throttle
+
def_param_group :dns_keys_apidoc do
param :flags, String, required: true, desc: '256 (KSK) or 257 (ZSK)'
param :protocol, String, required: true, desc: 'Key protocol (3)'
diff --git a/app/controllers/repp/v1/domains/nameservers_controller.rb b/app/controllers/repp/v1/domains/nameservers_controller.rb
index 6f76f9e99..8ee1cba35 100644
--- a/app/controllers/repp/v1/domains/nameservers_controller.rb
+++ b/app/controllers/repp/v1/domains/nameservers_controller.rb
@@ -5,6 +5,9 @@ module Repp
before_action :set_domain, only: %i[index create destroy]
before_action :set_nameserver, only: %i[destroy]
+ THROTTLED_ACTIONS = %i[index create destroy].freeze
+ include Shunter::Integration::Throttle
+
api :GET, '/repp/v1/domains/:domain_name/nameservers'
desc "Get domain's nameservers"
def index
diff --git a/app/controllers/repp/v1/domains/renews_controller.rb b/app/controllers/repp/v1/domains/renews_controller.rb
index b47710c7e..c91130119 100644
--- a/app/controllers/repp/v1/domains/renews_controller.rb
+++ b/app/controllers/repp/v1/domains/renews_controller.rb
@@ -6,6 +6,9 @@ module Repp
before_action :select_renewable_domains, only: [:bulk_renew]
before_action :set_domain, only: [:create]
+ THROTTLED_ACTIONS = %i[create bulk_renew].freeze
+ include Shunter::Integration::Throttle
+
api :POST, 'repp/v1/domains/:domain_name/renew'
desc 'Renew domain'
param :renews, Hash, required: true, desc: 'Renew parameters' do
diff --git a/app/controllers/repp/v1/domains/statuses_controller.rb b/app/controllers/repp/v1/domains/statuses_controller.rb
index d46725c46..b07ce3956 100644
--- a/app/controllers/repp/v1/domains/statuses_controller.rb
+++ b/app/controllers/repp/v1/domains/statuses_controller.rb
@@ -5,6 +5,9 @@ module Repp
before_action :set_domain, only: %i[update destroy]
before_action :verify_status
+ THROTTLED_ACTIONS = %i[update destroy].freeze
+ include Shunter::Integration::Throttle
+
api :DELETE, '/repp/v1/domains/:domain_name/statuses/:status'
param :domain_name, String, desc: 'Domain name'
desc 'Remove status from specific domain'
diff --git a/app/controllers/repp/v1/domains/transfers_controller.rb b/app/controllers/repp/v1/domains/transfers_controller.rb
index e9474d94d..69e685571 100644
--- a/app/controllers/repp/v1/domains/transfers_controller.rb
+++ b/app/controllers/repp/v1/domains/transfers_controller.rb
@@ -4,6 +4,9 @@ module Repp
class TransfersController < BaseController
before_action :set_domain, only: [:create]
+ THROTTLED_ACTIONS = %i[create].freeze
+ include Shunter::Integration::Throttle
+
api :POST, 'repp/v1/domains/:domain_name/transfer'
desc 'Transfer a specific domain'
param :transfer, Hash, required: true, desc: 'Renew parameters' do
diff --git a/app/controllers/repp/v1/domains_controller.rb b/app/controllers/repp/v1/domains_controller.rb
index 6990b0a86..c72c83882 100644
--- a/app/controllers/repp/v1/domains_controller.rb
+++ b/app/controllers/repp/v1/domains_controller.rb
@@ -8,6 +8,9 @@ module Repp
before_action :forward_registrar_id, only: %i[create update destroy]
before_action :set_domain, only: %i[update]
+ THROTTLED_ACTIONS = %i[transfer_info transfer index create show update destroy].freeze
+ include Shunter::Integration::Throttle
+
api :GET, '/repp/v1/domains'
desc 'Get all existing domains'
def index
diff --git a/app/controllers/repp/v1/invoices_controller.rb b/app/controllers/repp/v1/invoices_controller.rb
index 2d4340b3e..fe2c1c50a 100644
--- a/app/controllers/repp/v1/invoices_controller.rb
+++ b/app/controllers/repp/v1/invoices_controller.rb
@@ -4,6 +4,9 @@ module Repp
class InvoicesController < BaseController # rubocop:disable Metrics/ClassLength
load_and_authorize_resource
+ THROTTLED_ACTIONS = %i[download add_credit send_to_recipient cancel index show].freeze
+ include Shunter::Integration::Throttle
+
# rubocop:disable Metrics/MethodLength
api :get, '/repp/v1/invoices'
desc 'Get all invoices'
diff --git a/app/controllers/repp/v1/registrar/accreditation_info_controller.rb b/app/controllers/repp/v1/registrar/accreditation_info_controller.rb
index c55a561d2..dfb1fc3b0 100644
--- a/app/controllers/repp/v1/registrar/accreditation_info_controller.rb
+++ b/app/controllers/repp/v1/registrar/accreditation_info_controller.rb
@@ -3,8 +3,11 @@ module Repp
module Registrar
class AccreditationInfoController < BaseController
if Feature.allow_accr_endspoints?
- api :GET, 'repp/v1/registrar/accreditation/get_info'
- desc 'check login user and return data'
+ THROTTLED_ACTIONS = %i[index].freeze
+ include Shunter::Integration::Throttle
+
+ api :GET, 'repp/v1/registrar/accreditation/get_info'
+ desc 'check login user and return data'
def index
login = current_user
diff --git a/app/controllers/repp/v1/registrar/auth_controller.rb b/app/controllers/repp/v1/registrar/auth_controller.rb
index 46c21459e..5da1b3a38 100644
--- a/app/controllers/repp/v1/registrar/auth_controller.rb
+++ b/app/controllers/repp/v1/registrar/auth_controller.rb
@@ -6,6 +6,9 @@ module Repp
skip_before_action :check_ip_restriction, only: :tara_callback
skip_before_action :validate_client_certs, only: :tara_callback
+ THROTTLED_ACTIONS = %i[index tara_callback].freeze
+ include Shunter::Integration::Throttle
+
api :GET, 'repp/v1/registrar/auth'
desc 'check user auth info and return data'
def index
diff --git a/app/controllers/repp/v1/registrar/nameservers_controller.rb b/app/controllers/repp/v1/registrar/nameservers_controller.rb
index b3c6d8412..1014ddc0d 100644
--- a/app/controllers/repp/v1/registrar/nameservers_controller.rb
+++ b/app/controllers/repp/v1/registrar/nameservers_controller.rb
@@ -4,6 +4,9 @@ module Repp
class NameserversController < BaseController
before_action :verify_nameserver_existance, only: %i[update]
+ THROTTLED_ACTIONS = %i[put].freeze
+ include Shunter::Integration::Throttle
+
api :PUT, 'repp/v1/registrar/nameservers'
desc 'bulk nameserver change'
param :data, Hash, required: true, desc: 'Object holding nameserver changes' do
diff --git a/app/controllers/repp/v1/registrar/notifications_controller.rb b/app/controllers/repp/v1/registrar/notifications_controller.rb
index 6b1d342cc..eb3d158ad 100644
--- a/app/controllers/repp/v1/registrar/notifications_controller.rb
+++ b/app/controllers/repp/v1/registrar/notifications_controller.rb
@@ -4,6 +4,9 @@ module Repp
class NotificationsController < BaseController
before_action :set_notification, only: %i[update show]
+ THROTTLED_ACTIONS = %i[all_notifications index show update].freeze
+ include Shunter::Integration::Throttle
+
api :GET, '/repp/v1/registrar/notifications'
desc 'Get the latest unread poll message'
def index
diff --git a/app/controllers/repp/v1/registrar/summary_controller.rb b/app/controllers/repp/v1/registrar/summary_controller.rb
index a0e266e93..eaa3b0f57 100644
--- a/app/controllers/repp/v1/registrar/summary_controller.rb
+++ b/app/controllers/repp/v1/registrar/summary_controller.rb
@@ -2,6 +2,9 @@ module Repp
module V1
module Registrar
class SummaryController < BaseController
+ THROTTLED_ACTIONS = %i[index].freeze
+ include Shunter::Integration::Throttle
+
api :GET, 'repp/v1/registrar/summary'
desc 'check user summary info and return data'
diff --git a/app/lib/shunter.rb b/app/lib/shunter.rb
new file mode 100644
index 000000000..b06de6b9f
--- /dev/null
+++ b/app/lib/shunter.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Shunter
+ module_function
+
+ class ThrottleError < StandardError; end
+
+ BASE_LOGGER = ::Logger.new($stdout)
+ ONE_MINUTE = 60
+ ONE_HUNDRED_REQUESTS = 100
+
+ BASE_CONNECTION = {
+ host: ENV['shunter_redis_host'] || 'redis',
+ port: (ENV['shunter_redis_port'] || '6379').to_i,
+ }.freeze
+
+ def default_error_message
+ "Session limit exceeded. Current limit is #{default_threshold} in #{default_timespan} seconds"
+ end
+
+ def default_timespan
+ ENV['shunter_default_timespan'] || ONE_MINUTE
+ end
+
+ def default_threshold
+ ENV['shunter_default_threshold'] || ONE_HUNDRED_REQUESTS
+ end
+
+ def default_adapter
+ ENV['shunter_default_adapter'] || 'Shunter::Adapters::Redis'
+ end
+
+ def feature_enabled?
+ ActiveModel::Type::Boolean.new.cast(ENV['shunter_enabled'] || 'false')
+ end
+end
diff --git a/app/lib/shunter/adapters/memory.rb b/app/lib/shunter/adapters/memory.rb
new file mode 100644
index 000000000..eb0b25b27
--- /dev/null
+++ b/app/lib/shunter/adapters/memory.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Shunter
+ module Adapters
+ class Memory
+ attr_reader :store
+
+ def initialize(_options = {})
+ @@store ||= {}
+ end
+
+ def find_counter(key)
+ @@store[key]
+ end
+
+ def write_counter(key)
+ @@store[key] = 1
+ end
+
+ def increment_counter(key)
+ @@store[key] += 1
+ end
+
+ def clear!
+ @@store = {}
+ end
+
+ def expire_counter(_key, _timespan); end
+ end
+ end
+end
diff --git a/app/lib/shunter/adapters/redis.rb b/app/lib/shunter/adapters/redis.rb
new file mode 100644
index 000000000..adf27b359
--- /dev/null
+++ b/app/lib/shunter/adapters/redis.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Shunter
+ module Adapters
+ class Redis
+ attr_reader :redis
+
+ def initialize(options)
+ @redis = ::Redis.new(options)
+ end
+
+ def find_counter(key)
+ @redis.get(key)
+ end
+
+ def write_counter(key)
+ @redis.set(key, 1)
+ end
+
+ def increment_counter(key)
+ @redis.incr(key)
+ end
+
+ def expire_counter(key, timespan)
+ @redis.expire(key, timespan)
+ end
+ end
+ end
+end
diff --git a/app/lib/shunter/base.rb b/app/lib/shunter/base.rb
new file mode 100644
index 000000000..f3f6867f0
--- /dev/null
+++ b/app/lib/shunter/base.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module Shunter
+ class Base
+ attr_accessor :user_id, :adapter
+
+ def initialize(options = {})
+ @user_id = options[:user_id]
+ adapter_klass = Shunter.default_adapter.constantize
+ @adapter = adapter_klass.new(options[:conn_options])
+ end
+
+ def user_key
+ "counting_#{@user_id}"
+ end
+
+ def blocked_user_key
+ "blocked_#{@user_id}"
+ end
+
+ def throttle
+ return false if blocked?
+
+ valid_counter?
+ end
+
+ def blocked?
+ adapter.find_counter(blocked_user_key).present?
+ end
+
+ def valid_counter?
+ if adapter.find_counter(user_key)
+ number_of_requests = adapter.increment_counter(user_key)
+ if number_of_requests > allowed_requests.to_i
+ init_counter(blocked_user_key)
+ return false
+ end
+ else
+ init_counter(user_key)
+ end
+ true
+ end
+
+ private
+
+ def init_counter(key)
+ adapter.write_counter(key)
+ adapter.expire_counter(key, timespan)
+ end
+
+ def allowed_requests
+ Shunter.default_threshold
+ end
+
+ def timespan
+ Shunter.default_timespan
+ end
+
+ def logger
+ Shunter::BASE_LOGGER
+ end
+ end
+end
diff --git a/app/lib/shunter/integration/throttle.rb b/app/lib/shunter/integration/throttle.rb
new file mode 100644
index 000000000..91fb033ac
--- /dev/null
+++ b/app/lib/shunter/integration/throttle.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'active_support/concern'
+
+module Shunter
+ module Integration
+ module Throttle
+ extend ActiveSupport::Concern
+
+ included do |base|
+ actions = base.const_defined?('THROTTLED_ACTIONS') && base.const_get('THROTTLED_ACTIONS')
+ return if actions.blank?
+
+ around_action :throttle, only: actions
+
+ def throttle
+ if throttled_user.blank? || !Shunter.feature_enabled?
+ yield if block_given?
+ return
+ end
+
+ user_id = throttled_user.id
+
+ shunter = Shunter::Base.new(conn_options: connection_options, user_id: user_id)
+ if shunter.throttle
+ logger.info "Request from #{throttled_user.class}/#{throttled_user.id} is coming through throttling"
+ yield if block_given?
+ else
+ logger.info "Too many requests from #{throttled_user.class}/#{throttled_user.id}."
+ raise Shunter::ThrottleError
+ end
+ end
+ end
+
+ def connection_options
+ Shunter::BASE_CONNECTION
+ end
+
+ def logger
+ Shunter::BASE_LOGGER
+ end
+ end
+ end
+end
diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb
index c6589b63d..bb2bc84a1 100644
--- a/app/models/epp/domain.rb
+++ b/app/models/epp/domain.rb
@@ -105,6 +105,9 @@ class Epp::Domain < Domain
max: Setting.ns_max_count
}
],
+ '2502' => [ # Rate limit exceeded
+ %i[base session_limit_exceeded],
+ ],
]
}
end
diff --git a/app/models/epp/response/result/code.rb b/app/models/epp/response/result/code.rb
index f2b1ccd3b..916683840 100644
--- a/app/models/epp/response/result/code.rb
+++ b/app/models/epp/response/result/code.rb
@@ -62,7 +62,7 @@ module Epp
2308 => 'Data management policy violation',
2400 => 'Command failed',
2501 => 'Authentication error; server closing connection',
- 2502 => 'Session limit exceeded; server closing connection',
+ 2502 => Shunter.default_error_message,
}.freeze
private_constant :DEFAULT_DESCRIPTIONS
diff --git a/config/application.yml.sample b/config/application.yml.sample
index 559ce2e9b..dffeea5be 100644
--- a/config/application.yml.sample
+++ b/config/application.yml.sample
@@ -197,6 +197,10 @@ test:
cdns_scanner_output_file: 'test/fixtures/files/cdns_output.txt'
dnssec_resolver_ips: 8.8.8.8, 8.8.4.4
legal_documents_dir: 'test/fixtures/files'
+ shunter_default_adapter: "Shunter::Adapters::Memory"
+ shunter_enabled: "false"
+ shunter_redis_host: "redis"
+ shunter_redis_port: "6379"
openssl_config_path: 'test/fixtures/files/test_ca/openssl.cnf'
crl_dir: 'test/fixtures/files/test_ca/crl'
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 028c61b47..6e680b9c0 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -41,4 +41,6 @@ Rails.application.configure do
# If set to :null_store, Setting.x returns nil after first spec runs (database is emptied)
config.cache_store = :memory_store
+
+ config.log_level = :fatal
end
diff --git a/test/integration/api/domain_admin_contacts_test.rb b/test/integration/api/domain_admin_contacts_test.rb
index 6aa412c23..8064483bc 100644
--- a/test/integration/api/domain_admin_contacts_test.rb
+++ b/test/integration/api/domain_admin_contacts_test.rb
@@ -10,6 +10,8 @@ class APIDomainAdminContactsTest < ApplicationIntegrationTest
@admin_new.update(ident: @admin_current.ident,
ident_type: @admin_current.ident_type,
ident_country_code: @admin_current.ident_country_code)
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_replace_all_admin_contacts_when_ident_data_doesnt_match
@@ -148,6 +150,27 @@ class APIDomainAdminContactsTest < ApplicationIntegrationTest
JSON.parse(response.body, symbolize_names: true)
end
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ domain = domains(:airport)
+ domain.admin_contacts = [@admin_current]
+ patch '/repp/v1/domains/admin_contacts', params: { current_contact_id: @admin_current.code,
+ new_contact_id: @admin_new.code },
+ headers: { 'HTTP_AUTHORIZATION' => http_auth_key }
+ patch '/repp/v1/domains/admin_contacts', params: { current_contact_id: @admin_current.code,
+ new_contact_id: @admin_new.code },
+ headers: { 'HTTP_AUTHORIZATION' => http_auth_key }
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
private
def http_auth_key
diff --git a/test/integration/epp/contact/check/base_test.rb b/test/integration/epp/contact/check/base_test.rb
index 6ad027fc6..367436fc5 100644
--- a/test/integration/epp/contact/check/base_test.rb
+++ b/test/integration/epp/contact/check/base_test.rb
@@ -3,6 +3,9 @@ require 'test_helper'
class EppContactCheckBaseTest < EppTestCase
setup do
@contact = contacts(:john)
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_valid_response
@@ -157,6 +160,59 @@ class EppContactCheckBaseTest < EppTestCase
# assert_equal 'in use', response_xml.at_xpath('//contact:reason', contact: xml_schema).text
end
+ def test_returns_valid_response_if_not_throttled
+ request_xml = <<-XML
+
+
+
+
+
+ john-001
+
+
+
+
+ XML
+
+ post epp_check_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ request_xml = <<-XML
+
+
+
+
+
+ john-001
+
+
+
+
+ XML
+
+ post epp_check_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_check_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
private
def xml_schema
diff --git a/test/integration/epp/contact/create/base_test.rb b/test/integration/epp/contact/create/base_test.rb
index ba94fcd6f..1f16d531f 100644
--- a/test/integration/epp/contact/create/base_test.rb
+++ b/test/integration/epp/contact/create/base_test.rb
@@ -1,6 +1,11 @@
require 'test_helper'
class EppContactCreateBaseTest < EppTestCase
+ setup do
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
+ end
+
def test_creates_new_contact_with_required_attributes
name = 'new'
email = 'new@registrar.test'
@@ -362,4 +367,82 @@ class EppContactCreateBaseTest < EppTestCase
assert_equal country_code, contact.country_code
assert_equal state, contact.state
end
+
+ def test_returns_valid_response_if_not_throttled
+ name = 'new'
+ email = 'new@registrar.test'
+ phone = '+1.2'
+
+ request_xml = <<-XML
+
+
+
+
+
+
+ #{name}
+
+ #{phone}
+ #{email}
+
+
+
+
+ any
+
+
+
+
+ XML
+
+ post epp_create_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+ name = 'new'
+ email = 'new@registrar.test'
+ phone = '+1.2'
+
+ request_xml = <<-XML
+
+
+
+
+
+
+ #{name}
+
+ #{phone}
+ #{email}
+
+
+
+
+ any
+
+
+
+
+ XML
+
+ post epp_create_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_create_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/epp/contact/info/base_test.rb b/test/integration/epp/contact/info/base_test.rb
index dc8fcd5f7..09d0b0308 100644
--- a/test/integration/epp/contact/info/base_test.rb
+++ b/test/integration/epp/contact/info/base_test.rb
@@ -3,6 +3,9 @@ require 'test_helper'
class EppContactInfoBaseTest < EppTestCase
setup do
@contact = contacts(:john)
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_valid_response
@@ -129,6 +132,62 @@ class EppContactInfoBaseTest < EppTestCase
assert_equal 'No access', response_xml.at_xpath('//contact:name', contact: xml_schema).text
end
+ def test_returns_valid_response_if_not_throttled
+ @contact.update_columns(code: @contact.code.upcase)
+
+ request_xml = <<-XML
+
+
+
+
+
+ john-001
+
+
+
+
+ XML
+
+ post epp_info_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+ @contact.update_columns(code: @contact.code.upcase)
+
+ request_xml = <<-XML
+
+
+
+
+
+ john-001
+
+
+
+
+ XML
+
+ post epp_info_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_info_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
private
def xml_schema
diff --git a/test/integration/epp/contact/update/base_test.rb b/test/integration/epp/contact/update/base_test.rb
index 0c55c5223..6999e3f2d 100644
--- a/test/integration/epp/contact/update/base_test.rb
+++ b/test/integration/epp/contact/update/base_test.rb
@@ -6,6 +6,9 @@ class EppContactUpdateBaseTest < EppTestCase
setup do
@contact = contacts(:john)
ActionMailer::Base.deliveries.clear
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_updates_contact
@@ -470,6 +473,76 @@ class EppContactUpdateBaseTest < EppTestCase
assert_equal '+123.4', @contact.phone
end
+ def test_returns_valid_response_if_not_throttled
+ @contact.update_columns(code: @contact.code.upcase)
+
+ request_xml = <<-XML
+
+
+
+
+
+ john-001
+
+
+ new name
+
+ +123.4
+ new-email@inbox.test
+
+
+
+
+
+ XML
+
+ post epp_update_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+ @contact.update_columns(code: @contact.code.upcase)
+
+ request_xml = <<-XML
+
+
+
+
+
+ john-001
+
+
+ new name
+
+ +123.4
+ new-email@inbox.test
+
+
+
+
+
+ XML
+
+ post epp_update_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_update_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
private
def make_contact_free_of_domains_where_it_acts_as_a_registrant(contact)
diff --git a/test/integration/epp/domain/check/base_test.rb b/test/integration/epp/domain/check/base_test.rb
index 7a1c20c88..536d6525a 100644
--- a/test/integration/epp/domain/check/base_test.rb
+++ b/test/integration/epp/domain/check/base_test.rb
@@ -1,6 +1,11 @@
require 'test_helper'
class EppDomainCheckBaseTest < EppTestCase
+ setup do
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
+ end
+
def test_returns_valid_response
request_xml = <<-XML
@@ -193,4 +198,56 @@ class EppDomainCheckBaseTest < EppTestCase
assert_correct_against_schema response_xml
assert_equal 3, response_xml.xpath('//domain:cd', 'domain' => "#{Xsd::Schema.filename(for_prefix: 'domain-ee', for_version: '1.2')}").size
end
+
+ def test_returns_valid_response_if_not_throttled
+ request_xml = <<-XML
+
+
+
+
+
+ some.test
+
+
+
+
+ XML
+
+ post epp_check_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+ request_xml = <<-XML
+
+
+
+
+
+ some.test
+
+
+
+
+ XML
+
+ post epp_check_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_check_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/epp/domain/create/base_test.rb b/test/integration/epp/domain/create/base_test.rb
index 4932c6989..180d165b3 100644
--- a/test/integration/epp/domain/create/base_test.rb
+++ b/test/integration/epp/domain/create/base_test.rb
@@ -1,6 +1,10 @@
require 'test_helper'
class EppDomainCreateBaseTest < EppTestCase
+ setup do
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
+ end
def test_illegal_chars_in_dns_key
name = "new.#{dns_zones(:one).origin}"
@@ -852,4 +856,85 @@ class EppDomainCreateBaseTest < EppTestCase
assert_correct_against_schema response_xml
assert_epp_response :completed_successfully
end
+
+ def test_returns_valid_response_if_not_throttled
+ now = Time.zone.parse('2010-07-05')
+ travel_to now
+ disputed_domain = disputes(:active)
+ password = disputed_domain.password
+
+ request_xml = <<-XML
+
+
+
+
+
+ #{disputed_domain.domain_name}
+ #{contacts(:john).code}
+
+
+
+
+ #{'test' * 2000}
+
+ #{password}
+
+
+
+
+
+ XML
+
+ post epp_create_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ now = Time.zone.parse('2010-07-05')
+ travel_to now
+ disputed_domain = disputes(:active)
+ password = disputed_domain.password
+
+ request_xml = <<-XML
+
+
+
+
+
+ #{disputed_domain.domain_name}
+ #{contacts(:john).code}
+
+
+
+
+ #{'test' * 2000}
+
+ #{password}
+
+
+
+
+
+ XML
+
+ post epp_create_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_create_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/epp/domain/info/base_test.rb b/test/integration/epp/domain/info/base_test.rb
index da3be1d38..15939e212 100644
--- a/test/integration/epp/domain/info/base_test.rb
+++ b/test/integration/epp/domain/info/base_test.rb
@@ -1,6 +1,11 @@
require 'test_helper'
class EppDomainInfoBaseTest < EppTestCase
+ setup do
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
+ end
+
def test_returns_valid_response
assert_equal 'john-001', contacts(:john).code
domains(:shop).update_columns(statuses: [DomainStatus::OK],
@@ -180,6 +185,63 @@ class EppDomainInfoBaseTest < EppTestCase
assert_correct_against_schema response_xml
end
+ def test_returns_valid_response_if_not_throttled
+ domain = domains(:shop)
+
+ request_xml = <<-XML
+
+
+
+
+
+ #{domain.name}
+
+
+
+
+ XML
+
+ post epp_info_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+ domain = domains(:shop)
+
+ request_xml = <<-XML
+
+
+
+
+
+ #{domain.name}
+
+
+
+
+ XML
+
+ post epp_info_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_info_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ # binding.pry
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
def test_returns_valid_response_if_release_prohibited
domain = domains(:shop)
domain.update_columns(statuses: [DomainStatus::SERVER_RELEASE_PROHIBITED],
diff --git a/test/integration/epp/domain/update/base_test.rb b/test/integration/epp/domain/update/base_test.rb
index 10c92ebc5..dbcbe3cb2 100644
--- a/test/integration/epp/domain/update/base_test.rb
+++ b/test/integration/epp/domain/update/base_test.rb
@@ -10,6 +10,9 @@ class EppDomainUpdateBaseTest < EppTestCase
@original_registrant_change_verification =
Setting.request_confirmation_on_registrant_change_enabled
ActionMailer::Base.deliveries.clear
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
teardown do
@@ -882,6 +885,88 @@ class EppDomainUpdateBaseTest < EppTestCase
assert_epp_response :object_does_not_exist
end
+ def test_returns_valid_response_if_not_throttled
+ ENV['obj_and_extensions_prohibited'] = 'true'
+ @domain = domains(:shop)
+ @domain.statuses << DomainStatus::SERVER_EXTENSION_UPDATE_PROHIBITED
+ @domain.save
+
+ request_xml = <<-XML
+
+
+
+
+
+ shop.test
+
+
+
+ #{nameservers(:shop_ns1).hostname}
+
+
+ #{nameservers(:shop_ns2).hostname}
+
+
+
+
+
+
+
+ XML
+
+ post epp_update_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+ ENV['obj_and_extensions_prohibited'] = 'true'
+ @domain = domains(:shop)
+ @domain.statuses << DomainStatus::SERVER_EXTENSION_UPDATE_PROHIBITED
+ @domain.save
+
+ request_xml = <<-XML
+
+
+
+
+
+ shop.test
+
+
+
+ #{nameservers(:shop_ns1).hostname}
+
+
+ #{nameservers(:shop_ns2).hostname}
+
+
+
+
+
+
+
+ XML
+
+ post epp_update_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_update_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
private
def assert_verification_and_notification_emails
diff --git a/test/integration/epp/poll_test.rb b/test/integration/epp/poll_test.rb
index 7b114f7c0..0f7dc3765 100644
--- a/test/integration/epp/poll_test.rb
+++ b/test/integration/epp/poll_test.rb
@@ -2,6 +2,8 @@ require 'test_helper'
class EppPollTest < EppTestCase
setup do
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
@notification = notifications(:complete)
end
@@ -149,6 +151,44 @@ class EppPollTest < EppTestCase
assert_epp_response :authorization_error
end
+ def test_returns_valid_response_if_not_throttled
+ notification = notifications(:greeting)
+
+ request_xml = <<-XML
+
+
+
+
+
+
+ XML
+
+ post epp_poll_path, params: { frame: request_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :completed_successfully
+ assert_correct_against_schema response_xml
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ post epp_poll_path, params: { frame: request_req_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ post epp_poll_path, params: { frame: request_req_xml },
+ headers: { 'HTTP_COOKIE' => 'session=api_bestnames' }
+
+ response_xml = Nokogiri::XML(response.body)
+ assert_epp_response :session_limit_exceeded_server_closing_connection
+ assert_correct_against_schema response_xml
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
private
def request_req_xml
diff --git a/test/integration/repp/v1/accounts/activities_list_test.rb b/test/integration/repp/v1/accounts/activities_list_test.rb
index 2038815a1..5cc5c47a4 100644
--- a/test/integration/repp/v1/accounts/activities_list_test.rb
+++ b/test/integration/repp/v1/accounts/activities_list_test.rb
@@ -7,6 +7,9 @@ class ReppV1AccountsActivitiesListTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_account_activities
@@ -67,4 +70,19 @@ class ReppV1AccountsActivitiesListTest < ActionDispatch::IntegrationTest
assert_equal @user.registrar.cash_account.activities.count, json[:data][:activities].length
assert_equal json[:data][:activities][0][:description], activity.description
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get repp_v1_accounts_path, headers: @auth_headers
+ get repp_v1_accounts_path, headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/accounts/balance_test.rb b/test/integration/repp/v1/accounts/balance_test.rb
index 3fd25f3e7..de41da26d 100644
--- a/test/integration/repp/v1/accounts/balance_test.rb
+++ b/test/integration/repp/v1/accounts/balance_test.rb
@@ -8,9 +8,12 @@ class ReppV1BalanceTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
-
+
def test_can_query_balance
get '/repp/v1/accounts/balance', headers: @auth_headers
@@ -49,5 +52,20 @@ class ReppV1BalanceTest < ActionDispatch::IntegrationTest
assert trans[:created_at].to_date.to_s(:db) >= started_from
assert trans[:created_at].to_date.to_s(:db) >= end_to
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get '/repp/v1/accounts/balance', headers: @auth_headers
+ get '/repp/v1/accounts/balance', headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
end
diff --git a/test/integration/repp/v1/accounts/details_test.rb b/test/integration/repp/v1/accounts/details_test.rb
index 30acb5eb6..b643c60e2 100644
--- a/test/integration/repp/v1/accounts/details_test.rb
+++ b/test/integration/repp/v1/accounts/details_test.rb
@@ -7,6 +7,9 @@ class ReppV1AccountsDetailsTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_account_details
@@ -19,4 +22,19 @@ class ReppV1AccountsDetailsTest < ActionDispatch::IntegrationTest
assert_equal @user.registrar.billing_email, json[:data][:account][:billing_email]
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get '/repp/v1/accounts/details', headers: @auth_headers
+ get '/repp/v1/accounts/details', headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/accounts/switch_user_test.rb b/test/integration/repp/v1/accounts/switch_user_test.rb
index a860fb162..2299f2bf5 100644
--- a/test/integration/repp/v1/accounts/switch_user_test.rb
+++ b/test/integration/repp/v1/accounts/switch_user_test.rb
@@ -7,6 +7,9 @@ class ReppV1AccountsSwitchUserTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_switches_to_linked_api_user
@@ -48,4 +51,27 @@ class ReppV1AccountsSwitchUserTest < ActionDispatch::IntegrationTest
assert_response :bad_request
assert_equal 'Cannot switch to unlinked user', json[:message]
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ new_user = users(:api_goodnames)
+ new_user.update(identity_code: '1234')
+ request_body = {
+ account: {
+ new_user_id: new_user.id,
+ },
+ }
+
+ put '/repp/v1/accounts/switch_user', headers: @auth_headers, params: request_body
+ put '/repp/v1/accounts/switch_user', headers: @auth_headers, params: request_body
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/accounts/update_auto_reload_balance_test.rb b/test/integration/repp/v1/accounts/update_auto_reload_balance_test.rb
index 11a8d08ba..253cd6b0b 100644
--- a/test/integration/repp/v1/accounts/update_auto_reload_balance_test.rb
+++ b/test/integration/repp/v1/accounts/update_auto_reload_balance_test.rb
@@ -7,6 +7,9 @@ class ReppV1AccountsUpdateAutoReloadBalanceTest < ActionDispatch::IntegrationTes
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_updates_auto_reload_balance
@@ -66,4 +69,45 @@ class ReppV1AccountsUpdateAutoReloadBalanceTest < ActionDispatch::IntegrationTes
assert_nil @user.registrar.settings['balance_auto_reload']
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ amount = 100
+ threshold = 10
+ request_body = {
+ type: {
+ amount: amount,
+ threshold: threshold,
+ },
+ }
+
+ post '/repp/v1/accounts/update_auto_reload_balance', headers: @auth_headers,
+ params: request_body
+ post '/repp/v1/accounts/update_auto_reload_balance', headers: @auth_headers,
+ params: request_body
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get '/repp/v1/accounts/disable_auto_reload_balance', headers: @auth_headers
+ get '/repp/v1/accounts/disable_auto_reload_balance', headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/accounts/update_details_test.rb b/test/integration/repp/v1/accounts/update_details_test.rb
index c1275ddeb..a9293605d 100644
--- a/test/integration/repp/v1/accounts/update_details_test.rb
+++ b/test/integration/repp/v1/accounts/update_details_test.rb
@@ -7,6 +7,9 @@ class ReppV1AccountsUpdateDetailsTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_updates_details
@@ -27,4 +30,26 @@ class ReppV1AccountsUpdateDetailsTest < ActionDispatch::IntegrationTest
assert_equal(request_body[:account][:billing_email], @user.registrar.billing_email)
assert_equal(request_body[:account][:iban], @user.registrar.iban)
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ request_body = {
+ account: {
+ billing_email: 'donaldtrump@yandex.ru',
+ iban: 'GB331111111111111111',
+ },
+ }
+
+ put '/repp/v1/accounts', headers: @auth_headers, params: request_body
+ put '/repp/v1/accounts', headers: @auth_headers, params: request_body
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/contacts/check_test.rb b/test/integration/repp/v1/contacts/check_test.rb
index 6fc716638..1da629320 100644
--- a/test/integration/repp/v1/contacts/check_test.rb
+++ b/test/integration/repp/v1/contacts/check_test.rb
@@ -7,6 +7,9 @@ class ReppV1ContactsCheckTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_code_based_check_returns_true_for_available_contact
@@ -27,4 +30,20 @@ class ReppV1ContactsCheckTest < ActionDispatch::IntegrationTest
assert_equal contact.code, json[:data][:contact][:code]
assert_equal false, json[:data][:contact][:available]
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ contact = contacts(:jack)
+ get "/repp/v1/contacts/check/#{contact.code}", headers: @auth_headers
+ get "/repp/v1/contacts/check/#{contact.code}", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/contacts/create_test.rb b/test/integration/repp/v1/contacts/create_test.rb
index af1ca0fbf..3d0c2f646 100644
--- a/test/integration/repp/v1/contacts/create_test.rb
+++ b/test/integration/repp/v1/contacts/create_test.rb
@@ -7,6 +7,9 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_creates_new_contact
@@ -153,4 +156,32 @@ class ReppV1ContactsCreateTest < ActionDispatch::IntegrationTest
contact = Contact.find_by(code: json[:data][:contact][:code])
assert contact.legal_documents.any?
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ request_body = {
+ contact: {
+ name: 'Donald Trump',
+ phone: '+372.51111112',
+ email: 'donald@trumptower.com',
+ ident: {
+ ident_type: 'priv',
+ ident_country_code: 'EE',
+ ident: '39708290069',
+ },
+ },
+ }
+
+ post '/repp/v1/contacts', headers: @auth_headers, params: request_body
+ post '/repp/v1/contacts', headers: @auth_headers, params: request_body
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/contacts/delete_test.rb b/test/integration/repp/v1/contacts/delete_test.rb
index 07438d8af..e585e0962 100644
--- a/test/integration/repp/v1/contacts/delete_test.rb
+++ b/test/integration/repp/v1/contacts/delete_test.rb
@@ -7,6 +7,9 @@ class ReppV1ContactsDeleteTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_deletes_unassociated_contact
@@ -44,4 +47,19 @@ class ReppV1ContactsDeleteTest < ActionDispatch::IntegrationTest
assert_response :not_found
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ delete "/repp/v1/contacts/#{contacts(:invalid_email).code}", headers: @auth_headers
+ delete "/repp/v1/contacts/#{contacts(:john).code}", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/contacts/list_test.rb b/test/integration/repp/v1/contacts/list_test.rb
index 979d3ea40..56b909459 100644
--- a/test/integration/repp/v1/contacts/list_test.rb
+++ b/test/integration/repp/v1/contacts/list_test.rb
@@ -7,6 +7,9 @@ class ReppV1ContactsListTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_registrar_contacts
@@ -79,4 +82,19 @@ class ReppV1ContactsListTest < ActionDispatch::IntegrationTest
assert_equal @user.registrar.contacts.count, json[:data][:contacts].length
assert_equal json[:data][:contacts][0][:code], contact.code
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get repp_v1_contacts_path, headers: @auth_headers
+ get repp_v1_contacts_path, headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/contacts/search_test.rb b/test/integration/repp/v1/contacts/search_test.rb
index ceeefc7be..dfbed9cee 100644
--- a/test/integration/repp/v1/contacts/search_test.rb
+++ b/test/integration/repp/v1/contacts/search_test.rb
@@ -7,6 +7,9 @@ class ReppV1ContactsSearchTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_searches_all_contacts_by_id
@@ -40,4 +43,18 @@ class ReppV1ContactsSearchTest < ActionDispatch::IntegrationTest
assert json[:data].is_a? Array
assert_equal json[:data].length, 0
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get '/repp/v1/contacts/search', headers: @auth_headers, params: { query: '000' }
+
+ assert_raise Shunter::ThrottleError do
+ get '/repp/v1/contacts/search', headers: @auth_headers, params: { query: '000' }
+ end
+
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/contacts/show_test.rb b/test/integration/repp/v1/contacts/show_test.rb
index 496935ab6..8a79ccfdd 100644
--- a/test/integration/repp/v1/contacts/show_test.rb
+++ b/test/integration/repp/v1/contacts/show_test.rb
@@ -7,6 +7,9 @@ class ReppV1ContactsShowTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_error_when_not_found
@@ -42,4 +45,21 @@ class ReppV1ContactsShowTest < ActionDispatch::IntegrationTest
assert_equal 2303, json[:code]
assert_equal 'Object does not exist', json[:message]
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ contact = @user.registrar.contacts.first
+
+ get repp_v1_contact_path(id: contact.code), headers: @auth_headers
+ get repp_v1_contact_path(id: contact.code), headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/contacts/update_test.rb b/test/integration/repp/v1/contacts/update_test.rb
index e75ce4188..d51602c32 100644
--- a/test/integration/repp/v1/contacts/update_test.rb
+++ b/test/integration/repp/v1/contacts/update_test.rb
@@ -8,6 +8,9 @@ class ReppV1ContactsUpdateTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_updates_contact
@@ -118,4 +121,25 @@ class ReppV1ContactsUpdateTest < ActionDispatch::IntegrationTest
assert_equal 2308, json[:code]
assert_equal 'Ident update is not allowed. Consider creating new contact object', json[:message]
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ request_body = {
+ "contact": {
+ "email": "donaldtrump@yandex.ru"
+ }
+ }
+
+ put "/repp/v1/contacts/#{@contact.code}", headers: @auth_headers, params: request_body
+ put "/repp/v1/contacts/#{@contact.code}", headers: @auth_headers, params: request_body
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/domains/bulk_renew_test.rb b/test/integration/repp/v1/domains/bulk_renew_test.rb
index 510d09f62..56439a908 100644
--- a/test/integration/repp/v1/domains/bulk_renew_test.rb
+++ b/test/integration/repp/v1/domains/bulk_renew_test.rb
@@ -8,6 +8,9 @@ class ReppV1DomainsBulkRenewTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_renews_domains
@@ -129,6 +132,30 @@ class ReppV1DomainsBulkRenewTest < ActionDispatch::IntegrationTest
assert_equal 'Invalid renew period', json[:message]
end
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ payload = {
+ "domains": [
+ 'shop.test',
+ 'airport.test',
+ 'library.test'
+ ],
+ "renew_period": "1y"
+ }
+
+ post "/repp/v1/domains/renew/bulk", headers: @auth_headers, params: payload
+ post "/repp/v1/domains/renew/bulk", headers: @auth_headers, params: payload
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
private
def set_status_for_domain(domain, statuses)
diff --git a/test/integration/repp/v1/domains/contacts_test.rb b/test/integration/repp/v1/domains/contacts_test.rb
index 17f8f1f6b..87b916811 100644
--- a/test/integration/repp/v1/domains/contacts_test.rb
+++ b/test/integration/repp/v1/domains/contacts_test.rb
@@ -8,6 +8,9 @@ class ReppV1DomainsContactsTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_shows_existing_domain_contacts
@@ -22,6 +25,21 @@ class ReppV1DomainsContactsTest < ActionDispatch::IntegrationTest
assert_equal @domain.tech_contacts.length, json[:data][:tech_contacts].length
end
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get "/repp/v1/domains/#{@domain.name}/contacts", headers: @auth_headers
+ get "/repp/v1/domains/#{@domain.name}/contacts", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
def test_can_add_new_admin_contacts
new_contact = contacts(:john)
refute @domain.admin_contacts.find_by(code: new_contact.code).present?
@@ -71,7 +89,7 @@ class ReppV1DomainsContactsTest < ActionDispatch::IntegrationTest
def test_can_remove_tech_contacts
Spy.on_instance_method(Actions::DomainUpdate, :validate_email).and_return(true)
-
+
contact = contacts(:john)
payload = { contacts: [ { code: contact.code, type: 'tech' } ] }
post "/repp/v1/domains/#{@domain.name}/contacts", headers: @auth_headers, params: payload
diff --git a/test/integration/repp/v1/domains/dnssec_test.rb b/test/integration/repp/v1/domains/dnssec_test.rb
index 349639ad4..46e239fbf 100644
--- a/test/integration/repp/v1/domains/dnssec_test.rb
+++ b/test/integration/repp/v1/domains/dnssec_test.rb
@@ -8,6 +8,9 @@ class ReppV1DomainsDnssecTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_shows_dnssec_keys_associated_with_domain
@@ -120,4 +123,19 @@ class ReppV1DomainsDnssecTest < ActionDispatch::IntegrationTest
assert @domain.dnskeys.empty?
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get "/repp/v1/domains/#{@domain.name}/dnssec", headers: @auth_headers
+ get "/repp/v1/domains/#{@domain.name}/dnssec", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/domains/list_test.rb b/test/integration/repp/v1/domains/list_test.rb
index 205017a6c..3699927db 100644
--- a/test/integration/repp/v1/domains/list_test.rb
+++ b/test/integration/repp/v1/domains/list_test.rb
@@ -7,6 +7,9 @@ class ReppV1DomainsListTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_registrar_domains
@@ -92,4 +95,19 @@ class ReppV1DomainsListTest < ActionDispatch::IntegrationTest
assert_equal @user.registrar.domains.count, json[:data][:domains].length
assert_equal json[:data][:domains][0][:name], domain.name
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get repp_v1_domains_path, headers: @auth_headers
+ get repp_v1_domains_path, headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/domains/nameservers_test.rb b/test/integration/repp/v1/domains/nameservers_test.rb
index 780e889c1..3ff85260e 100644
--- a/test/integration/repp/v1/domains/nameservers_test.rb
+++ b/test/integration/repp/v1/domains/nameservers_test.rb
@@ -8,6 +8,9 @@ class ReppV1DomainsNameserversTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_can_add_new_nameserver
@@ -30,6 +33,21 @@ class ReppV1DomainsNameserversTest < ActionDispatch::IntegrationTest
assert_equal payload[:nameservers][0][:ipv6], @domain.nameservers.last.ipv6
end
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get "/repp/v1/domains/#{@domain.name}/nameservers", headers: @auth_headers
+ get "/repp/v1/domains/#{@domain.name}/nameservers", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
def test_can_remove_existing_nameserver
payload = {
nameservers: [
diff --git a/test/integration/repp/v1/domains/statuses_test.rb b/test/integration/repp/v1/domains/statuses_test.rb
index 271752ae3..ee2cb445b 100644
--- a/test/integration/repp/v1/domains/statuses_test.rb
+++ b/test/integration/repp/v1/domains/statuses_test.rb
@@ -8,6 +8,9 @@ class ReppV1DomainsStatusesTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_client_hold_can_be_added
@@ -79,4 +82,18 @@ class ReppV1DomainsStatusesTest < ActionDispatch::IntegrationTest
assert_equal 2306, json[:code]
end
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ put repp_v1_domain_status_path(domain_id: @domain.name, id: DomainStatus::CLIENT_HOLD), headers: @auth_headers
+ put repp_v1_domain_status_path(domain_id: @domain.name, id: DomainStatus::CLIENT_HOLD), headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/domains/transfer_info_test.rb b/test/integration/repp/v1/domains/transfer_info_test.rb
index a3b8fe874..64fd8ed10 100644
--- a/test/integration/repp/v1/domains/transfer_info_test.rb
+++ b/test/integration/repp/v1/domains/transfer_info_test.rb
@@ -7,6 +7,9 @@ class ReppV1DomainsTransferInfoTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@domain = domains(:shop)
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_can_query_domain_info
@@ -51,4 +54,22 @@ class ReppV1DomainsTransferInfoTest < ActionDispatch::IntegrationTest
assert_response :ok
assert_equal 1000, json[:code]
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ headers = @auth_headers
+ headers['Auth-Code'] = @domain.transfer_code
+
+ get "/repp/v1/domains/#{@domain.name}/transfer_info", headers: headers
+ get "/repp/v1/domains/#{@domain.name}/transfer_info", headers: headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/domains/transfer_test.rb b/test/integration/repp/v1/domains/transfer_test.rb
index 5854de195..fdcbe41d7 100644
--- a/test/integration/repp/v1/domains/transfer_test.rb
+++ b/test/integration/repp/v1/domains/transfer_test.rb
@@ -8,6 +8,9 @@ class ReppV1DomainsTransferTest < ActionDispatch::IntegrationTest
@domain = domains(:hospital)
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_transfers_scoped_domain
@@ -152,4 +155,20 @@ class ReppV1DomainsTransferTest < ActionDispatch::IntegrationTest
assert_not @domain.registrar == @user.registrar
end
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ payload = { transfer: { transfer_code: @domain.transfer_code } }
+ post "/repp/v1/domains/#{@domain.name}/transfer", headers: @auth_headers, params: payload
+ post "/repp/v1/domains/#{@domain.name}/transfer", headers: @auth_headers, params: payload
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
end
diff --git a/test/integration/repp/v1/invoices/add_credit_test.rb b/test/integration/repp/v1/invoices/add_credit_test.rb
index fe250de7d..a6dd541f4 100644
--- a/test/integration/repp/v1/invoices/add_credit_test.rb
+++ b/test/integration/repp/v1/invoices/add_credit_test.rb
@@ -24,6 +24,8 @@ class ReppV1InvoicesAddCreditTest < ActionDispatch::IntegrationTest
message: 'success'
}
stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").to_return(status: 200, body: msg2.to_json, headers: {})
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
teardown do
@@ -101,4 +103,39 @@ class ReppV1InvoicesAddCreditTest < ActionDispatch::IntegrationTest
assert_response :bad_request
assert_equal "Amount is too small. Minimum deposit is #{Setting.minimum_deposit} EUR", json[:message]
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ request_body = {
+ invoice: {
+ amount: 100,
+ description: 'Add credit',
+ },
+ }
+ Setting.registry_vat_prc = 0.1
+ ENV['billing_system_integrated'] = 'true'
+
+ if Feature.billing_system_integrated?
+ invoice_n = Invoice.order(number: :desc).last.number
+ stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator')
+ .to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {})
+ stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice')
+ .to_return(status: 200, body: '', headers: {})
+ end
+
+ post '/repp/v1/invoices/add_credit', headers: @auth_headers,
+ params: request_body
+ post '/repp/v1/invoices/add_credit', headers: @auth_headers,
+ params: request_body
+
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/invoices/cancel_test.rb b/test/integration/repp/v1/invoices/cancel_test.rb
index 1041d1d1f..0d7d3a585 100644
--- a/test/integration/repp/v1/invoices/cancel_test.rb
+++ b/test/integration/repp/v1/invoices/cancel_test.rb
@@ -41,4 +41,4 @@ class ReppV1InvoicesCancelTest < ActionDispatch::IntegrationTest
invoice.reload
assert_not invoice.cancelled?
end
-end
\ No newline at end of file
+end
diff --git a/test/integration/repp/v1/invoices/download_test.rb b/test/integration/repp/v1/invoices/download_test.rb
index cbb9de585..fe2e9233d 100644
--- a/test/integration/repp/v1/invoices/download_test.rb
+++ b/test/integration/repp/v1/invoices/download_test.rb
@@ -7,6 +7,9 @@ class ReppV1InvoicesDownloadTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_invoice_as_pdf
@@ -19,4 +22,21 @@ class ReppV1InvoicesDownloadTest < ActionDispatch::IntegrationTest
assert_equal "attachment; filename=\"Invoice-2.pdf\"; filename*=UTF-8''Invoice-2.pdf", response.headers['Content-Disposition']
assert_not_empty response.body
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ invoice = @user.registrar.invoices.first
+
+ get "/repp/v1/invoices/#{invoice.id}/download", headers: @auth_headers
+ get "/repp/v1/invoices/#{invoice.id}/download", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/invoices/list_test.rb b/test/integration/repp/v1/invoices/list_test.rb
index 5dfe2d53f..35fa7256a 100644
--- a/test/integration/repp/v1/invoices/list_test.rb
+++ b/test/integration/repp/v1/invoices/list_test.rb
@@ -7,6 +7,9 @@ class ReppV1InvoicesListTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_registrar_invoices
@@ -82,4 +85,19 @@ class ReppV1InvoicesListTest < ActionDispatch::IntegrationTest
assert_equal (@user.registrar.invoices.count - offset), json[:data][:invoices].length
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get repp_v1_invoices_path, headers: @auth_headers
+ get repp_v1_invoices_path, headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/invoices/send_test.rb b/test/integration/repp/v1/invoices/send_test.rb
index 77fe9997f..565ac27ff 100644
--- a/test/integration/repp/v1/invoices/send_test.rb
+++ b/test/integration/repp/v1/invoices/send_test.rb
@@ -7,6 +7,9 @@ class ReppV1InvoicesSendTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_sends_invoice_to_recipient
@@ -36,4 +39,30 @@ class ReppV1InvoicesSendTest < ActionDispatch::IntegrationTest
assert_equal 'Invoice no. 1', email.subject
assert email.attachments['invoice-1.pdf']
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ invoice = invoices(:one)
+ recipient = 'donaldtrump@yandex.ru'
+ request_body = {
+ invoice: {
+ id: invoice.id,
+ recipient: recipient,
+ },
+ }
+ post "/repp/v1/invoices/#{invoice.id}/send_to_recipient", headers: @auth_headers,
+ params: request_body
+ post "/repp/v1/invoices/#{invoice.id}/send_to_recipient", headers: @auth_headers,
+ params: request_body
+
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/invoices/show_test.rb b/test/integration/repp/v1/invoices/show_test.rb
index 74feb42ac..4f26f4b11 100644
--- a/test/integration/repp/v1/invoices/show_test.rb
+++ b/test/integration/repp/v1/invoices/show_test.rb
@@ -7,6 +7,9 @@ class ReppV1InvoicesShowTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_error_when_not_found
@@ -30,4 +33,21 @@ class ReppV1InvoicesShowTest < ActionDispatch::IntegrationTest
assert_equal invoice.id, json[:data][:invoice][:id]
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ invoice = @user.registrar.invoices.first
+
+ get repp_v1_invoice_path(id: invoice.id), headers: @auth_headers
+ get repp_v1_invoice_path(id: invoice.id), headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/registrar/auth/check_info_test.rb b/test/integration/repp/v1/registrar/auth/check_info_test.rb
index 03563d273..154e8e258 100644
--- a/test/integration/repp/v1/registrar/auth/check_info_test.rb
+++ b/test/integration/repp/v1/registrar/auth/check_info_test.rb
@@ -7,6 +7,9 @@ class ReppV1RegistrarAuthCheckInfoTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_returns_valid_user_auth_values
@@ -35,4 +38,19 @@ class ReppV1RegistrarAuthCheckInfoTest < ActionDispatch::IntegrationTest
assert_response :unauthorized
assert_equal json[:message], 'Invalid authorization information'
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get '/repp/v1/registrar/auth', headers: @auth_headers
+ get '/repp/v1/registrar/auth', headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/integration/repp/v1/registrar/auth/tara_callback_test.rb b/test/integration/repp/v1/registrar/auth/tara_callback_test.rb
index e39e24078..918fce9cc 100644
--- a/test/integration/repp/v1/registrar/auth/tara_callback_test.rb
+++ b/test/integration/repp/v1/registrar/auth/tara_callback_test.rb
@@ -43,4 +43,4 @@ class ReppV1RegistrarAuthTaraCallbackTest < ActionDispatch::IntegrationTest
assert_response :unauthorized
assert_equal 'No such user', json[:message]
end
-end
\ No newline at end of file
+end
diff --git a/test/integration/repp/v1/registrar/notifications_test.rb b/test/integration/repp/v1/registrar/notifications_test.rb
index 2677d393b..6eb6f9898 100644
--- a/test/integration/repp/v1/registrar/notifications_test.rb
+++ b/test/integration/repp/v1/registrar/notifications_test.rb
@@ -7,6 +7,9 @@ class ReppV1RegistrarNotificationsTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_all_unreaded_poll_messages
@@ -20,6 +23,22 @@ class ReppV1RegistrarNotificationsTest < ActionDispatch::IntegrationTest
assert_equal json[:data].last[:text], notification.last.text
end
+ def test_all_notifications_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ notification = @user.registrar.notifications.where(read: false).order(created_at: :desc).all
+ get "/repp/v1/registrar/notifications/all_notifications", headers: @auth_headers
+ get "/repp/v1/registrar/notifications/all_notifications", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
def test_gets_latest_unread_poll_message
notification = @user.registrar.notifications.where(read: false).order(created_at: :desc).first
get "/repp/v1/registrar/notifications", headers: @auth_headers
@@ -31,6 +50,22 @@ class ReppV1RegistrarNotificationsTest < ActionDispatch::IntegrationTest
assert_equal notification.text, json[:data][:text]
end
+ def test_index_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ notification = @user.registrar.notifications.where(read: false).order(created_at: :desc).first
+ get "/repp/v1/registrar/notifications", headers: @auth_headers
+ get "/repp/v1/registrar/notifications", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
def test_can_read_specific_notification_by_id
notification = @user.registrar.notifications.order(created_at: :desc).second
@@ -43,6 +78,23 @@ class ReppV1RegistrarNotificationsTest < ActionDispatch::IntegrationTest
assert_equal notification.text, json[:data][:text]
end
+ def test_show_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ notification = @user.registrar.notifications.order(created_at: :desc).second
+
+ get "/repp/v1/registrar/notifications/#{notification.id}", headers: @auth_headers
+ get "/repp/v1/registrar/notifications/#{notification.id}", headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+
def test_can_mark_notification_as_read
@auth_headers['Content-Type'] = 'application/json'
notification = @user.registrar.notifications.where(read: false).order(created_at: :desc).first
diff --git a/test/integration/repp/v1/registrar/summary_test.rb b/test/integration/repp/v1/registrar/summary_test.rb
index 97797990a..bd58d8e97 100644
--- a/test/integration/repp/v1/registrar/summary_test.rb
+++ b/test/integration/repp/v1/registrar/summary_test.rb
@@ -7,6 +7,9 @@ class ReppV1RegistrarSummaryTest < ActionDispatch::IntegrationTest
token = "Basic #{token}"
@auth_headers = { 'Authorization' => token }
+
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter&.clear!
end
def test_checks_user_summary_info
@@ -40,4 +43,19 @@ class ReppV1RegistrarSummaryTest < ActionDispatch::IntegrationTest
assert_nil json[:data][:notification]
assert_nil json[:data][:notifications_count]
end
-end
\ No newline at end of file
+
+ def test_returns_error_response_if_throttled
+ ENV["shunter_default_threshold"] = '1'
+ ENV["shunter_enabled"] = 'true'
+
+ get '/repp/v1/registrar/summary', headers: @auth_headers
+ get '/repp/v1/registrar/summary', headers: @auth_headers
+ json = JSON.parse(response.body, symbolize_names: true)
+
+ assert_response :bad_request
+ assert_equal json[:code], 2502
+ assert response.body.include?(Shunter.default_error_message)
+ ENV["shunter_default_threshold"] = '10000'
+ ENV["shunter_enabled"] = 'false'
+ end
+end
diff --git a/test/lib/shunter/shunter_base_test.rb b/test/lib/shunter/shunter_base_test.rb
new file mode 100644
index 000000000..5645f8cec
--- /dev/null
+++ b/test/lib/shunter/shunter_base_test.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require "test_helper"
+require "action_controller"
+require "pry"
+
+class ShunterBaseTest < Minitest::Test
+ ENV["shunter_enabled"] = 'true'
+
+ def test_throttling_works_on_inclusion
+ ENV["shunter_default_adapter"] = "Shunter::Adapters::Memory"
+ ENV["shunter_default_threshold"] = "100"
+ adapter = ENV["shunter_default_adapter"].constantize.new
+ adapter.clear!
+
+ TestKlass.new.throttle do
+ TestKlass.new.test
+ end
+ end
+
+ class TestKlass < ::ActionController::Base
+ THROTTLED_ACTIONS = %i[test].freeze
+ include Shunter::Integration::Throttle
+
+ def test
+ "test"
+ end
+
+ def throttled_user
+ @throttled_user ||= OpenStruct.new(id: 1)
+ end
+ end
+end
diff --git a/test/models/epp/response/result/code_test.rb b/test/models/epp/response/result/code_test.rb
index a78c92d3a..ca41db458 100644
--- a/test/models/epp/response/result/code_test.rb
+++ b/test/models/epp/response/result/code_test.rb
@@ -85,7 +85,7 @@ class EppResponseResultCodeTest < ActiveSupport::TestCase
2308 => 'Data management policy violation',
2400 => 'Command failed',
2501 => 'Authentication error; server closing connection',
- 2502 => 'Session limit exceeded; server closing connection'
+ 2502 => Shunter.default_error_message
}
assert_equal descriptions, Epp::Response::Result::Code.default_descriptions
end