64 lines
1.9 KiB
Ruby
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
|