gitlab-org--gitlab-foss/spec/support/shared_examples/controllers/rate_limited_endpoint_share...

64 lines
1.9 KiB
Ruby

# frozen_string_literal: true
#
# Requires a context containing:
# - request (use method definition to avoid memoizing!)
# - current_user
# - error_message # optional
RSpec.shared_examples 'rate limited endpoint' do |rate_limit_key:|
context 'when rate limiter enabled', :freeze_time, :clean_gitlab_redis_rate_limiting do
let(:expected_logger_attributes) do
{
message: 'Application_Rate_Limiter_Request',
env: :"#{rate_limit_key}_request_limit",
remote_ip: kind_of(String),
request_method: kind_of(String),
path: kind_of(String)
}.merge(expected_user_attributes)
end
let(:expected_user_attributes) do
if defined?(current_user) && current_user.present?
{ user_id: current_user.id, username: current_user.username }
else
{}
end
end
let(:error_message) { _('This endpoint has been requested too many times. Try again later.') }
before do
allow(Gitlab::ApplicationRateLimiter).to receive(:threshold).with(rate_limit_key).and_return(1)
end
it 'logs request and declines it when endpoint called more than the threshold' do |example|
expect(Gitlab::AuthLogger).to receive(:error).with(expected_logger_attributes).once
request
request
expect(response).to have_gitlab_http_status(:too_many_requests)
if example.metadata[:type] == :controller
expect(response.body).to eq(error_message)
else # it is API spec
expect(response.body).to eq({ message: { error: error_message } }.to_json)
end
end
end
context 'when rate limiter is disabled' do
before do
allow(Gitlab::ApplicationRateLimiter).to receive(:threshold).with(rate_limit_key).and_return(0)
end
it 'does not log request and does not block the request' do
expect(Gitlab::AuthLogger).not_to receive(:error)
request
expect(response).not_to have_gitlab_http_status(:too_many_requests)
end
end
end